sys/string_utils: add string_writer helper#20843
Conversation
|
That API indeed disarms the usual footguns :) I wonder if there is some BSD / whatever API already that we could steal? |
815f30d to
b2b49d3
Compare
b2b49d3 to
e52ffe9
Compare
Teufelchen1
left a comment
There was a problem hiding this comment.
All in all looks good. Some nits, some ideas.
You mentioned that this is often done manually in RIOT, could you also replace such instances with this helper right away?
|
Squash & Ci? |
6eea402 to
62e0d3f
Compare
ce88749 to
0fe3ac4
Compare
sys/include/string_utils.h
Outdated
| * @return number of bytes written on success | ||
| * -E2BIG if the string was truncated | ||
| */ | ||
| int swprintf(string_writer_t *sw, const char *restrict format, ...); |
There was a problem hiding this comment.
you can add
__attribute__ ((format (printf, 2, 3)))to enable static printf-like compiler checks for the format string and arguments, see https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html.
There was a problem hiding this comment.
GCC doesn't like it if the variable args are empty
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c: In function ‘test_libc_swprintf’:
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:42:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "Hello World!");
^~~
There was a problem hiding this comment.
Odd, I tried now and works for me:
__attribute__ ((format (printf, 2, 3)))
int __swprintf(string_writer_t *sw, FLASH_ATTR const char *restrict format, ...);Then:
res = swprintf(&sw, "Hello World!");works just fine, while:
res = swprintf(&sw, "Hello World%s!");results in
/home/[email protected]/proj/RIOT/tests/unittests/tests-libc/tests-libc.c: In function ‘test_libc_s
wprintf’:
/home/[email protected]/proj/RIOT/tests/unittests/tests-libc/tests-libc.c:42:38: error: format ‘%s’
expects a matching ‘char *’ argument [-Werror=format=]
42 | res = swprintf(&sw, "Hello World%s!");
| ~^
| |
| char *
Which compiler version are you using? Mine:
$ arm-none-eabi-gcc --version
arm-none-eabi-gcc (15:10.3-2021.07-4) 10.3.1 20210621 (release)
There was a problem hiding this comment.
This is only happens with avr-gcc (GCC) 7.3.0
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c: In function ‘test_libc_swprintf’:
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:42:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "Hello World!");
^~~
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:49:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "0123456789");
^~~
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:54:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "01234567891");
^~~
/home/benpicco/dev/RIOT/tests/unittests/tests-libc/tests-libc.c:59:5: error: format not a string literal and no format arguments [-Werror=format-security]
res = swprintf(&sw, "###");
^~~
There was a problem hiding this comment.
Ah I think it's because the TO_FLASH() is interfering
096f71f to
2041c82
Compare
2041c82 to
2bf4c71
Compare
9623e4f to
40b1188
Compare
40b1188 to
db6196e
Compare
Contribution description
Assembling a string through multiple writes if often open-coded like this
This is error prone (the above example foregoes any error handling) and ugly.
This introduces a small helper function to achieve the same in a much more convenient fasion:
Testing procedure
A new unit test has been added.
Issues/PRs references