Piotr Caban : vbscript: Support multibyte characters in Global_Chr.

Alexandre Julliard julliard at winehq.org
Mon May 19 15:10:00 CDT 2014


Module: wine
Branch: master
Commit: 193de805a1e0ed291d721ad13a5c8cd8494aac4e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=193de805a1e0ed291d721ad13a5c8cd8494aac4e

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon May 19 16:44:02 2014 +0200

vbscript: Support multibyte characters in Global_Chr.

---

 dlls/vbscript/global.c      |   26 ++++++++++++++++++++++----
 dlls/vbscript/tests/api.vbs |   14 ++++++++++++--
 2 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/dlls/vbscript/global.c b/dlls/vbscript/global.c
index 484158f..7c44661 100644
--- a/dlls/vbscript/global.c
+++ b/dlls/vbscript/global.c
@@ -1129,9 +1129,15 @@ static HRESULT Global_Asc(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIA
     return E_NOTIMPL;
 }
 
+/* The function supports only single-byte and double-byte character sets. It
+ * ignores language specified by IActiveScriptSite::GetLCID. The argument needs
+ * to be in range of short or unsigned short. */
 static HRESULT Global_Chr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIANT *res)
 {
-    int c;
+    int cp, c, len = 0;
+    CPINFO cpi;
+    WCHAR ch;
+    char buf[2];
     HRESULT hres;
 
     TRACE("%s\n", debugstr_variant(arg));
@@ -1140,14 +1146,26 @@ static HRESULT Global_Chr(vbdisp_t *This, VARIANT *arg, unsigned args_cnt, VARIA
     if(FAILED(hres))
         return hres;
 
-    if(c < 0 || c >= 0x100) {
+    cp = GetACP();
+    if(!GetCPInfo(cp, &cpi))
+        cpi.MaxCharSize = 1;
+
+    if((c!=(short)c && c!=(unsigned short)c) ||
+            (unsigned short)c>=(cpi.MaxCharSize>1 ? 0x10000 : 0x100)) {
         WARN("invalid arg %d\n", c);
         return MAKE_VBSERROR(VBSE_ILLEGAL_FUNC_CALL);
     }
 
-    if(res) {
-        WCHAR ch = c;
+    if(c>>8)
+        buf[len++] = c>>8;
+    if(!len || IsDBCSLeadByteEx(cp, buf[0]))
+        buf[len++] = c;
+    if(!MultiByteToWideChar(0, 0, buf, len, &ch, 1)) {
+        WARN("invalid arg %d, cp %d\n", c, cp);
+        return E_FAIL;
+    }
 
+    if(res) {
         V_VT(res) = VT_BSTR;
         V_BSTR(res) = SysAllocStringLen(&ch, 1);
         if(!V_BSTR(res))
diff --git a/dlls/vbscript/tests/api.vbs b/dlls/vbscript/tests/api.vbs
index 8197d6d..d7af8e9 100644
--- a/dlls/vbscript/tests/api.vbs
+++ b/dlls/vbscript/tests/api.vbs
@@ -140,12 +140,22 @@ Call ok(Chr(119.5) = "x", "Chr(119.5) = " & Chr(119.5))
 sub testChrError
     on error resume next
 
+    if isEnglishLang then
+        call Err.clear()
+        call Chr(-1)
+        call ok(Err.number = 5, "Err.number = " & Err.number)
+
+        call Err.clear()
+        call Chr(256)
+        call ok(Err.number = 5, "Err.number = " & Err.number)
+    end if
+
     call Err.clear()
-    call Chr(-1)
+    call Chr(65536)
     call ok(Err.number = 5, "Err.number = " & Err.number)
 
     call Err.clear()
-    call Chr(256)
+    call Chr(-32769)
     call ok(Err.number = 5, "Err.number = " & Err.number)
 end sub
 




More information about the wine-cvs mailing list