Dumb workaround for reading past end of string added by sjamaan on Thu Jul 9 14:55:31 2026
diff --git a/utf.c b/utf.c index d699ccf1..19e4be51 100644 --- a/utf.c +++ b/utf.c @@ -3197,18 +3197,30 @@ static C_char *utf8_decode(C_char *buf, C_u32 *c, int *e) * shifted out. */ *c = (C_u32)(s[0] & masks[len]) << 18; - *c |= (C_u32)(s[1] & 0x3f) << 12; - *c |= (C_u32)(s[2] & 0x3f) << 6; - *c |= (C_u32)(s[3] & 0x3f) << 0; + if (s[0] != '\0') { + *c |= (C_u32)(s[1] & 0x3f) << 12; + if (s[1] != '\0') { + *c |= (C_u32)(s[2] & 0x3f) << 6; + if (s[2] != '\0') { + *c |= (C_u32)(s[3] & 0x3f) << 0; + } + } + } *c >>= shiftc[len]; /* Accumulate the various error conditions. */ *e = (*c < mins[len]) << 6; // non-canonical encoding *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half? *e |= (*c > 0x10FFFF) << 8; // out of range? - *e |= (s[1] & 0xc0) >> 2; - *e |= (s[2] & 0xc0) >> 4; - *e |= (s[3] ) >> 6; + if (s[0] != '\0') { + *e |= (s[1] & 0xc0) >> 2; + if (s[1] != '\0') { + *e |= (s[2] & 0xc0) >> 4; + if (s[2] != '\0') { + *e |= (s[3] ) >> 6; + } + } + } *e ^= 0x2a; // top two bits of each tail byte correct? *e >>= shifte[len];