Fix DupWCFromBytes/CharEncConv optimized return bug when converting UTF16LE license file to wchar_t(UTF16LE)
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6414 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
e63fa6c53b
commit
bb9b88b70f
3 changed files with 13 additions and 11 deletions
|
@ -991,12 +991,12 @@ int CEXEBuild::LoadLicenseFile(const TCHAR *file, TCHAR** pdata, const TCHAR *cm
|
||||||
fseek(f,cbBOMOffset,SEEK_SET);
|
fseek(f,cbBOMOffset,SEEK_SET);
|
||||||
UINT cbTotalData=sizeof(TCHAR)+cbFileData+sizeof(TCHAR); // SF_*+file+\0
|
UINT cbTotalData=sizeof(TCHAR)+cbFileData+sizeof(TCHAR); // SF_*+file+\0
|
||||||
TCHAR*data=(TCHAR*)malloc(cbTotalData);
|
TCHAR*data=(TCHAR*)malloc(cbTotalData);
|
||||||
|
*pdata=data; // memory will be released by caller
|
||||||
if (!data)
|
if (!data)
|
||||||
{
|
{
|
||||||
ERROR_MSG(_T("Internal compiler error #12345: %s malloc(%d) failed.\n"),cmdname,cbTotalData);
|
ERROR_MSG(_T("Internal compiler error #12345: %s malloc(%d) failed.\n"),cmdname,cbTotalData);
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
}
|
||||||
*pdata=data; // memory will be released by caller
|
|
||||||
*((TCHAR*)((char*)data+cbTotalData-sizeof(TCHAR)))=_T('\0');
|
*((TCHAR*)((char*)data+cbTotalData-sizeof(TCHAR)))=_T('\0');
|
||||||
|
|
||||||
TCHAR*ldata=data+1;
|
TCHAR*ldata=data+1;
|
||||||
|
@ -1014,16 +1014,16 @@ l_errwcconv:
|
||||||
ERROR_MSG(_T("%s: wchar_t conversion failed!\n"),cmdname);
|
ERROR_MSG(_T("%s: wchar_t conversion failed!\n"),cmdname);
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
}
|
||||||
// Create a fake character in the "header" part of the buffer
|
// Create a fake character in the "header" part of the buffer (For DupWCFromBytes)
|
||||||
char*lichdr=((char*)ldata) - cbcu;
|
char*lichdr=((char*)ldata) - cbcu;
|
||||||
*((char*)lichdr)='X';
|
*((char*)lichdr)='X';
|
||||||
if (cbcu > 1) *((WORD*)lichdr)='X';
|
if (cbcu > 1) *((WORD*)lichdr)='X';
|
||||||
//BUGBUG: No room: if (cbcu > 2) *((UINT32*)lichdr)='X';
|
//BUGBUG: No room: if (cbcu > 2) *((UINT32*)lichdr)='X';
|
||||||
wchar_t*wcdata=DupWCFromBytes(lichdr,cbcu+cbFileData,srccp);
|
const bool canOptRet = (char*)data == lichdr;
|
||||||
|
wchar_t*wcdata=DupWCFromBytes(lichdr,cbcu+cbFileData,srccp|(canOptRet?DWCFBF_ALLOWOPTIMIZEDRETURN:0));
|
||||||
if (!wcdata) goto l_errwcconv;
|
if (!wcdata) goto l_errwcconv;
|
||||||
free(data);
|
if (wcdata != data) free(data);
|
||||||
*pdata=data=wcdata;
|
*pdata=data=wcdata, ldata=data+1;
|
||||||
ldata=data+1;
|
|
||||||
|
|
||||||
const bool isRTF=!memcmp(ldata,_T("{\\rtf"),5*sizeof(TCHAR));
|
const bool isRTF=!memcmp(ldata,_T("{\\rtf"),5*sizeof(TCHAR));
|
||||||
if (isRTF)
|
if (isRTF)
|
||||||
|
|
|
@ -92,14 +92,15 @@ UINT WCFromCodePoint(wchar_t*Dest,UINT cchDest,UINT32 CodPt)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
wchar_t* DupWCFromBytes(void*Buffer,UINT cbBuffer,WORD SrcCP)
|
wchar_t* DupWCFromBytes(void*Buffer,UINT cbBuffer,UINT32 SrcCP)
|
||||||
{
|
{
|
||||||
/*\
|
/*\
|
||||||
Converts a buffer encoded with SrcCP to a \0 terminated wchar_t malloc'ed buffer.
|
Converts a buffer encoded with SrcCP to a \0 terminated wchar_t malloc'ed buffer.
|
||||||
Returns 0 on failure.
|
Returns 0 on failure.
|
||||||
\*/
|
\*/
|
||||||
CharEncConv cec;
|
CharEncConv cec;
|
||||||
if (!cec.Initialize(-1, SrcCP)) return 0;
|
cec.SetAllowOptimizedReturn(!!(SrcCP&DWCFBF_ALLOWOPTIMIZEDRETURN));
|
||||||
|
if (!cec.Initialize(-1, SrcCP&=~DWCFBF_ALLOWOPTIMIZEDRETURN)) return 0;
|
||||||
wchar_t *pWC = (wchar_t*) cec.Convert(Buffer, cbBuffer);
|
wchar_t *pWC = (wchar_t*) cec.Convert(Buffer, cbBuffer);
|
||||||
return pWC ? (wchar_t*) cec.Detach() : 0;
|
return pWC ? (wchar_t*) cec.Detach() : 0;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +184,7 @@ void* CharEncConv::Convert(const void*Src, size_t cbSrc, size_t*cbOut)
|
||||||
if (cbSrc && ((WORD*)Src)[--cbSrc]) ++cbSrc;
|
if (cbSrc && ((WORD*)Src)[--cbSrc]) ++cbSrc;
|
||||||
*cbOut = cbSrc * sizeof(wchar_t);
|
*cbOut = cbSrc * sizeof(wchar_t);
|
||||||
}
|
}
|
||||||
return (void*) Src;
|
return (void*) (m_Result = (char*) Src);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
char *p = (char*) realloc(m_Result, cbSrc + sizeof(UINT32));
|
char *p = (char*) realloc(m_Result, cbSrc + sizeof(UINT32));
|
||||||
|
|
|
@ -91,7 +91,8 @@ UINT StrLenUTF16(const void*str);
|
||||||
bool StrSetUTF16LE(tstring&dest, const void*src);
|
bool StrSetUTF16LE(tstring&dest, const void*src);
|
||||||
|
|
||||||
UINT WCFromCodePoint(wchar_t*Dest,UINT cchDest,UINT32 CodPt);
|
UINT WCFromCodePoint(wchar_t*Dest,UINT cchDest,UINT32 CodPt);
|
||||||
wchar_t* DupWCFromBytes(void*Buffer,UINT cbBuffer,WORD SrcCP);
|
#define DWCFBF_ALLOWOPTIMIZEDRETURN 0x80000000 // DupWCFromBytes can return input Buffer
|
||||||
|
wchar_t* DupWCFromBytes(void*Buffer,UINT cbBuffer,UINT32 SrcCP);
|
||||||
UINT DetectUTFBOM(void*Buffer,UINT cb);
|
UINT DetectUTFBOM(void*Buffer,UINT cb);
|
||||||
UINT DetectUTFBOM(FILE*strm);
|
UINT DetectUTFBOM(FILE*strm);
|
||||||
WORD GetEncodingFromString(const TCHAR*s, bool&BOM);
|
WORD GetEncodingFromString(const TCHAR*s, bool&BOM);
|
||||||
|
@ -110,7 +111,7 @@ protected:
|
||||||
static bool IsWE(WORD Encoding) { return (WORD)-1 == Encoding; }
|
static bool IsWE(WORD Encoding) { return (WORD)-1 == Encoding; }
|
||||||
static bool IsWE(UINT32 Encoding) { return (UINT32)-1 == Encoding; }
|
static bool IsWE(UINT32 Encoding) { return (UINT32)-1 == Encoding; }
|
||||||
public:
|
public:
|
||||||
CharEncConv() : m_Result(0) {}
|
CharEncConv() : m_Result(0) { SetAllowOptimizedReturn(false); }
|
||||||
~CharEncConv() { Close(); }
|
~CharEncConv() { Close(); }
|
||||||
void Close()
|
void Close()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue