[PATCH v2 8/8] spi: spidev_test: rewrite unescape() to stay in bounds

From: Jonas Rebmann

Date: Wed Sep 16 2026 - 15:35:39 EST


unescape() could read the source buffer out of bounds for inputs like
"\\x" and could write the destination buffer out of bounds due to lack
of checking against the len parameter.

For better readability and consistency, rewrite it as a simplified
version of unescape_string() in string_helpers.h. This includes
rearranging src and dst parameters.

Signed-off-by: Jonas Rebmann <jre@xxxxxxxxxxxxxx>
---
tools/spi/spidev_test.c | 38 +++++++++++++++++++++-----------------
1 file changed, 21 insertions(+), 17 deletions(-)

diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c
index 93867ebf39a0..a076fb4037e3 100644
--- a/tools/spi/spidev_test.c
+++ b/tools/spi/spidev_test.c
@@ -13,6 +13,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include <errno.h>
#include <getopt.h>
#include <fcntl.h>
@@ -97,28 +98,31 @@ static void hex_dump(const void *src, size_t length, size_t line_size,
* Unescape - process hexadecimal escape character
* converts shell input "\x23" -> 0x23
*/
-static int unescape(char *_dst, char *_src, size_t len)
+static int unescape(char *src, char *dst, size_t size)
{
- int ret = 0;
- int match;
- char *src = _src;
- char *dst = _dst;
+ char *out = dst;
unsigned int ch;

- while (*src) {
- if (*src == '\\' && *(src+1) == 'x') {
- match = sscanf(src + 2, "%2x", &ch);
- if (!match)
- pabort("malformed input string");
+ while (*src && size--) {
+ if (src[0] == '\\' && src[1] != '\0') {
+ src++;
+
+ if (src[0] == 'x' &&
+ isxdigit((unsigned char)src[1]) &&
+ isxdigit((unsigned char)src[2]) &&
+ sscanf(&src[1], "%2x", &ch)) {
+ *out++ = (unsigned char)ch;
+ src += 3;
+ continue;
+ }

- src += 4;
- *dst++ = (unsigned char)ch;
- } else {
- *dst++ = *src++;
+ *out++ = '\\';
+ if (!size--)
+ break;
}
- ret++;
+ *out++ = *src++;
}
- return ret;
+ return out - dst;
}

static void transfer(int fd, uint8_t const * const tx, uint8_t const * const rx, size_t len)
@@ -421,7 +425,7 @@ static void transfer_escaped_string(int fd, char *str)
if (!rx)
pabort("can't allocate rx buffer");

- size = unescape((char *)tx, str, size);
+ size = unescape(str, (char *)tx, size);
transfer(fd, tx, rx, size);
free(rx);
free(tx);

--
2.56.0.rc0.108.gf0ef1b96a0