Skip to content

Commit 08c8d08

Browse files
authored
Merge pull request #226 from Zondax/fix/scanbuild-clang21-array-bounds
fix: silence clang-21 ArrayBound findings (+ real utf8ncpy OOB)
2 parents 8b5e197 + 137ae1d commit 08c8d08

4 files changed

Lines changed: 22 additions & 7 deletions

File tree

include/utf8.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -625,12 +625,17 @@ utf8_int8_t *utf8ncpy(utf8_int8_t *utf8_restrict dst, const utf8_int8_t *utf8_re
625625
}
626626
}
627627

628-
for (check_index = index - 1; check_index > 0 && 0x80 == (0xc0 & d[check_index]); check_index--) {
629-
/* just moving the index */
630-
}
628+
/* index == 0 means an empty string was copied; skip the back-scan so that
629+
* `index - 1` does not underflow (index/check_index are unsigned size_t) and
630+
* read out of bounds at d[SIZE_MAX]. */
631+
if (index > 0) {
632+
for (check_index = index - 1; check_index > 0 && 0x80 == (0xc0 & d[check_index]); check_index--) {
633+
/* just moving the index */
634+
}
631635

632-
if (check_index < index && (index - check_index) < utf8codepointsize(d[check_index])) {
633-
index = check_index;
636+
if (check_index < index && (index - check_index) < utf8codepointsize(d[check_index])) {
637+
index = check_index;
638+
}
634639
}
635640

636641
/* append null terminating byte */

include/zxversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717

1818
#define ZXLIB_MAJOR 47
1919
#define ZXLIB_MINOR 0
20-
#define ZXLIB_PATCH 0
20+
#define ZXLIB_PATCH 1

src/base58.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ int decode_base58(const char *in, size_t length, unsigned char *out, size_t *out
7676
if (tmp[startAt] == 0) {
7777
++startAt;
7878
}
79+
// Base58 output never has more digits than the input, so j (starting at
80+
// length) cannot reach 0 here. The explicit guard proves that bound to the
81+
// static analyzer and avoids an unsigned underflow of j on any future change.
82+
if (j == 0) {
83+
break;
84+
}
7985
buffer[--j] = (unsigned char)remainder;
8086
}
8187
while ((j < length) && (buffer[j] == 0)) {

src/zxcanary.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
#include "zxmacros.h"
2222

2323
// This symbol is defined by the link script to be at the start of the stack area.
24+
// The dynamic canary lives in the word immediately after it, which is a deliberate
25+
// out-of-object access. Compute the address through uintptr_t (not pointer arithmetic
26+
// on &app_stack_canary) so the static analyzer does not flag it as an array-bounds
27+
// violation; the generated access is identical.
2428
extern unsigned int app_stack_canary;
25-
#define ZONDAX_CANARY (*((volatile uint32_t *)(((uint8_t *)&app_stack_canary) + sizeof(uint32_t))))
29+
#define ZONDAX_CANARY (*((volatile uint32_t *)((uintptr_t)&app_stack_canary + sizeof(uint32_t))))
2630

2731
#if defined(HAVE_ZONDAX_CANARY)
2832
#include "errors.h"

0 commit comments

Comments
 (0)