From 56c34e1b2c9ea09c2d67adba38da99f3d84a6ec7 Mon Sep 17 00:00:00 2001 From: Peter Berg Larsen Date: Thu, 21 Apr 2005 17:14:39 +0000 Subject: [PATCH] Rewritten DoEnvironmentSubst16. --- dlls/shell32/shell.c | 114 +++++++++++++++++++++++-------------------- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/dlls/shell32/shell.c b/dlls/shell32/shell.c index dfa1937631..64a3d4e639 100644 --- a/dlls/shell32/shell.c +++ b/dlls/shell32/shell.c @@ -363,74 +363,82 @@ SEGPTR WINAPI FindEnvironmentString16(LPSTR str) * DoEnvironmentSubst [SHELL.37] * * Replace %KEYWORD% in the str with the value of variable KEYWORD - * from "DOS" environment. + * from "DOS" environment. If it is not found the %KEYWORD% is left + * intact. If the buffer is too small, str is not modified. + * + * str [I] '\0' terminated string with %keyword%. + * [O] '\0' terminated string with %keyword% substituted. + * length [I] size of str. + * + * Return + * str length in the LOWORD and 1 in HIWORD if subst was successful. */ DWORD WINAPI DoEnvironmentSubst16(LPSTR str,WORD length) { LPSTR lpEnv = MapSL(GetDOSEnvironment16()); - LPSTR lpBuffer = HeapAlloc( GetProcessHeap(), 0, length); LPSTR lpstr = str; - LPSTR lpbstr = lpBuffer; + LPSTR lpend; + LPSTR lpBuffer = HeapAlloc( GetProcessHeap(), 0, length); + WORD bufCnt = 0; + WORD envKeyLen; + LPSTR lpKey; + WORD retStatus = 0; + WORD retLength = length; CharToOemA(str,str); TRACE("accept %s\n", str); - while( *lpstr && lpbstr - lpBuffer < length ) - { - LPSTR lpend = lpstr; - - if( *lpstr == '%' ) - { - do { lpend++; } while( *lpend && *lpend != '%' ); - if( *lpend == '%' && lpend - lpstr > 1 ) /* found key */ - { - LPSTR lpKey; - *lpend = '\0'; - lpKey = SHELL_FindString(lpEnv, lpstr+1); - if( lpKey ) /* found key value */ - { - int l = strlen(lpKey); - - if( l > length - (lpbstr - lpBuffer) - 1 ) - { - WARN("-- Env subst aborted - string too short\n"); - *lpend = '%'; - break; - } - strcpy(lpbstr, lpKey); - lpbstr += l; - } - else break; - *lpend = '%'; - lpstr = lpend + 1; - } - else break; /* back off and whine */ - - continue; - } - - *lpbstr++ = *lpstr++; - } - - *lpbstr = '\0'; - if( lpstr - str == strlen(str) ) - { - strncpy(str, lpBuffer, length); - length = 1; - } - else - length = 0; - + while( *lpstr && bufCnt <= length - 1 ) { + if ( *lpstr != '%' ) { + lpBuffer[bufCnt++] = *lpstr++; + continue; + } + + for( lpend = lpstr + 1; *lpend && *lpend != '%'; lpend++) /**/; + + envKeyLen = lpend - lpstr - 1; + if( *lpend != '%' || envKeyLen == 0) + goto err; /* "%\0" or "%%" found; back off and whine */ + + *lpend = '\0'; + lpKey = SHELL_FindString(lpEnv, lpstr+1); + *lpend = '%'; + if( lpKey ) { + int l = strlen(lpKey); + + if( bufCnt + l > length - 1 ) + goto err; + + memcpy(lpBuffer + bufCnt, lpKey, l); + bufCnt += l; + } else { /* Keyword not found; Leave the %KEYWORD% intact */ + if( bufCnt + envKeyLen + 2 > length - 1 ) + goto err; + + memcpy(lpBuffer + bufCnt, lpstr, envKeyLen + 2); + bufCnt += envKeyLen + 2; + } + + lpstr = lpend + 1; + } + + if (!*lpstr && bufCnt <= length - 1) { + memcpy(str,lpBuffer, bufCnt); + str[bufCnt] = '\0'; + retLength = bufCnt + 1; + retStatus = 1; + } + + err: + if (!retStatus) + WARN("-- Env subst aborted - string too short or invalid input\n"); TRACE("-- return %s\n", str); OemToCharA(str,str); HeapFree( GetProcessHeap(), 0, lpBuffer); - /* Return str length in the LOWORD - * and 1 in HIWORD if subst was successful. - */ - return (DWORD)MAKELONG(strlen(str), length); + return (DWORD)MAKELONG(retLength, retStatus); } /************************************************************************* -- 2.32.0.93.g670b81a890