CVE-2015-5330: Fix handling of unicode near string endings
[samba.git] / lib / util / charset / codepoints.c
index 0984164d4838dffd46a2a4d7d596b06eb0cf937c..542eeae73a57789a982b1f759c3d0e20cf6b8ed5 100644 (file)
@@ -319,7 +319,8 @@ smb_iconv_t get_conv_handle(struct smb_iconv_handle *ic,
  */
 _PUBLIC_ codepoint_t next_codepoint_handle_ext(
                        struct smb_iconv_handle *ic,
-                       const char *str, charset_t src_charset,
+                       const char *str, size_t len,
+                       charset_t src_charset,
                        size_t *bytes_consumed)
 {
        /* it cannot occupy more than 4 bytes in UTF16 format */
@@ -339,7 +340,7 @@ _PUBLIC_ codepoint_t next_codepoint_handle_ext(
         * we assume that no multi-byte character can take more than 5 bytes.
         * This is OK as we only support codepoints up to 1M (U+100000)
         */
-       ilen_orig = strnlen(str, 5);
+       ilen_orig = MIN(len, 5);
        ilen = ilen_orig;
 
        descriptor = get_conv_handle(ic, src_charset, CH_UTF16);
@@ -395,9 +396,16 @@ _PUBLIC_ codepoint_t next_codepoint_handle_ext(
   return INVALID_CODEPOINT if the next character cannot be converted
 */
 _PUBLIC_ codepoint_t next_codepoint_handle(struct smb_iconv_handle *ic,
-                                   const char *str, size_t *size)
+                                          const char *str, size_t *size)
 {
-       return next_codepoint_handle_ext(ic, str, CH_UNIX, size);
+       /*
+        * We assume that no multi-byte character can take more than 5 bytes
+        * thus avoiding walking all the way down a long string. This is OK as
+        * Unicode codepoints only go up to (U+10ffff), which can always be
+        * encoded in 4 bytes or less.
+        */
+       return next_codepoint_handle_ext(ic, str, strnlen(str, 5), CH_UNIX,
+                                        size);
 }
 
 /*
@@ -459,11 +467,11 @@ _PUBLIC_ ssize_t push_codepoint_handle(struct smb_iconv_handle *ic,
        return 5 - olen;
 }
 
-_PUBLIC_ codepoint_t next_codepoint_ext(const char *str, charset_t src_charset,
-                                       size_t *size)
+_PUBLIC_ codepoint_t next_codepoint_ext(const char *str, size_t len,
+                                       charset_t src_charset, size_t *size)
 {
-       return next_codepoint_handle_ext(get_iconv_handle(), str,
-                                             src_charset, size);
+       return next_codepoint_handle_ext(get_iconv_handle(), str, len,
+                                        src_charset, size);
 }
 
 _PUBLIC_ codepoint_t next_codepoint(const char *str, size_t *size)