Commit 55c21025 authored by Richard Hansen's avatar Richard Hansen Committed by Eli Zaretskii
Browse files

bindat (strz): Null terminate fixed-length strings if there is room

* lisp/emacs-lisp/bindat.el (bindat--pack-strz): For fixed-length strz
fields, explicitly write a null terminator after the packed string if
there is room (bug#56048).
* doc/lispref/processes.texi (Bindat Types): Update documentation.
* test/lisp/emacs-lisp/bindat-tests.el (bindat-test--str-strz-prealloc):
Update tests.
parent eff42dc0
Pipeline #18729 passed with stages
in 35 minutes and 38 seconds
......@@ -3509,23 +3509,24 @@ packed; other multibyte strings signal an error. When unpacking a
(but excluding) the null byte that terminated the input string.
If @var{len} is provided, @code{strz} behaves the same as @code{str},
but with one difference: when unpacking, the first null byte
encountered in the packed string is interpreted as the terminating
byte, and it and all subsequent bytes are excluded from the result of
the unpacking.
but with a couple of differences:
@quotation Caution
The packed output will not be null-terminated unless one of the
following is true:
@itemize
@itemize @bullet
@item
The input string is shorter than @var{len} bytes and either no pre-allocated
string was provided to @code{bindat-pack} or the appropriate byte in
the pre-allocated string was already null.
When packing, a null terminator is written after the packed input
string if the number of characters in the input string is less than
@var{len}.
@item
The input string contains a null byte within the first @var{len}
bytes.
When unpacking, the first null byte encountered in the packed string
is interpreted as the terminating byte, and it and all subsequent
bytes are excluded from the result of the unpacking.
@end itemize
@quotation Caution
The packed output will not be null-terminated unless the input string
is shorter than @var{len} bytes or it contains a null byte within the
first @var{len} bytes.
@end quotation
@item vec @var{len} [@var{type}]
......
......@@ -443,11 +443,14 @@ e.g. corresponding to STRUCT.FIELD1[INDEX2].FIELD3..."
(defun bindat--pack-strz (len v)
(let* ((v (string-to-unibyte v))
(vlen (length v)))
;; Explicitly write a null terminator (if there's room) in case
;; the user provided a pre-allocated string to `bindat-pack' that
;; wasn't already zeroed.
(when (or (null len) (< vlen len))
(aset bindat-raw (+ bindat-idx vlen) 0))
(if len
;; When len is specified, behave the same as the str type
;; since we don't actually add the terminating zero anyway
;; (because we rely on the fact that `bindat-raw' was
;; presumably initialized with all-zeroes before we started).
;; (except for the null terminator possibly written above).
(bindat--pack-str len v)
(dotimes (i vlen)
(when (= (aref v i) 0)
......@@ -456,10 +459,6 @@ 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 already
;; zeroed.
(aset bindat-raw (+ bindat-idx vlen) 0)
(setq bindat-idx (+ bindat-idx vlen 1)))))
(defun bindat--pack-bits (len v)
......
......@@ -172,14 +172,14 @@
((((x str 2)) ((x . "a"))) . "ax")
((((x str 2)) ((x . "ab"))) . "ab")
((((x str 2)) ((x . "abc"))) . "ab")
((,(bindat-type strz 1) "") . "xx")
((,(bindat-type strz 2) "") . "xx")
((,(bindat-type strz 2) "a") . "ax")
((,(bindat-type strz 1) "") . "\0x")
((,(bindat-type strz 2) "") . "\0x")
((,(bindat-type strz 2) "a") . "a\0")
((,(bindat-type strz 2) "ab") . "ab")
((,(bindat-type strz 2) "abc") . "ab")
((((x strz 1)) ((x . ""))) . "xx")
((((x strz 2)) ((x . ""))) . "xx")
((((x strz 2)) ((x . "a"))) . "ax")
((((x strz 1)) ((x . ""))) . "\0x")
((((x strz 2)) ((x . ""))) . "\0x")
((((x strz 2)) ((x . "a"))) . "a\0")
((((x strz 2)) ((x . "ab"))) . "ab")
((((x strz 2)) ((x . "abc"))) . "ab")
((,(bindat-type strz) "") . "\0x")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment