The argument vector's malloc was unchecked, and a failure there would have published a null pointer with a length beside it. It now dies naming what it was building, because argv has no allocation site for a condition to hang on. flan_slurp_into read a capacity of elements as a capacity of bytes and skipped the epoch check every other container operation runs. The element size is now a parameter and the length it publishes counts whole elements, so the day slurp answers something other than (Vec u8) it does not answer with bytes nobody wrote. A string with a NUL in it is refused at the C boundary, which is the policy flan_path_cstr has always had for a path: C reads to the first NUL, so what crosses is a prefix of what was passed, and a window title is no different from a filename in that respect. The refusal names the declare-c, which is the name the program's author wrote. The runtime's two translation units are compiled with -Wall -Wextra. They were already clean under both; the flag is there so the next one is caught rather than read. The generation word keeps its place and loses its "yet": a reader for it is a third word on every slice in the language, which is a spec amendment rather than a runtime patch, and the comment now says so where someone deciding to trust the word would read it.
29 lines
1.3 KiB
Plaintext
29 lines
1.3 KiB
Plaintext
;;;; A string with a NUL in it, handed to C.
|
|
;;;;
|
|
;;;; A Flan string is ptr+len and a C string ends at its first NUL, so the two
|
|
;;;; disagree about what the value *is* the moment one of those bytes is in the
|
|
;;;; middle. The generated shim copies and terminates — string-of-bytes.flan
|
|
;;;; pins that — and a copy of these bytes is a C string of length 1 where the
|
|
;;;; program passed 5. The function would then act on a value nobody wrote.
|
|
;;;;
|
|
;;;; flan_path_cstr has always refused this for a path, on the grounds that the
|
|
;;;; file opened would not be the file named. Nothing about a path is special:
|
|
;;;; the same reasoning covers a window title, a shader name and a query, so
|
|
;;;; the shim refuses it too, naming the declare-c that was called. It is a
|
|
;;;; trap rather than a condition because a foreign call has no allocation site
|
|
;;;; for the compiler to guard and no transfer channel of its own.
|
|
(declare-c c-puts [s string] i32 "puts")
|
|
|
|
(defn main [] i32
|
|
(let [v (vec-new u8)]
|
|
(push v 104) ; h
|
|
(push v 105) ; i
|
|
(push v 0)
|
|
(push v 104) ; h
|
|
(push v 105) ; i
|
|
(println "before")
|
|
(c-puts (string (as-slice v)))
|
|
(println "unreachable")
|
|
(free v))
|
|
0)
|