Opened 3 months ago
Last modified 2 months ago
#4046 closed Feature Request
_WinAPI_MultiByteToWideChar - trailing junk characters in edge case. — at Initial Version
| Reported by: | anonymous | Owned by: | |
|---|---|---|---|
| Milestone: | Component: | Standard UDFs | |
| Version: | 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!
Note: See
TracTickets for help on using
tickets.
