]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - utf8lib.c
fix wrong array sizes in MODE_WATER in softrast causing an overrun
[xonotic/darkplaces.git] / utf8lib.c
index 3a2fabe79da7fb6dd4542dad468a1fa9512180f4..bb775b7fd91b749a4593382f52691135c58f4250 100644 (file)
--- a/utf8lib.c
+++ b/utf8lib.c
@@ -682,7 +682,7 @@ u8_COM_StringLengthNoColors(const char *_s, size_t size_s, qboolean *valid)
        const unsigned char *s = (const unsigned char*)_s;
        const unsigned char *end;
        size_t len = 0;
-       size_t bits = 0;
+       size_t st, ln;
 
        if (!utf8_enable.integer)
                return COM_StringLengthNoColors(_s, size_s, valid);
@@ -728,23 +728,46 @@ u8_COM_StringLengthNoColors(const char *_s, size_t size_s, qboolean *valid)
                                                ++len; // the character
                                                break;
                                }
-                               break;
+                               ++s;
+                               continue;
                        default:
-                               ++len;
                                break;
                }
 
-               // start of a wide character
-               bits = utf8_lengths[*s];
-               if (bits >= 2)
+               // ascii char, skip u8_analyze
+               if (*s < 0x80)
+               {
+                       ++len;
+                       ++s;
+                       continue;
+               }
+
+               // invalid, skip u8_analyze
+               if (*s < 0xC2)
                {
-                       for (++s; bits >= 1 && *s >= 0x80 && *s < 0xC0; ++s, --bits);
+                       ++s;
                        continue;
                }
-               // part of a wide character or invalid character, we ignore that one
-               if (bits == 0)
-                       --len;
-               ++s;
+
+               if (!u8_analyze((const char*)s, &st, &ln, NULL, U8_ANALYZE_INFINITY))
+               {
+                       // we CAN end up here, if an invalid char is between this one and the end of the string
+                       if(valid)
+                               *valid = TRUE;
+                       return len;
+               }
+
+               if(end && s + st + ln > end)
+               {
+                       // string length exceeded by new character
+                       if(valid)
+                               *valid = TRUE;
+                       return len;
+               }
+
+               // valid character, skip after it
+               s += st + ln;
+               ++len;
        }
        // never get here
 }