在递归函数中使用 libpcre
有人对这里发生的事情有任何想法吗?我有一个递归函数,有时会调用 pcre 来匹配正在构建的字符串中的模式。如果用于匹配的模式中没有括号(转义括号也可以正常工作),则它工作正常,但如果我使用 ([az]) 等模式,当最深的递归函数尝试时,valgrind 会给出以下错误返回(使用模式 \([az]\) 工作正常):
编辑:我编写了一个非递归版本,工作正常;当存在括号时,libpcre 是否有可能使用递归,并且以某种方式弄乱了我的例程中前一个函数的地址?
==4712== 1 errors in context 1 of 1:
==4712== Jump to the invalid address stated on the next line
==4712== at 0xFFFFFFFF: ???
==4712== by 0x40B646: ???
==4712== by 0x40B646: ???
==4712== by 0x40B646: ???
==4712== by 0x40B646: ???
==4712== by 0x40B483: ???
==4712== Address 0xffffffff is not stack'd, malloc'd or (recently) free'd
linked_list_t *_GetExistingKeysByPattern(linked_list_t *keys,
session_t *session)
{
char *cKey;
linked_list_t *existingKeys = ListNew(NULL);
ListIterSet(keys);
while (cKey = ListIterNext(keys))
{ //cKey could be SOFTWARE\\something\\([0-9]\.1) for example
char keyPath[512];
keyPath[0] = '\0';
_GetExistingKeysByPatternHelper(cKey, keyPath, existingKeys, session);
}
return existingKeys;
}
void _GetExistingKeysByPatternHelper(char *patternStart,
char *keyPath,
linked_list_t *existing,
session_t *session)
{
char *ptr, currentKeyPath[512];
unsigned short endOfPattern = 0;
char *patternStartCopy = strdup(patternStart);
if (ptr = strstr(patternStartCopy, "\\\\"))
*ptr = '\0';
else
endOfPattern = 1;
snprintf(currentKeyPath,
512,
"%s%s%s",
keyPath,
keyPath[0] == '\0' ? "" : "\\",
patternStartCopy[0]=='^'?patternStartCopy+1:patternStartCopy);
if (OpenRegistryEntry(session, currentKeyPath))
{
if (!endOfPattern)
_GetExistingKeysByPatternHelper(ptr + 2,
currentKeyPath,
existing,
session);
else
ListInsert(existing, (void *) strdup(currentKeyPath));
}
else if (keyPath[0] != '\0')
{
// Potential pattern
if (OpenRegistryEntry(session, keyPath))
{
char *subKey;
unsigned short i = 0;
while (subKey = EnumerateRegistry(session, i++))
{
if (PatternEval(subKey, patternStartCopy, 1))
{
char keyPathCopy[512];
snprintf(keyPathCopy,
512,
"%s\\%s",
keyPath,
subKey);
if (!endOfPattern)
{
_GetExistingKeysByPatternHelper(ptr + 2,
keyPathCopy,
existing,
session);
OpenRegistryEntry(session, keyPath);
}
else
ListInsert(existing, (void *) strdup(keyPathCopy));
}
free(subKey);
}
}
}
free(patternStartCopy);
}
unsigned short PatternEval(char *str, char *pattern, unsigned short carrot)
{
unsigned short res = 0;
const char *error;
int erroroffset, rc, i;
pcre *re;
int ovector[100];
char *tmp;
if (carrot)
{
if (*pattern == '^') pattern++;
tmp = (char *) malloc (strlen(pattern) + 2);
sprintf(tmp, "^%s", pattern);
}
else
tmp = pattern;
if(re = pcre_compile(tmp, PCRE_CASELESS, &error, &erroroffset, 0))
{
if ((rc = pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector))) >= 0)
res = 1;
pcre_free(re);
}
else
printf("pcre_compile failed (offset %d), %s\n",erroroffset,error);
if (carrot)
free(tmp);
return res;
}
Anyone have any ideas as to what is going on here? I have a recursive function, which sometimes makes calls to pcre to match patterns within a string that is being built. It works fine if there are no parenthesis in the pattern that is being used to match (escaped parentheses work fine also), but if I use a pattern such as ([a-z]) valgrind gives me the following error when the deepest recursive function tries to return (using the pattern \([a-z]\) works fine):
EDIT: I wrote a non recursive version and that works fine; is it possible that libpcre uses recursion when there are parentheses present and that somehow messes up the address of the previous function in my routine??
==4712== 1 errors in context 1 of 1:
==4712== Jump to the invalid address stated on the next line
==4712== at 0xFFFFFFFF: ???
==4712== by 0x40B646: ???
==4712== by 0x40B646: ???
==4712== by 0x40B646: ???
==4712== by 0x40B646: ???
==4712== by 0x40B483: ???
==4712== Address 0xffffffff is not stack'd, malloc'd or (recently) free'd
linked_list_t *_GetExistingKeysByPattern(linked_list_t *keys,
session_t *session)
{
char *cKey;
linked_list_t *existingKeys = ListNew(NULL);
ListIterSet(keys);
while (cKey = ListIterNext(keys))
{ //cKey could be SOFTWARE\\something\\([0-9]\.1) for example
char keyPath[512];
keyPath[0] = '\0';
_GetExistingKeysByPatternHelper(cKey, keyPath, existingKeys, session);
}
return existingKeys;
}
void _GetExistingKeysByPatternHelper(char *patternStart,
char *keyPath,
linked_list_t *existing,
session_t *session)
{
char *ptr, currentKeyPath[512];
unsigned short endOfPattern = 0;
char *patternStartCopy = strdup(patternStart);
if (ptr = strstr(patternStartCopy, "\\\\"))
*ptr = '\0';
else
endOfPattern = 1;
snprintf(currentKeyPath,
512,
"%s%s%s",
keyPath,
keyPath[0] == '\0' ? "" : "\\",
patternStartCopy[0]=='^'?patternStartCopy+1:patternStartCopy);
if (OpenRegistryEntry(session, currentKeyPath))
{
if (!endOfPattern)
_GetExistingKeysByPatternHelper(ptr + 2,
currentKeyPath,
existing,
session);
else
ListInsert(existing, (void *) strdup(currentKeyPath));
}
else if (keyPath[0] != '\0')
{
// Potential pattern
if (OpenRegistryEntry(session, keyPath))
{
char *subKey;
unsigned short i = 0;
while (subKey = EnumerateRegistry(session, i++))
{
if (PatternEval(subKey, patternStartCopy, 1))
{
char keyPathCopy[512];
snprintf(keyPathCopy,
512,
"%s\\%s",
keyPath,
subKey);
if (!endOfPattern)
{
_GetExistingKeysByPatternHelper(ptr + 2,
keyPathCopy,
existing,
session);
OpenRegistryEntry(session, keyPath);
}
else
ListInsert(existing, (void *) strdup(keyPathCopy));
}
free(subKey);
}
}
}
free(patternStartCopy);
}
unsigned short PatternEval(char *str, char *pattern, unsigned short carrot)
{
unsigned short res = 0;
const char *error;
int erroroffset, rc, i;
pcre *re;
int ovector[100];
char *tmp;
if (carrot)
{
if (*pattern == '^') pattern++;
tmp = (char *) malloc (strlen(pattern) + 2);
sprintf(tmp, "^%s", pattern);
}
else
tmp = pattern;
if(re = pcre_compile(tmp, PCRE_CASELESS, &error, &erroroffset, 0))
{
if ((rc = pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector))) >= 0)
res = 1;
pcre_free(re);
}
else
printf("pcre_compile failed (offset %d), %s\n",erroroffset,error);
if (carrot)
free(tmp);
return res;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里的最后一个参数至少是错误的:
sizeof(ovector) 给出了以字节为单位的大小,但是 pcre_exec 需要整数的数量,因此将其更改为
文档还指出
提示大小应该是 3 的倍数,尽管这部分还不清楚。
The last parameter here is at least wrong:
The sizeof(ovector) gives the size in bytes, but pcre_exec needs the number of ints, so change that to
The documentation also states
Hinting that the size should be a multiple of 3, though this part is quite unclear.