Skip to content

Commit

Permalink
Strings with embedded null terms passed incorrectly as BSTR ext call …
Browse files Browse the repository at this point in the history
…args

BSTRs are sized strings, so can contain embedded null terminators.
  • Loading branch information
blairmcg committed Feb 18, 2018
1 parent 337550c commit 2259c49
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 22 deletions.
10 changes: 3 additions & 7 deletions ExternalCall.asm
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ extern NewUtf16String:near32
NewUtf16StringFromString EQU ?New@Utf16String@ST@@SIPAV?$TOTE@VUtf16String@ST@@@@PAV?$TOTE@VString@ST@@@@@Z
extern NewUtf16StringFromString:near32

NewBSTR EQU ?NewBSTR@@YIPAV?$TOTE@VExternalAddress@ST@@@@PAV?$TOTE@VBehavior@ST@@@@PAX@Z
NewBSTR EQU ?NewBSTR@@YIPAV?$TOTE@VExternalAddress@ST@@@@PAV?$TOTE@VObject@ST@@@@@Z
extern NewBSTR:near32

NewGUID EQU ?NewGUID@@YIPAV?$TOTE@VVariantByteObject@ST@@@@PAU_GUID@@@Z
Expand Down Expand Up @@ -1026,12 +1026,8 @@ extCallArgBSTR:
mov TEMP, [ARG].m_oteClass ; Get class of ARG into TEMP
ASSUME TEMP:PTR OTE

mov ARG, [ARG].m_location
ASSUME ARG:PTR ByteArray ; No, its bytes

.IF (TEMP != [Pointers.ClassBSTR] && TEMP != [Pointers.ClassLargeInteger])
ASSERTEQU %TEMP, <ecx>
mov edx, ARG
mov ecx, ARG
call NewBSTR
ASSUME eax:PTR OTE

Expand All @@ -1041,9 +1037,9 @@ extCallArgBSTR:
AddToZctNoSP <a>

mov eax, [_SP+OOPSIZE]
mov ARG, [eax].m_location
.ENDIF

mov ARG, [ARG].m_location
; ARG now contains address of bytes
ASSUME ARG:PTR ByteArray

Expand Down
28 changes: 13 additions & 15 deletions extcall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,13 @@ OTE* __fastcall ExternalStructure::New(BehaviorOTE* classPointer, void* ptr)
///////////////////////////////////////////////////////////////////////////////
// Answer a new BSTR from the specified UTF16 string

AddressOTE* __fastcall NewBSTR(LPCWSTR szContents)
AddressOTE* __fastcall NewBSTR(WCHAR* pChars, size_t len)
{
AddressOTE* resultPointer = reinterpret_cast<AddressOTE*>(ObjectMemory::newUninitializedByteObject(Pointers.ClassBSTR, sizeof(BYTE*)));
ExternalAddress* extAddress = resultPointer->m_location;
if (*szContents)
if (len > 0)
{
extAddress->m_pointer = reinterpret_cast<BYTE*>(::SysAllocString(szContents));
extAddress->m_pointer = reinterpret_cast<BYTE*>(::SysAllocStringLen(pChars, len));
resultPointer->beFinalizable();
}
else
Expand All @@ -136,31 +136,29 @@ AddressOTE* __fastcall NewBSTR(LPCWSTR szContents)
}

// Answer a new BSTR converted from the a byte string with the specified encoding
template <UINT CP> static AddressOTE* __fastcall NewBSTR(LPCSTR szContents)
template <UINT CP> static AddressOTE* __fastcall NewBSTR(const char* szContents, size_t len)
{
int ret = MultiByteToWideChar(CP, 0, szContents, -1, nullptr, 0);
if (ret == 0) return nullptr;
LPWSTR wsz = static_cast<LPWSTR>(alloca(ret * sizeof(OLECHAR)));
ret = MultiByteToWideChar(CP, 0, szContents, -1, wsz, ret);
if (ret == 0) return nullptr;

return NewBSTR(wsz);
Utf16StringOTE* utf16 = Utf16String::New<CP>(szContents, len);
AddressOTE* answer = NewBSTR(utf16->m_location->m_characters, utf16->getSize() / sizeof(WCHAR));
ObjectMemory::deallocateByteObject((OTE*)utf16);
return answer;
}

AddressOTE* __fastcall NewBSTR(BehaviorOTE* oteClass, void* pChars)
AddressOTE* __fastcall NewBSTR(OTE* oteString)
{
BehaviorOTE* oteClass = oteString->m_oteClass;
if (oteClass == Pointers.ClassUtf16String)
{
return NewBSTR(static_cast<LPCWSTR>(pChars));
return NewBSTR(reinterpret_cast<Utf16StringOTE*>(oteString)->m_location->m_characters, oteString->getSize()/sizeof(WCHAR));
}
else if (oteClass == Pointers.ClassUtf8String)
{
return NewBSTR<CP_UTF8>(static_cast<LPCSTR>(pChars));
return NewBSTR<CP_UTF8>(reinterpret_cast<Utf8StringOTE*>(oteString)->m_location->m_characters, oteString->getSize());
}
else if (oteClass->m_location->m_instanceSpec.m_nullTerminated)
{
// Assume it is an ANSI string
return NewBSTR<CP_ACP>(static_cast<LPCSTR>(pChars));
return NewBSTR<CP_ACP>(reinterpret_cast<StringOTE*>(oteString)->m_location->m_characters, oteString->getSize());
}
return nullptr;
}
Expand Down

0 comments on commit 2259c49

Please sign in to comment.