Dan Kegel : cmd: Don't read past end of thisVar in WCMD_expand_envvar ( valgrind).
Alexandre Julliard
julliard at winehq.org
Thu May 26 10:56:27 CDT 2011
Module: wine
Branch: master
Commit: 1857a05996d9f969bd090253a8ad6532b0b675f8
URL: http://source.winehq.org/git/wine.git/?a=commit;h=1857a05996d9f969bd090253a8ad6532b0b675f8
Author: Dan Kegel <dank at kegel.com>
Date: Wed May 25 21:46:42 2011 -0700
cmd: Don't read past end of thisVar in WCMD_expand_envvar (valgrind).
---
programs/cmd/wcmdmain.c | 71 ++++++++++++++++++++++++-----------------------
1 files changed, 36 insertions(+), 35 deletions(-)
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 7b7ce8f..5f07c75 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -476,6 +476,37 @@ void WCMD_opt_s_strip_quotes(WCHAR *cmd) {
/*************************************************************************
+ * WCMD_is_magic_envvar
+ * Return TRUE if s is '%'magicvar'%'
+ * and is not masked by a real environment variable.
+ */
+
+static inline BOOL WCMD_is_magic_envvar(const WCHAR *s, const WCHAR *magicvar)
+{
+ int len;
+
+ if (s[0] != '%')
+ return FALSE; /* Didn't begin with % */
+ len = strlenW(s);
+ if (len < 2 || s[len-1] != '%')
+ return FALSE; /* Didn't end with another % */
+
+ if (CompareStringW(LOCALE_USER_DEFAULT,
+ NORM_IGNORECASE | SORT_STRINGSORT,
+ s+1, len-2, magicvar, -1) != CSTR_EQUAL) {
+ /* Name doesn't match. */
+ return FALSE;
+ }
+
+ if (GetEnvironmentVariableW(magicvar, NULL, 0) > 0) {
+ /* Masked by real environment variable. */
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*************************************************************************
* WCMD_expand_envvar
*
* Expands environment variables, allowing for WCHARacter substitution
@@ -489,15 +520,10 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
int len;
static const WCHAR ErrorLvl[] = {'E','R','R','O','R','L','E','V','E','L','\0'};
- static const WCHAR ErrorLvlP[] = {'%','E','R','R','O','R','L','E','V','E','L','%','\0'};
static const WCHAR Date[] = {'D','A','T','E','\0'};
- static const WCHAR DateP[] = {'%','D','A','T','E','%','\0'};
static const WCHAR Time[] = {'T','I','M','E','\0'};
- static const WCHAR TimeP[] = {'%','T','I','M','E','%','\0'};
static const WCHAR Cd[] = {'C','D','\0'};
- static const WCHAR CdP[] = {'%','C','D','%','\0'};
static const WCHAR Random[] = {'R','A','N','D','O','M','\0'};
- static const WCHAR RandomP[] = {'%','R','A','N','D','O','M','%','\0'};
static const WCHAR Delims[] = {'%',' ',':','\0'};
WINE_TRACE("Expanding: %s (%s,%s)\n", wine_dbgstr_w(start),
@@ -545,47 +571,22 @@ static WCHAR *WCMD_expand_envvar(WCHAR *start, WCHAR *forVar, WCHAR *forVal) {
/* Expand to contents, if unchanged, return */
/* Handle DATE, TIME, ERRORLEVEL and CD replacements allowing */
/* override if existing env var called that name */
- if ((CompareStringW(LOCALE_USER_DEFAULT,
- NORM_IGNORECASE | SORT_STRINGSORT,
- thisVar, 12, ErrorLvlP, -1) == 2) &&
- (GetEnvironmentVariableW(ErrorLvl, thisVarContents, 1) == 0) &&
- (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
+ if (WCMD_is_magic_envvar(thisVar, ErrorLvl)) {
static const WCHAR fmt[] = {'%','d','\0'};
wsprintfW(thisVarContents, fmt, errorlevel);
len = strlenW(thisVarContents);
-
- } else if ((CompareStringW(LOCALE_USER_DEFAULT,
- NORM_IGNORECASE | SORT_STRINGSORT,
- thisVar, 6, DateP, -1) == 2) &&
- (GetEnvironmentVariableW(Date, thisVarContents, 1) == 0) &&
- (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
-
+ } else if (WCMD_is_magic_envvar(thisVar, Date)) {
GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL,
NULL, thisVarContents, MAXSTRING);
len = strlenW(thisVarContents);
-
- } else if ((CompareStringW(LOCALE_USER_DEFAULT,
- NORM_IGNORECASE | SORT_STRINGSORT,
- thisVar, 6, TimeP, -1) == 2) &&
- (GetEnvironmentVariableW(Time, thisVarContents, 1) == 0) &&
- (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
+ } else if (WCMD_is_magic_envvar(thisVar, Time)) {
GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, NULL,
NULL, thisVarContents, MAXSTRING);
len = strlenW(thisVarContents);
-
- } else if ((CompareStringW(LOCALE_USER_DEFAULT,
- NORM_IGNORECASE | SORT_STRINGSORT,
- thisVar, 4, CdP, -1) == 2) &&
- (GetEnvironmentVariableW(Cd, thisVarContents, 1) == 0) &&
- (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
+ } else if (WCMD_is_magic_envvar(thisVar, Cd)) {
GetCurrentDirectoryW(MAXSTRING, thisVarContents);
len = strlenW(thisVarContents);
-
- } else if ((CompareStringW(LOCALE_USER_DEFAULT,
- NORM_IGNORECASE | SORT_STRINGSORT,
- thisVar, 8, RandomP, -1) == 2) &&
- (GetEnvironmentVariableW(Random, thisVarContents, 1) == 0) &&
- (GetLastError() == ERROR_ENVVAR_NOT_FOUND)) {
+ } else if (WCMD_is_magic_envvar(thisVar, Random)) {
static const WCHAR fmt[] = {'%','d','\0'};
wsprintfW(thisVarContents, fmt, rand() % 32768);
len = strlenW(thisVarContents);
More information about the wine-cvs
mailing list