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. - `FD_CLR` - `FD_SET` +- `asprintf` - `bcopy` - `bzero` - `calloc` @@ -121,6 +122,7 @@ At this point, the program will safely crash. - `umask` - `vfprintf` - `vprintf` +- `vasprintf` - `vsnprintf` - `vsprintf` - `wcrtomb` diff --git a/include/stdio.h b/include/stdio.h index c6817fa..e1e8da2 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) return __orig_vprintf(__f, __v); #endif } + +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#if __has_builtin(__builtin_vasprintf) +__diagnose_as_builtin(__builtin_vasprintf, 1, 2, 3) +#endif +_FORTIFY_FN(vasprintf) int vasprintf(char **restrict strp, const char *restrict fmt, __builtin_va_list ap) +{ +#if __has_builtin(__builtin___vasprintf_chk) && USE_NATIVE_CHK + return __builtin___vasprintf_chk(_FORTIFY_SOURCE, strp, fmt, ap); +#else + int ret = __orig_vasprintf(strp, fmt, ap); + if (ret < 0) + *strp = NULL; + return ret; +#endif +} + + +#endif // defined(_GNU_SOURCE) || defined(_BSD_SOURCE) + // #endif // __clang__ @@ -312,6 +332,26 @@ _FORTIFY_FN(fprintf) int fprintf(FILE *__s, const char *__f, ...) #endif } +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) +#undef asprintf +__fh_access(read_only, 2) +__fh_format(printf, 2, 0) +#if __has_builtin(__builtin_asprintf) +__diagnose_as_builtin(__builtin_asprintf, 2, 3) +#endif +_FORTIFY_FN(asprintf) int asprintf(char **restrict strp, const char *restrict fmt, ...) +{ +#if __has_builtin(__builtin___asprintf_chk) && USE_NATIVE_CHK + return __builtin___asprintf_chk(_FORTIFY_SOURCE, strp, fmt, __builtin_va_arg_pack()); +#else + int ret = __orig_asprintf(strp, fmt, __builtin_va_arg_pack()); + if (ret<0) + *strp = NULL; + return ret; +#endif +} +#endif + #pragma GCC diagnostic pop #endif /* __has_builtin(__builtin_va_arg_pack) */ diff --git a/tests/Makefile b/tests/Makefile index c18898e..32b17b0 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -1,4 +1,4 @@ -CFLAGS+=-I../include/ -D_FORTIFY_SOURCE=3 -static -O2 -DPEDANTIC_CHECKS +CFLAGS+=-I../include/ -D_FORTIFY_SOURCE=3 -static -O2 -DPEDANTIC_CHECKS -Wno-format COMPTIME_TARGETS= \ test_memcpy_overwrite_under \ @@ -12,6 +12,7 @@ RUNTIME_TARGETS= \ test_FD_SET_negative \ test_FD_ISSET_SETSIZE \ test_FD_ISSET_negative \ + test_asprintf \ test_bcopy_dynamic_read \ test_bcopy_dynamic_write \ test_bcopy_static_read \ @@ -126,11 +127,12 @@ RUNTIME_TARGETS= \ test_ttyname_r_dynamic \ test_ttyname_r_static \ test_umask \ + test_vasprintf \ + test_vfprintf \ + test_vprintf \ test_vsnprintf_dynamic \ test_vsnprintf_static \ test_vsprintf \ - test_vfprintf \ - test_vprintf \ test_wcscat_static_write \ test_wcscpy_static_write \ 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 @@ +#define _GNU_SOURCE +#include "common.h" + +#include +#include +#include + +int main(int argc, char** argv) { + char* buf; + asprintf(&buf, "total: %d+%d=%d", 1, 2, 3); + puts(buf); + free(buf); + +#ifndef __clang__ + asprintf(&buf, "total: %", 1); + assert(buf == NULL); +#endif + + return 0; +} 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 @@ +#define _GNU_SOURCE +#include "common.h" + +#include +#include +#include +#include + +void test(const char *fmt, ...) +{ + char* buf; + va_list args; + va_start(args, fmt); + vasprintf(&buf, fmt, args); + va_end(args); + puts(buf); + free(buf); +} + +void test2(const char *fmt, ...) +{ + char* buf; + va_list args; + va_start(args, fmt); + vasprintf(&buf, fmt, args); + va_end(args); + assert(buf == NULL); +} + +int main(int argc, char** argv) { + test("Total: %d+%d=%d", 1, 2, 3); +#ifndef __clang__ + test2("Total: %", 1, 2, 3); +#endif + return 0; +}