任何人都对这里发生的事情有任何想法?我有一个递归函数,有时会调用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;
}
答案 0 :(得分:2)
这里的最后一个参数至少是错误的:
pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector))
sizeof(ovector)以字节为单位给出大小,但是pcre_exec需要int的数量,因此将其更改为
pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector)/sizeof(ovector[0]))
文档还说明了
ovecsize Number of elements in the vector (a multiple of 3)
暗示大小应该是3的倍数,尽管这部分还不太清楚。