commit b5d5cebc2b4218ca2c04c52546849df7625a53a0
parent 9064a508d5f1ed3514d3e5b4734576e80f7048ae
Author: jvoisin <julien.voisin@dustri.org>
Date: Wed, 6 Dec 2023 21:45:57 +0100
Add qsort
Diffstat:
4 files changed, 71 insertions(+), 0 deletions(-)
diff --git a/include/stdlib.h b/include/stdlib.h
@@ -37,6 +37,23 @@ __extension__
extern "C" {
#endif
+#undef qsort
+#if __has_builtin(__builtin_qsort)
+__diagnose_as_builtin(__builtin_qsort, 1, 2, 3, 4)
+#endif
+__access(read_write, 1)
+_FORTIFY_FN(qsort) void qsort(void * _FORTIFY_POS0 base, size_t nmemb, size_t size,
+ int (*compar)(const void *, const void *))
+{
+ size_t __b = __bos(base, 0);
+
+ if (__bmo(nmemb, size))
+ __builtin_trap();
+ if (nmemb * size> __b)
+ __builtin_trap();
+
+ return __orig_qsort(base, nmemb, size, compar);
+}
/* FIXME clang */
#if !defined(__clang__)
diff --git a/tests/Makefile b/tests/Makefile
@@ -71,6 +71,8 @@ RUNTIME_TARGETS= \
test_printf \
test_pwrite_dynamic \
test_pwrite_static \
+ test_qsort_dynamic \
+ test_qsort_static \
test_read_dynamic \
test_read_static \
test_readlink_dynamic \
diff --git a/tests/test_qsort_dynamic.c b/tests/test_qsort_dynamic.c
@@ -0,0 +1,26 @@
+#include "common.h"
+
+#include <stdlib.h>
+
+static int cmp(const void *p1, const void *p2);
+
+int main(int argc, char** argv) {
+ char buffer[] = {'a', 'b', 'c', 'd', 'e', '\0'};
+
+ qsort(buffer, 6, sizeof(char), cmp);
+
+ puts(buffer);
+
+ CHK_FAIL_START
+ qsort(buffer, argc, sizeof(char), cmp);
+ CHK_FAIL_END
+
+ puts(buffer);
+
+ return ret;
+}
+
+static int cmp(const void *p1, const void *p2)
+{
+ return (* (char*) p1 > * (char*) p2);
+}
diff --git a/tests/test_qsort_static.c b/tests/test_qsort_static.c
@@ -0,0 +1,26 @@
+#include "common.h"
+
+#include <stdlib.h>
+
+static int cmp(const void *p1, const void *p2);
+
+int main(int argc, char** argv) {
+ char buffer[] = {'a', 'b', 'c', 'd', 'e', '\0'};
+
+ qsort(buffer, 6, sizeof(char), cmp);
+
+ puts(buffer);
+
+ CHK_FAIL_START
+ qsort(buffer, 12, sizeof(char), cmp);
+ CHK_FAIL_END
+
+ puts(buffer);
+
+ return ret;
+}
+
+static int cmp(const void *p1, const void *p2)
+{
+ return (* (char*) p1 > * (char*) p2);
+}