开发者

using libpcre in recursive functions

开发者 https://www.devze.com 2023-02-09 13:34 出处:网络
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

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 gi开发者_如何转开发ves 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;
}


The last parameter here is at least wrong:

 pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector))

The sizeof(ovector) gives the size in bytes, but pcre_exec needs the number of ints, so change that to

pcre_exec(re, 0, str, strlen(str), 0, 0, ovector, sizeof(ovector)/sizeof(ovector[0]))

The documentation also states

 ovecsize     Number of elements in the vector (a multiple of 3)

Hinting that the size should be a multiple of 3, though this part is quite unclear.

0

精彩评论

暂无评论...
验证码 换一张
取 消