summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md2
-rw-r--r--include/stdio.h42
-rw-r--r--tests/Makefile8
-rw-r--r--tests/test_asprintf.c20
-rw-r--r--tests/test_vasprintf.c36
5 files changed, 105 insertions, 3 deletions
diff --git a/README.md b/README.md
index 9b9a956..f47df41 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,7 @@ At this point, the program will safely crash.
59 59
60- `FD_CLR` 60- `FD_CLR`
61- `FD_SET` 61- `FD_SET`
62- `asprintf`
62- `bcopy` 63- `bcopy`
63- `bzero` 64- `bzero`
64- `calloc` 65- `calloc`
@@ -121,6 +122,7 @@ At this point, the program will safely crash.
121- `umask` 122- `umask`
122- `vfprintf` 123- `vfprintf`
123- `vprintf` 124- `vprintf`
125- `vasprintf`
124- `vsnprintf` 126- `vsnprintf`
125- `vsprintf` 127- `vsprintf`
126- `wcrtomb` 128- `wcrtomb`
diff --git a/include/stdio.h b/include/stdio.h
index c6817fa..abdef6c 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -220,6 +220,26 @@ _FORTIFY_FN(vprintf) int vprintf(const char *__f, __builtin_va_list __v)
220 return __orig_vprintf(__f, __v); 220 return __orig_vprintf(__f, __v);
221#endif 221#endif
222} 222}
223
224#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
225#undef vasprintf
226#if __has_builtin(__builtin_vasprintf)
227__diagnose_as_builtin(__builtin_vasprintf, 1, 2, 3)
228#endif
229_FORTIFY_FN(vasprintf) int vasprintf(char **restrict strp, const char *restrict fmt, __builtin_va_list ap)
230{
231#if __has_builtin(__builtin___vasprintf_chk) && USE_NATIVE_CHK
232 return __builtin___vasprintf_chk(_FORTIFY_SOURCE, strp, fmt, ap);
233#else
234 int ret = __orig_vasprintf(strp, fmt, ap);
235 if (ret < 0)
236 *strp = NULL;
237 return ret;
238#endif
239}
240
241
242#endif // defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
223#endif // __clang__ 243#endif // __clang__
224 244
225 245
@@ -312,6 +332,28 @@ _FORTIFY_FN(fprintf) int fprintf(FILE *__s, const char *__f, ...)
312#endif 332#endif
313} 333}
314 334
335#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
336#ifndef __clang__
337#undef asprintf
338__fh_access(read_only, 2)
339__fh_format(printf, 2, 0)
340#if __has_builtin(__builtin_asprintf)
341__diagnose_as_builtin(__builtin_asprintf, 2, 3)
342#endif
343_FORTIFY_FN(asprintf) int asprintf(char **restrict strp, const char *restrict fmt, ...)
344{
345#if __has_builtin(__builtin___asprintf_chk) && USE_NATIVE_CHK
346 return __builtin___asprintf_chk(_FORTIFY_SOURCE, strp, fmt, __builtin_va_arg_pack());
347#else
348 int ret = __orig_asprintf(strp, fmt, __builtin_va_arg_pack());
349 if (ret<0)
350 *strp = NULL;
351 return ret;
352#endif
353}
354#endif // __clang__
355#endif
356
315#pragma GCC diagnostic pop 357#pragma GCC diagnostic pop
316#endif /* __has_builtin(__builtin_va_arg_pack) */ 358#endif /* __has_builtin(__builtin_va_arg_pack) */
317 359
diff --git a/tests/Makefile b/tests/Makefile
index c18898e..32b17b0 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,4 +1,4 @@
1CFLAGS+=-I../include/ -D_FORTIFY_SOURCE=3 -static -O2 -DPEDANTIC_CHECKS 1CFLAGS+=-I../include/ -D_FORTIFY_SOURCE=3 -static -O2 -DPEDANTIC_CHECKS -Wno-format
2 2
3COMPTIME_TARGETS= \ 3COMPTIME_TARGETS= \
4 test_memcpy_overwrite_under \ 4 test_memcpy_overwrite_under \
@@ -12,6 +12,7 @@ RUNTIME_TARGETS= \
12 test_FD_SET_negative \ 12 test_FD_SET_negative \
13 test_FD_ISSET_SETSIZE \ 13 test_FD_ISSET_SETSIZE \
14 test_FD_ISSET_negative \ 14 test_FD_ISSET_negative \
15 test_asprintf \
15 test_bcopy_dynamic_read \ 16 test_bcopy_dynamic_read \
16 test_bcopy_dynamic_write \ 17 test_bcopy_dynamic_write \
17 test_bcopy_static_read \ 18 test_bcopy_static_read \
@@ -126,11 +127,12 @@ RUNTIME_TARGETS= \
126 test_ttyname_r_dynamic \ 127 test_ttyname_r_dynamic \
127 test_ttyname_r_static \ 128 test_ttyname_r_static \
128 test_umask \ 129 test_umask \
130 test_vasprintf \
131 test_vfprintf \
132 test_vprintf \
129 test_vsnprintf_dynamic \ 133 test_vsnprintf_dynamic \
130 test_vsnprintf_static \ 134 test_vsnprintf_static \
131 test_vsprintf \ 135 test_vsprintf \
132 test_vfprintf \
133 test_vprintf \
134 test_wcscat_static_write \ 136 test_wcscat_static_write \
135 test_wcscpy_static_write \ 137 test_wcscpy_static_write \
136 test_wcsncat_static_write \ 138 test_wcsncat_static_write \
diff --git a/tests/test_asprintf.c b/tests/test_asprintf.c
new file mode 100644
index 0000000..a02d110
--- /dev/null
+++ b/tests/test_asprintf.c
@@ -0,0 +1,20 @@
1#define _GNU_SOURCE
2#include "common.h"
3
4#include <assert.h>
5#include <stdio.h>
6#include <stdlib.h>
7
8int main(int argc, char** argv) {
9 char* buf;
10 asprintf(&buf, "total: %d+%d=%d", 1, 2, 3);
11 puts(buf);
12 free(buf);
13
14#ifndef __clang__
15 asprintf(&buf, "total: %", 1);
16 assert(buf == NULL);
17#endif
18
19 return 0;
20}
diff --git a/tests/test_vasprintf.c b/tests/test_vasprintf.c
new file mode 100644
index 0000000..2f71714
--- /dev/null
+++ b/tests/test_vasprintf.c
@@ -0,0 +1,36 @@
1#define _GNU_SOURCE
2#include "common.h"
3
4#include <assert.h>
5#include <stdarg.h>
6#include <stdio.h>
7#include <stdlib.h>
8
9void test(const char *fmt, ...)
10{
11 char* buf;
12 va_list args;
13 va_start(args, fmt);
14 vasprintf(&buf, fmt, args);
15 va_end(args);
16 puts(buf);
17 free(buf);
18}
19
20void test2(const char *fmt, ...)
21{
22 char* buf;
23 va_list args;
24 va_start(args, fmt);
25 vasprintf(&buf, fmt, args);
26 va_end(args);
27 assert(buf == NULL);
28}
29
30int main(int argc, char** argv) {
31 test("Total: %d+%d=%d", 1, 2, 3);
32#ifndef __clang__
33 test2("Total: %", 1, 2, 3);
34#endif
35 return 0;
36}