Modify

Opened 5 hours ago

#4046 new Bug

_WinAPI_MultiByteToWideChar - trailing junk characters in edge case.

Reported by: anonymous Owned by:
Milestone: Component: Standard UDFs
Version: 3.3.16.1 Severity: None
Keywords: Cc:

Description

Hi folks, just a quick suggestion for an improvement to _WinAPI_MultiByteToWideChar.

I've found its currently possible to receive some junk characters at the end of the outputted string. This happens when the input text is a struct, is NOT null-terminated, and there is other data in memory after the string.

The proposed fix would be to explicitly pass the struct length when IsDllStruct($vText) = True (at the moment this param is hard coded to -1).

#include <WinAPIConv.au3>

Global Const $CP_UTF8 = 65001

;Simulated struct already that's already in memory
Local $dUtf8 = Binary("0x48656C6C6F576F726C6421")
Local $iUtf8Len =  BinaryLen($dUtf8)
Local $tSomeStruct = DllStructCreate("byte utf8[" & $iUtf8Len & "];byte other_stuff[4]")
$tSomeStruct.utf8 = $dUtf8
$tSomeStruct.other_stuff = Binary("0xFFFFFFFF")

Local $tUTF8 = DllStructCreate("byte[" & $iUtf8Len & "]", DllStructGetPtr($tSomeStruct))

Local $tWstr = _WinAPI_MultiByteToWideChar($tUTF8, $CP_UTF8)
ConsoleWrite("Current Result:"  & @CRLF)
ConsoleWrite(DllStructGetData($tWstr, 1) & @CRLF & @CRLF)

Local $tWstr = _WinAPI_MultiByteToWideChar_Modified($tUTF8, $CP_UTF8)
ConsoleWrite("Modified Result:"  & @CRLF)
ConsoleWrite(DllStructGetData($tWstr, 1) & @CRLF)

Func _WinAPI_MultiByteToWideChar_Modified($vText, $iCodePage = 0, $iFlags = 0, $bRetString = False)
	Local $sTextType = ""
	If IsString($vText) Then $sTextType = "str"
	If (IsDllStruct($vText) Or IsPtr($vText)) Then $sTextType = "struct*"
	If $sTextType = "" Then Return SetError(1, 0, 0) ; invalid input parameter type
	Local $iTextLen = IsDllStruct($vText) ? DllStructGetSize($vText) : -1  ;--- ADDED LINE ----

	; compute size for the output WideChar
	Local $aCall = DllCall("kernel32.dll", "int", "MultiByteToWideChar", "uint", $iCodePage, "dword", $iFlags, _
			$sTextType, $vText, "int", $iTextLen, "ptr", 0, "int", 0)
	If @error Or Not $aCall[0] Then Return SetError(@error + 10, @extended, 0)

	; allocate space for output WideChar
	Local $iOut = $aCall[0]
	Local $tOut = DllStructCreate("wchar[" & $iOut & "]")

	$aCall = DllCall("kernel32.dll", "int", "MultiByteToWideChar", "uint", $iCodePage, "dword", $iFlags, $sTextType, $vText, _
			"int", $iTextLen, "struct*", $tOut, "int", $iOut)
	If @error Or Not $aCall[0] Then Return SetError(@error + 20, @extended, 0)

	If $bRetString Then Return DllStructGetData($tOut, 1)
	Return $tOut
EndFunc

Output:

Current Result:
HelloWorld!????

Modified Result:
HelloWorld!

Attachments (0)

Change History (0)

Guidelines for posting comments:

  • You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
  • In-depth discussions should take place on the forum.

For more information see the full version of the ticket guidelines here.

Add Comment

Modify Ticket

Action
as new The ticket will remain with no owner.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.