httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Steve Hay" <Steve...@planit.com>
Subject RE: VS2010 release builds of Apache/mod_perl crash on Vista/2008/Win7
Date Tue, 08 Feb 2011 22:29:41 GMT
William A. Rowe Jr. wrote on 2011-02-08:
> On 2/8/2011 8:29 AM, Steve Hay wrote:
>> +        int len = (int)strlen(newarr[arg]) + 1; +        *env =
>> (char*)_malloc_dbg(len * sizeof(char), _CRT_BLOCK, __FILE__, __LINE__);
>> +        strcpy_s(*env, len, newarr[arg]);
> 
> That's just sick ... It's inexcusable to use strcpy when len is already
> known :)
> 
> Very interesting observations, are you in a position to try this with
> the older
> C compilers?  Interested to know if we can just apply this to all
> flavors without
> any headaches.

I'm not sure if strcpy_s() is as sick as strcpy() would be, given that it takes a len argument
anyway (?), but I've been looking at saving a little work in the function concerned anyway,
by copying the new environment strings into place directly from the return value of the UTF-8
conversion function, rather than going through the intermediate newarr[] array as my quick
hack currently does.

The function at the foot of this email is more along the lines of what I'm thinking, and is
still working correctly. Would this approach be an improvement when suitably tidied up?

I wonder if the problem is that malloced data generally has heads and tails on it to catch
buffer overruns when freeing and the free which the putenv() call does when *replacing* an
existing environment variable is maybe unhappy at the absence of the expected heads and tails
on that, given that the APR-ized environment is currently allocated in a single block (with
only one head & tail), rather than string-by-string like stdenvp.c did it orignially (giving
each string its own head & tail)? It doesn't explain why it still runs on XP/2003, or
in debug mode, or with old compilers, though...

I have VC98 and VS2005/VS2008/VS2010 all handy and will try release and debug mode builds
of my test program with each compiler, and run each binary on XP and 2008. I don't have VS2003
available.

I will also do full Apache/Perl/mod_perl tests as well, but since that'll obviously take rather
longer maybe just a release mode build for each compiler would suffice?


static int warrsztoastr(char*** retarr, wchar_t* arrsz, int args) {
    const wchar_t* wch;
    size_t totlen;
    size_t newlen;
    size_t wsize;
    char** env;
	char* pstrs;
    char* strs;
    int arg;
    if (args < 0) {
        for (args = 1, wch = arrsz; wch[0] || wch[1]; ++wch)
            if (!*wch)
                ++args;
    }
    wsize = 1 + wch - arrsz;
    newlen = totlen = wsize * 3 + 1;
    pstrs = strs = (char*)_malloc_dbg(newlen * sizeof(char), _CRT_BLOCK, __FILE__, __LINE__);
    (void)ucs2toutf8(arrsz, &wsize, strs, &newlen);
    assert(newlen && !wsize);
    *retarr = env = (char **)_malloc_dbg((args + 1) * sizeof(char*), _CRT_BLOCK, __FILE__,
__LINE__);
    for (arg = 0; arg < args; ++arg) {
        char* p = pstrs;
        int len = 0;
        while (*p++)
            ++len;
        len += 1;
        *env = (char*)_malloc_dbg(len * sizeof(char), _CRT_BLOCK, __FILE__, __LINE__);
        memcpy(*env, pstrs, len * sizeof(char));
        pstrs += len;
        ++env;
    }
    *env = NULL;
    _free_dbg(strs, _CRT_BLOCK);
    return args;
}
Mime
View raw message