Welcome to the CHICKEN Scheme pasting service

Incomplete attempt at making decoder honor len added by sjamaan on Thu Jul 9 11:22:04 2026

diff --git a/utf.c b/utf.c
index d699ccf1..85c5f4dc 100644
--- a/utf.c
+++ b/utf.c
@@ -3172,7 +3172,7 @@ static const char lengths[] = {
     0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0
 };
 
-static C_char *utf8_decode(C_char *buf, C_u32 *c, int *e)
+static C_char *utf8_decode(C_char *buf, C_u32 *c, int *e, int slen)
 {
     static const int masks[]  = {0x00, 0x7f, 0x1f, 0x0f, 0x07};
     static const uint32_t mins[] = {4194304, 0, 128, 2048, 65536};
@@ -3196,19 +3196,19 @@ static C_char *utf8_decode(C_char *buf, C_u32 *c, int *e)
     /* Assume a four-byte character and load four bytes. Unused bits are
      * 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 (slen > 0) *c  = (C_u32)(s[0] & masks[len]) << 18;
+    if (slen > 1) *c |= (C_u32)(s[1] & 0x3f) << 12;
+    if (slen > 2) *c |= (C_u32)(s[2] & 0x3f) <<  6;
+    if (slen > 3) *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 (slen > 1) *e |= (s[1] & 0xc0) >> 2;
+    if (slen > 2) *e |= (s[2] & 0xc0) >> 4;
+    if (slen > 3) *e |= (s[3]       ) >> 6;
     *e ^= 0x2a; // top two bits of each tail byte correct?
     *e >>= shifte[len];
 
@@ -3263,7 +3263,7 @@ static C_char *utf_index1(C_word s, C_word i)
             return p;
         }
         p1 = p;
-        p = utf8_decode(p, &c, &e);
+        p = utf8_decode(p, &c, &e, (count-index));
         ++index;
         off += p - p1;
     }
@@ -3289,9 +3289,10 @@ static C_char *utf_index(C_word s, C_word i)
 C_regparm C_word C_utf_subchar(C_word s, C_word i)
 {
     C_char *p = utf_index(s, C_unfix(i));
+    C_word len = C_unfix(C_block_item(s, 1));
     int e;
     C_u32 c;
-    utf8_decode(p, &c, &e);
+    utf8_decode(p, &c, &e, len);
     return C_make_character(c);
 }
 
@@ -3504,7 +3507,7 @@ C_regparm int C_utf_count(C_char *s, int len)
     int e;
     C_char *s2;
     while (len > 0) {
-        s2 = utf8_decode(s, &c, &e);
+        s2 = utf8_decode(s, &c, &e, len);
         len -= (s2 - s);
         s = s2;
         i++;
@@ -3523,7 +3526,7 @@ C_regparm C_word C_utf_validate(C_word bv, C_word blen, C_word start, C_word end
     while (len > 0) {
         if(*s >= 0x80 && *s <= 0xbf) return C_SCHEME_FALSE;
         if(lengths[*s >> 3] > len) return C_SCHEME_FALSE;
-        s2 = (unsigned char *)utf8_decode((C_char *)s, &c, &e);
+        s2 = (unsigned char *)utf8_decode((C_char *)s, &c, &e, len);
         if(e) return C_SCHEME_FALSE;
         len -= (s2 - s);
         s = s2;
@@ -3561,7 +3564,8 @@ C_regparm C_word C_utf_decode(C_word bv, C_word pos)
 {
     C_u32 c;
     int e;
-    utf8_decode(C_c_string(bv) + C_unfix(pos), &c, &e);
+    C_word bvlen = C_header_size(bv) - 1;
+    utf8_decode(C_c_string(bv) + C_unfix(pos), &c, &e, bvlen);
     return C_make_character(c);
 }
 

Your annotation:

Enter a new annotation:

Your nick:
The title of your paste:
Your paste (mandatory) :
What's the equality predicate for strings in R5RS?
Visually impaired? Let me spell it for you (wav file) download WAV