Found yet one more case with heap corruption: =>0 0x401c2369 (HEAP_CreateFreeBlock+0x104(subheap=0x40300000, ptr=0x40364b78, size=0xb488) [heap.c:429] in NTDLL.DLL) (ebp=408dfc14) 1 0x401c242a (HEAP_MakeInUseBlockFree+0x7d(subheap=0x40300000, pArena=0x40364b78) [heap.c:466] in NTDLL.DLL) (ebp=408dfc3c) 2 0x401c3c30 (RtlFreeHeap+0x12a(heap=0x40300000, flags=0x2, ptr=0x40364b80) [heap.c:1202] in NTDLL.DLL) (ebp=408dfc68) 3 0x4047d7bc (HeapFree+0x1e(heap=0x40300000, flags=0x0, ptr=0x40364b80) [heap.c:284] in KERNEL32.DLL) (ebp=408dfc80) 4 0x4048bef9 (get_registry_locale_info+0x25e(flags=0x0, value=0x40512302, buffer=0x0, len=0x0) [locale.c:822] in KERNEL32.DLL) (ebp=408dfcc8) 5 0x4048c15c (GetLocaleInfoW+0xec(lcid=0x419, lctype=0x28, buffer=0x0, len=0x0) [locale.c:933] in KERNEL32.DLL) (ebp=408dfd20) 6 0x4048bf5b (GetLocaleInfoA+0x54(lcid=0x419, lctype=0x28, buffer=0x408dfd70, len=0x100) [locale.c:859] in KERNEL32.DLL) (ebp=408dfd50)
The heap corruption happens here: ((WCHAR *)info->Data)[ret] = '\0'; Should we move it somewhere else? Because in this case this is the only one thing, that's being executed (it's not a number nor buffer is set). BTW reading MSDN it's clearly stated, that: "lpLCData [out] Pointer to a buffer that receives the requested data. This pointer is not used if cchData is zero." Why are we using !buffer as an indication for this not the !len ? I'm not sure if I want to submit a patch for this. There few things that I don't feel comfortable about. Attached is something that fixed the problem for me. But I have a gut feeling this function needs to be redone. Friday, December 5, 2003, 9:29:34 AM, you wrote: > Yep that is the problem I was seeing with one program I'm running. And this > patch took care of it. Thanks! > Vitaliy Margolen > Tuesday, December 2, 2003, 13:01:18, Vitaliy Margolen wrote: >> Hi, found a problem with the latest locale changes. When it calls the >> GetLocaleInfoW() function, the attached error occurs. >> This occurred because of the new code using the LOCALE_RETURN_NUMBER flag. The >> problem is if the buffer supplied to get_registry_locale_info is quite small >> (say sizeof(INT)). The value returned by NtQueryValueKey() however, is for a >> string, and is much longer. As NtQueryValueKey updates the value of size, >> this caused other parts of the code to corrupt memory.
Index: locale.c =================================================================== RCS file: /home/wine/wine/dlls/kernel/locale.c,v retrieving revision 1.27 diff -u -r1.27 locale.c --- locale.c 1 Dec 2003 22:46:19 -0000 1.27 +++ locale.c 13 Dec 2003 17:52:11 -0000 @@ -742,6 +742,7 @@ static INT get_registry_locale_info( UINT flags, LPCWSTR value, LPWSTR buffer, INT len ) { DWORD size; + DWORD resultSize; INT ret; HKEY hkey; NTSTATUS status; @@ -761,8 +762,9 @@ return 0; } - status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, info, size, &size ); + status = NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, info, size, &resultSize ); if (status == STATUS_BUFFER_OVERFLOW && !buffer) status = 0; + if (!(flags & LOCALE_RETURN_NUMBER)) size = info_size + resultSize; if (!status) { @@ -772,7 +774,8 @@ { if (ret < len || !buffer) { - ((WCHAR *)info->Data)[ret] = '\0'; + if (buffer) + ((WCHAR *)info->Data)[ret] = '\0'; ret++; } else