Add an error check for correct formatting in Deflate uncompressed
[sgt/halibut] / ustring.c
index 8cf8554..3c5698c 100644 (file)
--- a/ustring.c
+++ b/ustring.c
@@ -172,17 +172,18 @@ char *utoa_locale_dup(wchar_t const *s)
      * This variant uses the C library locale.
      */
     char *ret;
-    int len;
+    int len, outlen;
     size_t siz;
 
     len = ustrlen(s);
 
-    ret = snewn(1 + MB_CUR_MAX * len, char);
+    outlen = 1 + MB_CUR_MAX * len;
+    ret = snewn(outlen+1, char);
 
-    siz = wcstombs(ret, s, len);
+    siz = wcstombs(ret, s, outlen);
 
     if (siz) {
-       assert(siz <= MB_CUR_MAX * len);
+       assert(siz <= (size_t)(outlen));
        ret[siz] = '\0';
        ret = sresize(ret, siz+1, char);
        return ret;
@@ -203,17 +204,18 @@ wchar_t *ufroma_locale_dup(char const *s)
      * This variant uses the C library locale.
      */
     wchar_t *ret;
-    int len;
+    int len, outlen;
     size_t siz;
 
     len = strlen(s);
 
-    ret = snewn(1 + 2*len, wchar_t);  /* be conservative */
+    outlen = 1 + 2*len;
+    ret = snewn(outlen+1, wchar_t);  /* be conservative */
 
-    siz = mbstowcs(ret, s, len);
+    siz = mbstowcs(ret, s, outlen);
 
     if (siz) {
-       assert(siz <= (size_t)(2 * len));
+       assert(siz <= (size_t)(outlen));
        ret[siz] = L'\0';
        ret = sresize(ret, siz+1, wchar_t);
        return ret;
@@ -338,7 +340,7 @@ int utoi(wchar_t const *s) {
        s++;
     }
 
-    return n;
+    return n * sign;
 }
 
 double utof(wchar_t const *s)
@@ -459,3 +461,28 @@ int cvt_ok(int charset, const wchar_t *s)
     }
     return TRUE;
 }
+
+/*
+ * Wrapper around charset_from_localenc which accepts the charset
+ * name as a wide string (since that happens to be more useful).
+ * Also throws a Halibut error and falls back to CS_ASCII if the
+ * charset is unrecognised, meaning the rest of the program can
+ * rely on always getting a valid charset id back from this
+ * function.
+ */
+int charset_from_ustr(filepos *fpos, const wchar_t *name)
+{
+    char *csname;
+    int charset;
+
+    csname = utoa_dup(name, CS_ASCII);
+    charset = charset_from_localenc(csname);
+
+    if (charset == CS_NONE) {
+       charset = CS_ASCII;
+       error(err_charset, fpos, name);
+    }
+
+    sfree(csname);
+    return charset;
+}