From 475485ce5b9419472f23355aa17d58e94b676a3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Sat, 8 Nov 2014 22:56:49 +0100 Subject: [PATCH] Added patch to fix crash in atof and strtod when passing NULL as string. --- README.md | 3 +- patches/Makefile | 19 +++ ...sh-when-NULL-pointer-is-passed-to-at.patch | 141 ++++++++++++++++++ patches/msvcrt-atof_strtod/definition | 4 + 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 patches/msvcrt-atof_strtod/0001-msvcrt-Avoid-crash-when-NULL-pointer-is-passed-to-at.patch create mode 100644 patches/msvcrt-atof_strtod/definition diff --git a/README.md b/README.md index a2f5c34d..ab228c21 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Wine. All those differences are also documented on the Included bug fixes and improvements =================================== -**Bugfixes and features included in the next upcoming release [12]:** +**Bugfixes and features included in the next upcoming release [13]:** * Add stub for NtSetLdtEntries/ZwSetLdtEntries ([Wine Bug #26268](https://bugs.winehq.org/show_bug.cgi?id=26268)) * Add stubs for vectored continue handler ([Wine Bug #30572](https://bugs.winehq.org/show_bug.cgi?id=30572)) @@ -50,6 +50,7 @@ Included bug fixes and improvements * FairplayKD.sys needs KeSetSystemAffinityThread ([Wine Bug #36822](https://bugs.winehq.org/show_bug.cgi?id=36822)) * Fix crash of Trine Demo on start ([Wine Bug #19231](https://bugs.winehq.org/show_bug.cgi?id=19231)) * Fix texture corruption in CSI: Fatal Conspiracy ([Wine Bug #33768](https://bugs.winehq.org/show_bug.cgi?id=33768)) +* MSVCRT crashes when NULL is passed as string to atof or strtod ([Wine Bug #32550](https://bugs.winehq.org/show_bug.cgi?id=32550)) * Return correct values for GetThreadTimes function ([Wine Bug #20230](https://bugs.winehq.org/show_bug.cgi?id=20230)) * vSphere needs IoCsqInitialize ([Wine Bug #36777](https://bugs.winehq.org/show_bug.cgi?id=36777)) * wglDescribePixelFormat should return max index for NULL descriptor ([Wine Bug #6176](https://bugs.winehq.org/show_bug.cgi?id=6176)) diff --git a/patches/Makefile b/patches/Makefile index 5bec4d80..85a1ba1e 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -51,6 +51,7 @@ PATCHLIST := \ libs-Unicode_Collation.ok \ libwine-BSD_mmap_fixed.ok \ msvcp90-basic_string_wchar_dtor.ok \ + msvcrt-atof_strtod.ok \ ntdll-DOS_Attributes.ok \ ntdll-Dynamic_DST.ok \ ntdll-Exception.ok \ @@ -787,6 +788,24 @@ msvcp90-basic_string_wchar_dtor.ok: echo '+ { "msvcp90-basic_string_wchar_dtor", "Michael Müller", "basic_string_wchar_dtor needs to return NULL." },'; \ ) > msvcp90-basic_string_wchar_dtor.ok +# Patchset msvcrt-atof_strtod +# | +# | Included patches: +# | * Do not crash when passing NULL as string to atof or strtod. [by Michael Müller] +# | +# | This patchset fixes the following Wine bugs: +# | * [#32550] MSVCRT crashes when NULL is passed as string to atof or strtod +# | +# | Modified files: +# | * dlls/msvcrt/string.c, dlls/msvcrt/tests/string.c +# | +.INTERMEDIATE: msvcrt-atof_strtod.ok +msvcrt-atof_strtod.ok: + $(call APPLY_FILE,msvcrt-atof_strtod/0001-msvcrt-Avoid-crash-when-NULL-pointer-is-passed-to-at.patch) + @( \ + echo '+ { "msvcrt-atof_strtod", "Michael Müller", "Do not crash when passing NULL as string to atof or strtod." },'; \ + ) > msvcrt-atof_strtod.ok + # Patchset ntdll-DOS_Attributes # | # | Included patches: diff --git a/patches/msvcrt-atof_strtod/0001-msvcrt-Avoid-crash-when-NULL-pointer-is-passed-to-at.patch b/patches/msvcrt-atof_strtod/0001-msvcrt-Avoid-crash-when-NULL-pointer-is-passed-to-at.patch new file mode 100644 index 00000000..e170e1f7 --- /dev/null +++ b/patches/msvcrt-atof_strtod/0001-msvcrt-Avoid-crash-when-NULL-pointer-is-passed-to-at.patch @@ -0,0 +1,141 @@ +From e600a4020ee684f73376d5c7389e6326291d3f1b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 8 Nov 2014 22:39:28 +0100 +Subject: msvcrt: Avoid crash when NULL pointer is passed to atof / strtod + functions. + +--- + dlls/msvcrt/string.c | 6 +++++ + dlls/msvcrt/tests/string.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 70 insertions(+) + +diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c +index 6f9280f..d933643 100644 +--- a/dlls/msvcrt/string.c ++++ b/dlls/msvcrt/string.c +@@ -434,6 +434,12 @@ static double strtod_helper(const char *str, char **end, MSVCRT__locale_t locale + */ + double CDECL MSVCRT_strtod_l(const char *str, char **end, MSVCRT__locale_t locale) + { ++ if (!str) ++ { ++ if (end) *end = NULL; ++ *MSVCRT__errno() = MSVCRT_EINVAL; ++ return 0.0; ++ } + return strtod_helper(str, end, locale, NULL); + } + +diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c +index 1788035..5620c6d 100644 +--- a/dlls/msvcrt/tests/string.c ++++ b/dlls/msvcrt/tests/string.c +@@ -89,6 +89,8 @@ static int (__cdecl *p_tolower)(int); + static size_t (__cdecl *p_mbrlen)(const char*, size_t, mbstate_t*); + static size_t (__cdecl *p_mbrtowc)(wchar_t*, const char*, size_t, mbstate_t*); + static int (__cdecl *p__atodbl_l)(_CRT_DOUBLE*,char*,_locale_t); ++static double (__cdecl *p__atof_l)(const char*,_locale_t); ++static double (__cdecl *p__strtod_l)(const char *,char**,_locale_t); + static int (__cdecl *p__strnset_s)(char*,size_t,int,size_t); + + #define SETNOFAIL(x,y) x = (void*)GetProcAddress(hMsvcrt,y) +@@ -1552,6 +1554,31 @@ static void test__strtod(void) + char *end; + double d; + ++ errno = EBADF; ++ d = strtod(NULL, NULL); ++ ok(almost_equal(d, 0.0), "strtod(NULL, NULL) = %lf\n", d); ++ ok(errno == EINVAL, "errno = %d\n", errno); ++ ++ d = strtod("1.0", NULL); ++ ok(almost_equal(d, 1.0), "strtod(\"1.0\", NULL) = %lf\n", d); ++ ++ errno = EBADF; ++ end = (char *)0xdeadbeef; ++ d = strtod(NULL, &end); ++ ok(almost_equal(d, 0.0), "strtod(NULL, &end) = %lf\n", d); ++ ok(errno == EINVAL, "errno = %d\n", errno); ++ ok(!end, "ptr = %p\n", end); ++ ++ if (!p__strtod_l) ++ win_skip("_strtod_l not found\n"); ++ else ++ { ++ errno = EBADF; ++ d = p__strtod_l(NULL, NULL, NULL); ++ ok(almost_equal(d, 0.0), "_strtod_l(NULL, NULL, NULL) = %lf\n", d); ++ ok(errno == EINVAL, "errno = %d\n", errno); ++ } ++ + d = strtod(double1, &end); + ok(almost_equal(d, 12.1), "d = %lf\n", d); + ok(end == double1+4, "incorrect end (%d)\n", (int)(end-double1)); +@@ -2609,6 +2636,11 @@ static void test_atoi(void) + { + int r; + ++ errno = EBADF; ++ r = atoi(NULL); ++ ok(r == 0, "atoi(NULL) = %d\n", r); ++ ok(errno == EBADF, "errno = %d\n", errno); ++ + r = atoi("0"); + ok(r == 0, "atoi(0) = %d\n", r); + +@@ -2622,6 +2654,35 @@ static void test_atoi(void) + ok(r == 0, "atoi(4294967296) = %d\n", r); + } + ++static void test_atof(void) ++{ ++ double r; ++ ++ errno = EBADF; ++ r = atof(NULL); ++ ok(almost_equal(r, 0.0), "atof(NULL) = %lf\n", r); ++ ok(errno == EINVAL, "errno = %d\n", errno); ++ ++ r = atof("0.0"); ++ ok(almost_equal(r, 0.0), "atof(0.0) = %lf\n", r); ++ ++ r = atof("-1.0"); ++ ok(almost_equal(r, -1.0), "atof(-1.0) = %lf\n", r); ++ ++ r = atof("1.0"); ++ ok(almost_equal(r, 1.0), "atof(1.0) = %lf\n", r); ++ ++ if (!p__atof_l) ++ win_skip("_atof_l not found\n"); ++ else ++ { ++ errno = EBADF; ++ r = p__atof_l(NULL, NULL); ++ ok(r == 0.0, "_atof_l(NULL, NULL) = %lf\n", r); ++ ok(errno == EINVAL, "errno = %d\n", errno); ++ } ++} ++ + static void test_strncpy(void) + { + #define TEST_STRNCPY_LEN 10 +@@ -2796,6 +2857,8 @@ START_TEST(string) + p_mbrtowc = (void*)GetProcAddress(hMsvcrt, "mbrtowc"); + p_mbsrtowcs = (void*)GetProcAddress(hMsvcrt, "mbsrtowcs"); + p__atodbl_l = (void*)GetProcAddress(hMsvcrt, "_atodbl_l"); ++ p__atof_l = (void*)GetProcAddress(hMsvcrt, "_atof_l"); ++ p__strtod_l = (void*)GetProcAddress(hMsvcrt, "_strtod_l"); + p__strnset_s = (void*)GetProcAddress(hMsvcrt, "_strnset_s"); + + /* MSVCRT memcpy behaves like memmove for overlapping moves, +@@ -2848,6 +2911,7 @@ START_TEST(string) + test__stricmp(); + test__wcstoi64(); + test_atoi(); ++ test_atof(); + test_strncpy(); + test_strxfrm(); + test__strnset_s(); +-- +1.9.1 + diff --git a/patches/msvcrt-atof_strtod/definition b/patches/msvcrt-atof_strtod/definition new file mode 100644 index 00000000..e28d0055 --- /dev/null +++ b/patches/msvcrt-atof_strtod/definition @@ -0,0 +1,4 @@ +Author: Michael Müller +Subject: Do not crash when passing NULL as string to atof or strtod. +Revision: 1 +Fixes: [32550] MSVCRT crashes when NULL is passed as string to atof or strtod