home: hub: zuo

Download patch

ref: 1cc4a95509e9b17b4141d9eed6c6a04b525a7d3a
parent: 46745c5e5cf56cc496fe35609ad50d76f9c57235
author: Matthew Flatt <mflatt@racket-lang.org>
date: Sat Jul 23 13:06:41 CDT 2022

Zuo: check for nul characters in `string->symbol`

--- a/tests/symbol.zuo
+++ b/tests/symbol.zuo
@@ -19,3 +19,6 @@
 (check (not (equal? 'apple (string->uninterned-symbol "apple"))))
 (check-arg-fail (string->symbol 'apple) not-string)
 (check-arg-fail (string->uninterned-symbol 'apple) not-string)
+
+(check-arg-fail (string->symbol "apple\0spice") "without a nul character")
+(check (symbol? (string->uninterned-symbol "apple\0spice")))
--- a/zuo-doc/lang-zuo.scrbl
+++ b/zuo-doc/lang-zuo.scrbl
@@ -500,7 +500,9 @@
 )]{
 
 Analogous to @realracket*[symbol? symbol->string string->symbol
-string->uninterned-symbol] from @racketmodname[racket].}
+string->uninterned-symbol] from @racketmodname[racket], but
+@racket[string->symbol] accepts only strings that do not contain the
+null character.}
 
 
 @section{Hash Tables (Persistent Maps)}
--- a/zuo.c
+++ b/zuo.c
@@ -1323,7 +1323,7 @@
 
   first = last = z.o_null;
   while ((left != z.o_null) && (right != z.o_null)) {
-    zuo_t *p;
+    zuo_t *p, *s_left, *s_right;
 
     if (strcmp(ZUO_STRING_PTR(((zuo_symbol_t *)_zuo_car(left))->str),
                ZUO_STRING_PTR(((zuo_symbol_t *)_zuo_car(right))->str))
@@ -2573,8 +2573,28 @@
   return zuo_sized_string((const char *)&((zuo_string_t *)obj)->s[s_idx], e_idx - s_idx);
 }
 
+static int zuo_is_string_without_nul(zuo_t *obj) {
+  zuo_int_t i;
+
+  if ((obj->tag != zuo_string_tag)
+      || ZUO_STRING_LEN(obj) == 0)
+    return 0;
+
+  for (i = ZUO_STRING_LEN(obj); i--; ) {
+    if (((zuo_string_t *)obj)->s[i] == 0)
+      return 0;
+  }
+
+  return 1;
+}
+
 static zuo_t *zuo_string_to_symbol(zuo_t *obj) {
-  check_string("string->symbol", obj);
+  if (!zuo_is_string_without_nul(obj)) {
+    const char *who = "string->symbol";
+    check_string(who, obj);
+    zuo_fail_arg(who, "string without a nul character", obj);
+  }
+
   return zuo_symbol_from_string(ZUO_STRING_PTR(obj), obj);
 }
 
@@ -3577,18 +3597,7 @@
 #endif
 
 static int zuo_is_path_string(zuo_t *obj) {
-  zuo_int_t i;
-
-  if ((obj->tag != zuo_string_tag)
-      || ZUO_STRING_LEN(obj) == 0)
-    return 0;
-
-  for (i = ZUO_STRING_LEN(obj); i--; ) {
-    if (((zuo_string_t *)obj)->s[i] == 0)
-      return 0;
-  }
-
-  return 1;
+  return zuo_is_string_without_nul(obj);
 }
 
 static zuo_t *zuo_path_string_p(zuo_t *obj) {