* Bug 15817 fixed: now ascii(c) with c>=128 does not crash on OSX 97/20797/4
Stéphane Mottelet [Mon, 22 Oct 2018 17:09:46 +0000 (19:09 +0200)]
http://bugzilla.scilab.org/show_bug.cgi?id=15817

Finally, we only patch to_wide_string() to use iconv as Linux
and keep a specific wide_string_to_UTF8() for OSX.

Problems which lead to revert https://codereview.scilab.org/#/c/20775/
do not occur with this smarter patch. Tests have been made with a
standalone packaged application launched from the Finder, under
Sierra, High Sierra and Mojave.

Change-Id: I091d74adb04e78fc36e7b8e35964799924518dec

scilab/CHANGES.md
scilab/modules/localization/src/c/charEncoding.c
scilab/modules/localization/tests/nonreg_tests/bug_15817.tst [new file with mode: 0644]

index 61e8f7d..ac15325 100644 (file)
@@ -686,6 +686,7 @@ Known issues
 * [#15814](http://bugzilla.scilab.org/show_bug.cgi?id=15814): Selecting graphic children with booleans yielded an error.
 * [#15815](http://bugzilla.scilab.org/show_bug.cgi?id=15815): After `polarplot()`, reversing axes or switching `gca().rotation_angles` shifted all angular and radial labels.
 * [#15816](http://bugzilla.scilab.org/show_bug.cgi?id=15816): `polarplot()`, `pie()`, `mesh()` and  `contourf()` ignored / canceled any upstream `drawlater`.
+* [#15817](http://bugzilla.scilab.org/show_bug.cgi?id=15817): `ascii(c)` with c>=128 crashed on OSX.
 * [#15818](http://bugzilla.scilab.org/show_bug.cgi?id=15818): `polarplot()` example could not be subplotted. `polarplot`'s demo did not display 'View code' and too often prompted the user.
 * [#15827](http://bugzilla.scilab.org/show_bug.cgi?id=15828): After `bode(..'rad')`, abscissae were titled 'Fréquence' instead of 'Pulsation' in french, and datatips still shew 'Hz' instead of 'rad/s'.
 * [#15830](http://bugzilla.scilab.org/show_bug.cgi?id=15830): `linspace` was not reliable for series of encoded integers.
index e0ee5b6..448787f 100644 (file)
@@ -113,7 +113,56 @@ int wcstat(char* filename, struct _stat *st)
     return stat_result;
 }
 /*--------------------------------------------------------------------------*/
-#else
+#else /* OSX or Linux */
+wchar_t *to_wide_string(const char *_UTFStr)
+{
+    wchar_t* pOutSave = NULL;
+    char* pInSave = NULL;
+    size_t iSize = 0;
+    size_t iLeftIn = 0;
+    size_t iLeftOut = 0;
+    iconv_t cd_UTF8_to_UTF16 = NULL;
+    wchar_t* pOut = NULL;
+
+    if (_UTFStr == NULL)
+    {
+        return NULL;
+    }
+
+    cd_UTF8_to_UTF16 = iconv_open("WCHAR_T", "UTF-8");
+
+    iLeftIn = strlen(_UTFStr);
+    pInSave = (char*)_UTFStr;
+
+    iLeftOut = (iLeftIn + 1) * sizeof(wchar_t);
+    pOut = (wchar_t*)MALLOC(iLeftOut);
+    memset(pOut, 0x00, iLeftOut);
+    pOutSave = pOut;
+
+    iSize = iconv(cd_UTF8_to_UTF16, (char**)&_UTFStr, &iLeftIn, (char**)&pOut, &iLeftOut);
+    iconv_close(cd_UTF8_to_UTF16);
+    if (iSize == (size_t)(-1))
+    {
+        iconv_t cd_ISO8851_to_UTF16 = iconv_open("WCHAR_T", "ISO_8859-1");
+
+        _UTFStr = pInSave;
+        iLeftIn = strlen(_UTFStr);
+
+        iLeftOut = (iLeftIn + 1) * sizeof(wchar_t);
+        pOut = pOutSave;
+        memset(pOut, 0x00, iLeftOut);
+
+
+        iSize = iconv(cd_ISO8851_to_UTF16, (char**)&_UTFStr, &iLeftIn, (char**)&pOut, &iLeftOut);
+        iconv_close(cd_ISO8851_to_UTF16);
+        if (iSize == (size_t)(-1))
+        {
+            FREE(pOut);
+            return NULL;
+        }
+    }
+    return pOutSave;
+}
 /*--------------------------------------------------------------------------*/
 #ifdef __APPLE__ // Mac OS X
 /*--------------------------------------------------------------------------*/
@@ -152,46 +201,6 @@ char *wide_string_to_UTF8(const wchar_t *_wide)
     return pchar;
 }
 /*--------------------------------------------------------------------------*/
-wchar_t *to_wide_string(const char *_UTFStr)
-{
-    wchar_t *_buf = NULL;
-    size_t pszLen = 0;
-    char *psz = _UTFStr;
-    mbstate_t ps;
-
-    if (_UTFStr == NULL)
-    {
-        return NULL;
-    }
-
-    memset (&ps, 0x00, sizeof(ps));
-    pszLen = mbsrtowcs(NULL, (const char**)&psz, 0, &ps);
-
-    if ( pszLen == (size_t)(-1) )
-    {
-        return NULL;
-    }
-
-    _buf = (wchar_t*)MALLOC((pszLen + 1) * sizeof(wchar_t));
-    if (_buf == NULL)
-    {
-        return NULL;
-    }
-
-    pszLen = mbsrtowcs(_buf, (const char**)&psz, (int)strlen(psz), &ps);
-
-    if ( pszLen == (size_t)(-1) )
-    {
-        FREE(_buf);
-        return NULL;
-    }
-    else
-    {
-        _buf[pszLen] = L'\0';
-    }
-    return _buf;
-}
-/*--------------------------------------------------------------------------*/
 #else // Linux
 /*--------------------------------------------------------------------------*/
 char *wide_string_to_UTF8(const wchar_t *_wide)
@@ -230,56 +239,6 @@ char *wide_string_to_UTF8(const wchar_t *_wide)
     return pOutSave;
 }
 /*--------------------------------------------------------------------------*/
-wchar_t *to_wide_string(const char *_UTFStr)
-{
-    wchar_t* pOutSave = NULL;
-    char* pInSave = NULL;
-    size_t iSize = 0;
-    size_t iLeftIn = 0;
-    size_t iLeftOut = 0;
-    iconv_t cd_UTF8_to_UTF16 = NULL;
-    wchar_t* pOut = NULL;
-
-    if (_UTFStr == NULL)
-    {
-        return NULL;
-    }
-
-    cd_UTF8_to_UTF16 = iconv_open("WCHAR_T", "UTF-8");
-
-    iLeftIn = strlen(_UTFStr);
-    pInSave = (char*)_UTFStr;
-
-    iLeftOut = (iLeftIn + 1) * sizeof(wchar_t);
-    pOut = (wchar_t*)MALLOC(iLeftOut);
-    memset(pOut, 0x00, iLeftOut);
-    pOutSave = pOut;
-
-    iSize = iconv(cd_UTF8_to_UTF16, (char**)&_UTFStr, &iLeftIn, (char**)&pOut, &iLeftOut);
-    iconv_close(cd_UTF8_to_UTF16);
-    if (iSize == (size_t)(-1))
-    {
-        iconv_t cd_ISO8851_to_UTF16 = iconv_open("WCHAR_T", "ISO_8859-1");
-
-        _UTFStr = pInSave;
-        iLeftIn = strlen(_UTFStr);
-
-        iLeftOut = (iLeftIn + 1) * sizeof(wchar_t);
-        pOut = pOutSave;
-        memset(pOut, 0x00, iLeftOut);
-
-
-        iSize = iconv(cd_ISO8851_to_UTF16, (char**)&_UTFStr, &iLeftIn, (char**)&pOut, &iLeftOut);
-        iconv_close(cd_ISO8851_to_UTF16);
-        if (iSize == (size_t)(-1))
-        {
-            FREE(pOut);
-            return NULL;
-        }
-    }
-    return pOutSave;
-}
-/*--------------------------------------------------------------------------*/
 #endif
 /*--------------------------------------------------------------------------*/
 int wcstat(char* filename, struct stat *st)
diff --git a/scilab/modules/localization/tests/nonreg_tests/bug_15817.tst b/scilab/modules/localization/tests/nonreg_tests/bug_15817.tst
new file mode 100644 (file)
index 0000000..011342b
--- /dev/null
@@ -0,0 +1,21 @@
+// =============================================================================
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) 2018 - Stéphane MOTTELET
+//
+//  This file is distributed under the same license as the Scilab package.
+// =============================================================================
+// <-- MACOSX ONLY -->
+// <-- CLI SHELL MODE -->
+// <-- NO CHECK REF -->
+//
+// <-- Non-regression test for bug 15817 -->
+//
+// <-- Bugzilla URL -->
+// http://bugzilla.scilab.org/show_bug.cgi?id=15817
+//
+// <-- Short Description -->
+// ascii(c); with c>=128 crashes on OSX
+
+// ascii(128)=="€" is false under Linux and OSX hence we test only 
+// visible chars starting from ascii code 161
+assert_checkequal(ascii([161:255]),"¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ")
\ No newline at end of file