diff --git a/package/system/apk/patches/0003-io-fix-undefined-behaviour-in-apk_istream_get_delim.patch b/package/system/apk/patches/0003-io-fix-undefined-behaviour-in-apk_istream_get_delim.patch new file mode 100644 index 00000000000..d32dd2541f7 --- /dev/null +++ b/package/system/apk/patches/0003-io-fix-undefined-behaviour-in-apk_istream_get_delim.patch @@ -0,0 +1,67 @@ +From 55ab583de9a35ea79d63b8058a131ef260d407a9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Timo=20Ter=C3=A4s?= +Date: Mon, 21 Apr 2025 12:22:04 +0300 +Subject: [PATCH] io: fix undefined behaviour in apk_istream_get_delim + +Arithmetics on null pointer are undefined, so leave is->ptr +pointing to is->buf always. Rewrite the function to be +a bit more readable. + +ref #11064, #11105 +--- + src/io.c | 38 +++++++++++++++++++++----------------- + 1 file changed, 21 insertions(+), 17 deletions(-) + +--- a/src/io.c ++++ b/src/io.c +@@ -191,29 +191,33 @@ int apk_istream_get_max(struct apk_istre + + int apk_istream_get_delim(struct apk_istream *is, apk_blob_t token, apk_blob_t *data) + { +- apk_blob_t ret = APK_BLOB_NULL, left = APK_BLOB_NULL; +- int r = 0; ++ int r; ++ ++ if (is->err && is->ptr == is->end) { ++ *data = APK_BLOB_NULL; ++ return is->err < 0 ? is->err : -APKE_EOF; ++ } + + do { +- if (apk_blob_split(APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr), token, &ret, &left)) +- break; ++ apk_blob_t left; ++ if (apk_blob_split(APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr), token, data, &left)) { ++ is->ptr = (uint8_t*)left.ptr; ++ is->end = (uint8_t*)left.ptr + left.len; ++ return 0; ++ } + r = __apk_istream_fill(is); + } while (r == 0); + +- /* Last segment before end-of-file. Return also zero length non-null +- * blob if eof comes immediately after the delimiter. */ +- if (is->ptr && r > 0) +- ret = APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr); +- +- if (!APK_BLOB_IS_NULL(ret)) { +- is->ptr = (uint8_t*)left.ptr; +- is->end = (uint8_t*)left.ptr + left.len; +- *data = ret; +- return 0; ++ if (r < 0) { ++ *data = APK_BLOB_NULL; ++ return apk_istream_error(is, r); + } +- if (r < 0) apk_istream_error(is, r); +- *data = APK_BLOB_NULL; +- return r < 0 ? r : -APKE_EOF; ++ ++ /* EOF received. Return the last buffered data or an empty ++ * blob if EOF came directly after last separator. */ ++ *data = APK_BLOB_PTR_LEN((char*)is->ptr, is->end - is->ptr); ++ is->ptr = is->end = is->buf; ++ return 0; + } + + static void blob_get_meta(struct apk_istream *is, struct apk_file_meta *meta)