2011-02-08 5 views
1

여기에 무슨 일이 벌어지고 있는지에 대한 의견이 있으십니까? 필자는 재귀 함수를 가지고 있는데, 때때로 pcre를 호출하여 빌드중인 문자열 내의 패턴과 일치시킵니다. 일치하는 데 사용되는 패턴에 괄호가없는 경우에도 잘 작동하지만 (이스케이프 처리 된 괄호는 잘 작동합니다), ([az]와 같은) 패턴을 사용하면 valgrind가 가장 깊은 재귀 함수가 (패턴 \ ([az] \)를 사용하면 돌아갑니다.재귀 함수에서 libpcre 사용하기

EDIT : 비 재귀 버전을 작성했는데 제대로 작동합니다. 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의 배수 여야한다는 것을 암시하지만이 부분은 분명하지 않습니다.