bindat (strz): Write null terminator after variable length string

* lisp/emacs-lisp/bindat.el (bindat--pack-strz): Explicitly write a
null byte after packing a variable-length string to ensure proper
termination when packing to a pre-allocated string.
* doc/lispref/processes.texi (Bindat Types): Update documentation.
* test/lisp/emacs-lisp/bindat-tests.el (bindat-test--str-strz-prealloc):
Update tests.
This commit is contained in:
Richard Hansen 2022-06-09 20:41:50 -04:00 committed by Eli Zaretskii
parent dcee64d4bf
commit 6c3b6149d9
3 changed files with 9 additions and 15 deletions

View file

@ -3495,24 +3495,15 @@ output.
@item strz &optional @var{len}
If @var{len} is not provided: Variable-length null-terminated unibyte
string (@pxref{Text Representations}). When packing, the entire input
string is copied to the packed output. The following byte will be
null (zero) unless a pre-allocated string was provided to
@code{bindat-pack}, in which case that byte is left unmodified. The
length of the packed output is the length of the input string plus one
(for the null terminator). The input string must not contain any null
bytes. If the input string is multibyte with only ASCII and
string is copied to the packed output followed by a null (zero) byte.
The length of the packed output is the length of the input string plus
one (for the null terminator). The input string must not contain any
null bytes. If the input string is multibyte with only ASCII and
@code{eight-bit} characters, it is converted to unibyte before it is
packed; other multibyte strings signal an error. When unpacking, the
resulting string contains all bytes up to (but excluding) the null
byte.
@quotation Caution
If a pre-allocated string is provided to @code{bindat-pack}, the
packed output will not be properly null-terminated unless the
pre-allocated string already has a null byte at the appropriate
location.
@end quotation
If @var{len} is provided: @code{strz} behaves the same as @code{str}
with one difference: When unpacking, the first null byte encountered
in the packed string and all subsequent bytes are excluded from the

View file

@ -450,6 +450,9 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
;; need to scan the input string looking for a null byte.
(error "Null byte encountered in input strz string"))
(aset bindat-raw (+ bindat-idx i) (aref v i)))
;; Explicitly write a null terminator in case the user provided a
;; pre-allocated string to bindat-pack that wasn't zeroed first.
(aset bindat-raw (+ bindat-idx len) 0)
(setq bindat-idx (+ bindat-idx len 1))))
(defun bindat--pack-bits (len v)

View file

@ -182,8 +182,8 @@
((((x strz 2)) ((x . "a"))) . "ax")
((((x strz 2)) ((x . "ab"))) . "ab")
((((x strz 2)) ((x . "abc"))) . "ab")
((,(bindat-type strz) "") . "xx")
((,(bindat-type strz) "a") . "ax")))
((,(bindat-type strz) "") . "\0x")
((,(bindat-type strz) "a") . "a\0")))
(let ((prealloc (make-string 2 ?x)))
(apply #'bindat-pack (append (car tc) (list prealloc)))
(should (equal prealloc (cdr tc))))))