erlang: fix string literal in a binary — <<"abc">> emitted one null byte

er-eval-binary-segment evaluated a string-valued segment (the parser
represents <<"abc">> as one integer segment whose value is the whole string
"abc") by calling er-emit-int! on the string, emitting a single bogus 0
byte. So every <<"...">> literal became {:tag "binary" :bytes (0)} — which
made binary =:= read as "always equal" and crypto:hash input-independent.
Fix: the integer branch now expands a string value to one byte per
character (Erlang semantics: <<"abc">> ≡ <<97,98,99>>). Verified:
byte_size(<<"abc">>)=3, <<"a">> =:= <<"b">> is false, crypto:hash distinct
per input.

(User-authorized cross-scope fix from the identity loop; loops/erlang
should adopt this as the owner of lib/erlang.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-07 14:12:10 +00:00
parent db76cc8c65
commit 92f60d4b8d

View File

@@ -1485,9 +1485,15 @@
(size (er-eval-binary-size (get seg :size) env)))
(cond
(= spec "integer")
(let
((bits (if (= size nil) 8 size)))
(er-emit-int! out val bits))
(cond
(= (type-of val) "string")
(for-each
(fn (c) (er-emit-int! out (char->integer c) 8))
(string->list val))
:else
(let
((bits (if (= size nil) 8 size)))
(er-emit-int! out val bits)))
(= spec "binary")
(cond
(er-binary? val)