diff options
Diffstat (limited to 'test/sanitizer_common/TestCases/Posix')
29 files changed, 1075 insertions, 46 deletions
diff --git a/test/sanitizer_common/TestCases/Posix/arc4random.cc b/test/sanitizer_common/TestCases/Posix/arc4random.cc new file mode 100644 index 000000000000..0a983b58f59f --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/arc4random.cc @@ -0,0 +1,71 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, darwin, solaris + +#include <cstdlib> +#include <ctime> +#include <cstdio> +#include <inttypes.h> + +void print_buf(unsigned char *buf, size_t buflen) { + printf("buf '"); + for (auto i = 0; i < buflen; i ++) + printf("%" PRIx8, buf[i]); + printf("'\n"); +} + +void test_seed() { +#ifdef __NetBSD__ + time_t now = ::time(nullptr); + arc4random_addrandom((unsigned char *)&now, sizeof(now)); +#endif +} + +void test_arc4random() { + printf("test_arc4random\n"); + auto i = arc4random(); + print_buf((unsigned char *)&i, sizeof(i)); +} + +void test_arc4random_uniform() { + printf("test_arc4random_uniform\n"); + auto i = arc4random_uniform(1024); + print_buf((unsigned char *)&i, sizeof(i)); +} + +void test_arc4random_buf10() { + printf("test_arc4random_buf10\n"); + char buf[10]; +#ifdef __NetBSD__ + arc4random_stir(); +#endif + arc4random_buf(buf, sizeof(buf)); + print_buf((unsigned char *)buf, sizeof(buf)); +} + +void test_arc4random_buf256() { + printf("test_arc4random_buf256\n"); + char buf[256]; +#ifdef __NetBSD__ + arc4random_stir(); +#endif + arc4random_buf(buf, sizeof(buf)); + print_buf((unsigned char *)buf, sizeof(buf)); +} + +int main(void) { + test_seed(); + test_arc4random(); + test_arc4random_uniform(); + test_arc4random_buf10(); + test_arc4random_buf256(); + return 0; + // CHECK: test_arc4random + // CHECK: buf '{{.*}}' + // CHECK: test_arc4random_uniform + // CHECK: buf '{{.*}}' + // CHECK: test_arc4random_buf10 + // CHECK: buf '{{.*}}' + // CHECK: test_arc4random_buf256 + // CHECK: buf '{{.*}}' +} diff --git a/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cc b/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cc index d9a1bc66082c..94c50be169b4 100644 --- a/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cc +++ b/test/sanitizer_common/TestCases/Posix/dedup_token_length_test.cc @@ -8,6 +8,8 @@ // REQUIRES: stable-runtime +// XFAIL: netbsd && !asan + volatile int *null = 0; namespace Xyz { diff --git a/test/sanitizer_common/TestCases/Posix/devname.cc b/test/sanitizer_common/TestCases/Posix/devname.cc index da4bb8853a12..1495f7d9d518 100644 --- a/test/sanitizer_common/TestCases/Posix/devname.cc +++ b/test/sanitizer_common/TestCases/Posix/devname.cc @@ -1,6 +1,7 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s // UNSUPPORTED: linux, solaris +#include <assert.h> #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> @@ -9,11 +10,8 @@ int main(void) { struct stat st; char *name; - if (stat("/dev/null", &st)) - exit(1); - - if (!(name = devname(st.st_rdev, S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK))) - exit(1); + assert(!stat("/dev/null", &st)); + assert((name = devname(st.st_rdev, S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK))); printf("%s\n", name); diff --git a/test/sanitizer_common/TestCases/Posix/devname_r.cc b/test/sanitizer_common/TestCases/Posix/devname_r.cc index 826b7c92ef2f..ae10a766271e 100644 --- a/test/sanitizer_common/TestCases/Posix/devname_r.cc +++ b/test/sanitizer_common/TestCases/Posix/devname_r.cc @@ -4,6 +4,7 @@ #include <sys/cdefs.h> #include <sys/stat.h> +#include <assert.h> #include <stdio.h> #include <stdlib.h> @@ -12,13 +13,15 @@ int main(void) { char name[100]; mode_t type; - if (stat("/dev/null", &st)) - exit(1); + assert(!stat("/dev/null", &st)); type = S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK; - if (!devname_r(st.st_rdev, type, name, sizeof(name))) - exit(1); +#if defined(__NetBSD__) + assert(!devname_r(st.st_rdev, type, name, sizeof(name))); +#else + assert(devname_r(st.st_rdev, type, name, sizeof(name))); +#endif printf("%s\n", name); diff --git a/test/sanitizer_common/TestCases/Posix/dump_instruction_bytes.cc b/test/sanitizer_common/TestCases/Posix/dump_instruction_bytes.cc index 87e797a00ae1..f42802a34582 100644 --- a/test/sanitizer_common/TestCases/Posix/dump_instruction_bytes.cc +++ b/test/sanitizer_common/TestCases/Posix/dump_instruction_bytes.cc @@ -1,11 +1,9 @@ // Check that sanitizer prints the faulting instruction bytes on // dump_instruction_bytes=1 -// clang-format off // RUN: %clangxx %s -o %t // RUN: %env_tool_opts=dump_instruction_bytes=1 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-DUMP // RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NODUMP -// clang-format on // REQUIRES: x86-target-arch diff --git a/test/sanitizer_common/TestCases/Posix/feof_fileno_ferror.cc b/test/sanitizer_common/TestCases/Posix/feof_fileno_ferror.cc new file mode 100644 index 000000000000..cfcf0e3970a4 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/feof_fileno_ferror.cc @@ -0,0 +1,41 @@ +// RUN: %clangxx -g %s -o %t && %run %t + +#include <assert.h> +#include <stdio.h> +#include <unistd.h> + +int main(int argc, char **argv) { + FILE *fp = fopen(argv[0], "r"); + assert(fp); + + // file should be good upon opening + assert(!feof(fp) && !ferror(fp)); + + // read until EOF + char buf[BUFSIZ]; + while (fread(buf, 1, sizeof buf, fp) != 0) {} + assert(feof(fp)); + + // clear EOF + clearerr(fp); + assert(!feof(fp) && !ferror(fp)); + + // get file descriptor + int fd = fileno(fp); + assert(fd != -1); + + // break the file by closing underlying descriptor + assert(close(fd) != -1); + + // verify that an error is signalled + assert(fread(buf, 1, sizeof buf, fp) == 0); + assert(ferror(fp)); + + // clear error + clearerr(fp); + assert(!feof(fp) && !ferror(fp)); + + // fclose() will return EBADF because of closed fd + assert(fclose(fp) == -1); + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/fgetc_ungetc_getc.cc b/test/sanitizer_common/TestCases/Posix/fgetc_ungetc_getc.cc new file mode 100644 index 000000000000..f895cf194ce7 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/fgetc_ungetc_getc.cc @@ -0,0 +1,19 @@ +// RUN: %clangxx -g %s -o %t && %run %t + +#include <assert.h> +#include <stdio.h> + +int main(int argc, char **argv) { + FILE *fp = fopen(argv[0], "r"); + assert(fp); + + // the file should be at least one character long, always + assert(fgetc(fp) != EOF); + // POSIX guarantees being able to ungetc() at least one character + assert(ungetc('X', fp) != EOF); + // check whether ungetc() worked + assert(getc(fp) == 'X'); + + assert(!fclose(fp)); + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/fgetln.cc b/test/sanitizer_common/TestCases/Posix/fgetln.cc index e98cf449a272..b1b4665389a3 100644 --- a/test/sanitizer_common/TestCases/Posix/fgetln.cc +++ b/test/sanitizer_common/TestCases/Posix/fgetln.cc @@ -1,24 +1,20 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t // UNSUPPORTED: linux +#include <assert.h> #include <stdio.h> #include <stdlib.h> int main(void) { - FILE *fp; - size_t len; - char *s; - - fp = fopen("/etc/hosts", "r"); - if (!fp) - exit(1); + FILE *fp = fopen("/etc/hosts", "r"); + assert(fp); - s = fgetln(fp, &len); + size_t len; + char *s = fgetln(fp, &len); printf("%.*s\n", (int)len, s); - if (fclose(fp) == EOF) - exit(1); + assert(!fclose(fp)); return 0; } diff --git a/test/sanitizer_common/TestCases/Posix/fgets.cc b/test/sanitizer_common/TestCases/Posix/fgets.cc index 8dde5cd1a84f..6a639f8047db 100644 --- a/test/sanitizer_common/TestCases/Posix/fgets.cc +++ b/test/sanitizer_common/TestCases/Posix/fgets.cc @@ -1,20 +1,16 @@ // RUN: %clangxx -g %s -o %t && %run %t +#include <assert.h> #include <stdio.h> int main(int argc, char **argv) { - FILE *fp; - char buf[2]; - char *s; - - fp = fopen(argv[0], "r"); - if (!fp) - return 1; + FILE *fp = fopen(argv[0], "r"); + assert(fp); - s = fgets(buf, sizeof(buf), fp); - if (!s) - return 2; + char buf[2]; + char *s = fgets(buf, sizeof(buf), fp); + assert(s); - fclose(fp); + assert(!fclose(fp)); return 0; } diff --git a/test/sanitizer_common/TestCases/Posix/fputc_putc_putchar.cc b/test/sanitizer_common/TestCases/Posix/fputc_putc_putchar.cc new file mode 100644 index 000000000000..7e786cd9ef37 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/fputc_putc_putchar.cc @@ -0,0 +1,13 @@ +// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s +// CHECK: abc + +#include <assert.h> +#include <stdio.h> + +int main(void) { + assert(fputc('a', stdout) != EOF); + assert(putc('b', stdout) != EOF); + assert(putchar('c') != EOF); + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/fputs_puts.cc b/test/sanitizer_common/TestCases/Posix/fputs_puts.cc index 8e8f7d384e8c..21bb93aa4310 100644 --- a/test/sanitizer_common/TestCases/Posix/fputs_puts.cc +++ b/test/sanitizer_common/TestCases/Posix/fputs_puts.cc @@ -1,18 +1,12 @@ // RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s // CHECK: {{^foobar$}} +#include <assert.h> #include <stdio.h> int main(void) { - int r; - - r = fputs("foo", stdout); - if (r < 0) - return 1; - - r = puts("bar"); - if (r < 0) - return 1; + assert(fputs("foo", stdout) >= 0); + assert(puts("bar") >= 0); return 0; } diff --git a/test/sanitizer_common/TestCases/Posix/fseek.cc b/test/sanitizer_common/TestCases/Posix/fseek.cc new file mode 100644 index 000000000000..26f3b849f4c4 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/fseek.cc @@ -0,0 +1,53 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, darwin, solaris + +#include <assert.h> +#include <inttypes.h> +#include <stdio.h> + +int main(void) { + printf("fseek\n"); + + FILE *fp = fopen("/etc/fstab", "r"); + assert(fp); + + int rv = fseek(fp, 10, SEEK_SET); + assert(!rv); + + printf("position: %ld\n", ftell(fp)); + + rewind(fp); + + printf("position: %ld\n", ftell(fp)); + + rv = fseeko(fp, 15, SEEK_SET); + assert(!rv); + + printf("position: %" PRIuMAX "\n", (uintmax_t)ftello(fp)); + + fpos_t pos; + rv = fgetpos(fp, &pos); + assert(!rv); + + rewind(fp); + + printf("position: %" PRIuMAX "\n", (uintmax_t)ftello(fp)); + + rv = fsetpos(fp, &pos); + assert(!rv); + + printf("position: %" PRIuMAX "\n", (uintmax_t)ftello(fp)); + + rv = fclose(fp); + assert(!rv); + + // CHECK: fseek + // CHECK: position: 10 + // CHECK: position: 0 + // CHECK: position: 15 + // CHECK: position: 0 + // CHECK: position: 15 + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/fts.cc b/test/sanitizer_common/TestCases/Posix/fts.cc new file mode 100644 index 000000000000..79c41f7de674 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/fts.cc @@ -0,0 +1,42 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, darwin, solaris + +#include <sys/param.h> +#include <sys/types.h> + +#include <sys/stat.h> + +#include <assert.h> +#include <fts.h> +#include <stdio.h> +#include <stdlib.h> + +int main() { + char *const paths[] = {(char *)"/etc", 0}; + FTS *ftsp = fts_open(paths, FTS_LOGICAL, NULL); + assert(ftsp); + + FTSENT *chp = fts_children(ftsp, 0); + assert(chp); + + size_t n = 0; + for (FTSENT *p = fts_read(ftsp); p; p = fts_read(ftsp)) { + /* Skip recursively subdirectories */ + if (p->fts_info == FTS_D && p->fts_level != FTS_ROOTLEVEL) /* pre-order */ + fts_set(ftsp, p, FTS_SKIP); + else if (p->fts_info == FTS_DP) /* post-order */ + continue; + else if (p->fts_info == FTS_F) /* regular file */ + n++; + } + + int rv = fts_close(ftsp); + assert(!rv); + + printf("Number of files in /etc: '%zu'\n", n); + + return EXIT_SUCCESS; + + // CHECK: Number of files in /etc: '{{.*}}' +} diff --git a/test/sanitizer_common/TestCases/Posix/funopen.cc b/test/sanitizer_common/TestCases/Posix/funopen.cc new file mode 100644 index 000000000000..7d3192488ec5 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/funopen.cc @@ -0,0 +1,91 @@ +// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s + +// CHECK: READ CALLED; len={{[0-9]*}} +// CHECK-NEXT: READ: test +// CHECK-NEXT: WRITE CALLED: test +// CHECK-NEXT: READ CALLED; len={{[0-9]*}} +// CHECK-NEXT: READ: test +// CHECK-NEXT: WRITE CALLED: test +// CHECK-NEXT: CLOSE CALLED +// CHECK-NEXT: SEEK CALLED; off=100, whence=0 +// CHECK-NEXT: READ CALLED; len={{[0-9]*}} +// CHECK-NEXT: READ: test +// +// UNSUPPORTED: linux, darwin, solaris + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +int cookie_var; + +int f_read(void *cookie, char *buf, int len) { + assert(cookie == &cookie_var); + assert(len >= 6); + printf("READ CALLED; len=%d\n", len); + return strlcpy(buf, "test\n", len); +} + +int f_write(void *cookie, const char *buf, int len) { + assert(cookie == &cookie_var); + char *data = strndup(buf, len); + assert(data); + printf("WRITE CALLED: %s\n", data); + free(data); + return len; +} + +off_t f_seek(void *cookie, off_t off, int whence) { + assert(cookie == &cookie_var); + assert(whence == SEEK_SET); + printf("SEEK CALLED; off=%d, whence=%d\n", (int)off, whence); + return off; +} + +int f_close(void *cookie) { + assert(cookie == &cookie_var); + printf("CLOSE CALLED\n"); + return 0; +} + +int main(void) { + FILE *fp; + char buf[10]; + + // 1. read-only variant + fp = fropen(&cookie_var, f_read); + assert(fp); + // verify that fileno() does not crash or report nonsense + assert(fileno(fp) == -1); + assert(fgets(buf, sizeof(buf), fp)); + printf("READ: %s", buf); + assert(!fclose(fp)); + + // 2. write-only variant + fp = fwopen(&cookie_var, f_write); + assert(fp); + assert(fileno(fp) == -1); + assert(fputs("test", fp) >= 0); + assert(!fclose(fp)); + + // 3. read+write+close + fp = funopen(&cookie_var, f_read, f_write, NULL, f_close); + assert(fp); + assert(fileno(fp) == -1); + assert(fgets(buf, sizeof(buf), fp)); + printf("READ: %s", buf); + assert(fputs("test", fp) >= 0); + assert(!fclose(fp)); + + // 4. read+seek + fp = funopen(&cookie_var, f_read, NULL, f_seek, NULL); + assert(fp); + assert(fileno(fp) == -1); + assert(fseek(fp, 100, SEEK_SET) == 0); + assert(fgets(buf, sizeof(buf), fp)); + printf("READ: %s", buf); + assert(!fclose(fp)); + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/getc_unlocked.cc b/test/sanitizer_common/TestCases/Posix/getc_unlocked.cc new file mode 100644 index 000000000000..c4257d130428 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/getc_unlocked.cc @@ -0,0 +1,20 @@ +// RUN: %clangxx -g %s -o %t && %run %t + +#include <assert.h> +#include <stdio.h> + +int main(int argc, char **argv) { + FILE *fp = fopen(argv[0], "r"); + assert(fp); + + // the file should be at least one character long, always + assert(getc_unlocked(fp) != EOF); + // POSIX guarantees being able to ungetc() at least one character + // NB: ungetc_unlocked is apparently not present + assert(ungetc('X', fp) != EOF); + // check whether ungetc() works with getc_unlocked() + assert(getc_unlocked(fp) == 'X'); + + assert(!fclose(fp)); + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/getfsent.cc b/test/sanitizer_common/TestCases/Posix/getfsent.cc new file mode 100644 index 000000000000..687a7a7d4879 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/getfsent.cc @@ -0,0 +1,36 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, darwin, solaris + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <fstab.h> + +int main(void) { + printf("getfsent\n"); + + setfsent(); + struct fstab *fentry = getfsent(); + + assert(fentry); + + setfsent(); + struct fstab *pentry = getfsspec(fentry->fs_spec); + assert(pentry); + setfsent(); + struct fstab *wentry = getfsfile(fentry->fs_file); + assert(wentry); + assert(!memcmp(fentry, wentry, sizeof(*wentry))); + assert(!memcmp(pentry, wentry, sizeof(*pentry))); + + printf("First entry: device block '%s', mounted with '%s'\n", + fentry->fs_spec, fentry->fs_mntops); + + endfsent(); + + return 0; + // CHECK: getfsent + // CHECK: First entry: device block '{{.*}}', mounted with '{{.*}}' +} diff --git a/test/sanitizer_common/TestCases/Posix/getmntinfo.cc b/test/sanitizer_common/TestCases/Posix/getmntinfo.cc new file mode 100644 index 000000000000..26c065d4dd1f --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/getmntinfo.cc @@ -0,0 +1,35 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, solaris + +#include <sys/types.h> + +#if defined(__NetBSD__) +#include <sys/statvfs.h> +#else +#include <sys/mount.h> +#endif + +#include <err.h> +#include <stdio.h> +#include <stdlib.h> + +int main(void) { + printf("getmntinfo\n"); + +#if defined(__NetBSD__) + struct statvfs *fss; +#else + struct statfs *fss; +#endif + int nfss = getmntinfo(&fss, MNT_NOWAIT); + if (nfss <= 0) + errx(1, "getmntinfo"); + + for (int i = 0; i < nfss; i++) + printf("%d: %s\n", i, fss[i].f_fstypename); + + // CHECK: getmntinfo + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/getusershell.cc b/test/sanitizer_common/TestCases/Posix/getusershell.cc new file mode 100644 index 000000000000..c00d75f11211 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/getusershell.cc @@ -0,0 +1,23 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s + +// UNSUPPORTED: android + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <unistd.h> + +int main(void) { + printf("getusershell\n"); + + setusershell(); + char *fentry = getusershell(); + + printf("First entry: '%s'\n", fentry); + + endusershell(); + + return 0; + // CHECK: getusershell + // CHECK: First entry: '{{.*}}' +} diff --git a/test/sanitizer_common/TestCases/Posix/lstat.cc b/test/sanitizer_common/TestCases/Posix/lstat.cc index 37237d82102c..01c2ea83d9c1 100644 --- a/test/sanitizer_common/TestCases/Posix/lstat.cc +++ b/test/sanitizer_common/TestCases/Posix/lstat.cc @@ -1,16 +1,14 @@ // RUN: %clangxx -O0 -g %s -o %t && %run %t +#include <assert.h> #include <stdlib.h> #include <sys/stat.h> int main(void) { struct stat st; - if (lstat("/dev/null", &st)) - exit(1); - - if (!S_ISCHR(st.st_mode)) - exit(1); + assert(!lstat("/dev/null", &st)); + assert(S_ISCHR(st.st_mode)); return 0; } diff --git a/test/sanitizer_common/TestCases/Posix/nl_langinfo.cc b/test/sanitizer_common/TestCases/Posix/nl_langinfo.cc new file mode 100644 index 000000000000..b8123542fb8f --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/nl_langinfo.cc @@ -0,0 +1,20 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, darwin, solaris + +#include <langinfo.h> + +#include <stdio.h> + +int main(void) { + printf("nl_langinfo\n"); + + char *info = nl_langinfo(DAY_1); + + printf("DAY_1='%s'\n", info); + + // CHECK: nl_langinfo + // CHECK: DAY_1='{{.*}}' + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/popen.cc b/test/sanitizer_common/TestCases/Posix/popen.cc new file mode 100644 index 000000000000..6bf6255a697a --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/popen.cc @@ -0,0 +1,23 @@ +// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s +// CHECK: 1 +// CHECK-NEXT: 2 + +#include <assert.h> +#include <stdio.h> + +int main(void) { + // use a tool that produces different output than input to verify + // that everything worked correctly + FILE *fp = popen("sort", "w"); + assert(fp); + + // verify that fileno() returns a meaningful descriptor (needed + // for the implementation of TSan) + assert(fileno(fp) != -1); + + assert(fputs("2\n", fp) >= 0); + assert(fputs("1\n", fp) >= 0); + assert(pclose(fp) == 0); + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/putc_putchar_unlocked.cc b/test/sanitizer_common/TestCases/Posix/putc_putchar_unlocked.cc new file mode 100644 index 000000000000..12c35c220d97 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/putc_putchar_unlocked.cc @@ -0,0 +1,12 @@ +// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s +// CHECK: bc + +#include <assert.h> +#include <stdio.h> + +int main(void) { + assert(putc_unlocked('b', stdout) != EOF); + assert(putchar_unlocked('c') != EOF); + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/readlinkat.c b/test/sanitizer_common/TestCases/Posix/readlinkat.c index 0afb5efe6b5f..227c6da54afb 100644 --- a/test/sanitizer_common/TestCases/Posix/readlinkat.c +++ b/test/sanitizer_common/TestCases/Posix/readlinkat.c @@ -1,5 +1,7 @@ // RUN: %clang -O0 %s -o %t && %run %t +// XFAIL: i386-netbsd && asan + #include <assert.h> #include <fcntl.h> #include <limits.h> diff --git a/test/sanitizer_common/TestCases/Posix/regex.cc b/test/sanitizer_common/TestCases/Posix/regex.cc new file mode 100644 index 000000000000..3727f01325f8 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/regex.cc @@ -0,0 +1,71 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: darwin, solaris + +#include <assert.h> +#include <regex.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef __arraycount +#define __arraycount(a) ((sizeof(a) / sizeof(a[0]))) +#endif + +void test_matched(const regex_t *preg, const char *string) { + int rv = regexec(preg, string, 0, NULL, 0); + if (!rv) + printf("%s: matched\n", string); + else if (rv == REG_NOMATCH) + printf("%s: not-matched\n", string); + else + abort(); +} + +void test_print_matches(const regex_t *preg, const char *string) { + regmatch_t rm[10]; + int rv = regexec(preg, string, __arraycount(rm), rm, 0); + if (!rv) { + for (size_t i = 0; i < __arraycount(rm); i++) { + // This condition shall be simplified, but verify that the data fields + // are accessible. + if (rm[i].rm_so == -1 && rm[i].rm_eo == -1) + continue; + printf("matched[%zu]='%.*s'\n", i, (int)(rm[i].rm_eo - rm[i].rm_so), + string + rm[i].rm_so); + } + } else if (rv == REG_NOMATCH) + printf("%s: not-matched\n", string); + else + abort(); +} + +int main(void) { + printf("regex\n"); + + regex_t regex; + int rv = regcomp(®ex, "[[:upper:]]\\([[:upper:]]\\)", 0); + assert(!rv); + + test_matched(®ex, "abc"); + test_matched(®ex, "ABC"); + + test_print_matches(®ex, "ABC"); + + regfree(®ex); + + rv = regcomp(®ex, "[[:upp:]]", 0); + assert(rv); + + char errbuf[1024]; + regerror(rv, ®ex, errbuf, sizeof errbuf); + printf("error: %s\n", errbuf); + + // CHECK: regex + // CHECK: abc: not-matched + // CHECK: ABC: matched + // CHECK: matched[0]='AB' + // CHECK: matched[1]='B' + // CHECK: error:{{.*}} + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/setvbuf.cc b/test/sanitizer_common/TestCases/Posix/setvbuf.cc new file mode 100644 index 000000000000..bc29ba45d89a --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/setvbuf.cc @@ -0,0 +1,81 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s + +// UNSUPPORTED: solaris + +#include <stdio.h> + +void print_something() { + for (size_t i = 0; i < 10 * BUFSIZ; i++) + printf("Hello world %zu\n", i); +} + +void print_one_byte(char *buf) { + printf("First byte is %c\n", buf[0]); +} + +void test_setbuf() { + char buf[BUFSIZ]; + + setbuf(stdout, NULL); + + print_something(); + + setbuf(stdout, buf); + + print_something(); + + print_one_byte(buf); +} + +void test_setbuffer() { + char buf[BUFSIZ]; + + setbuffer(stdout, NULL, 0); + + print_something(); + + setbuffer(stdout, buf, BUFSIZ); + + print_something(); + + print_one_byte(buf); +} + +void test_setlinebuf() { + setlinebuf(stdout); + + print_something(); +} + +void test_setvbuf() { + char buf[BUFSIZ]; + + setvbuf(stdout, NULL, _IONBF, 0); + + print_something(); + + setvbuf(stdout, buf, _IOLBF, BUFSIZ); + + print_something(); + + print_one_byte(buf); + + setvbuf(stdout, buf, _IOFBF, BUFSIZ); + + print_something(); + + print_one_byte(buf); +} + +int main(void) { + printf("setvbuf\n"); + + test_setbuf(); + test_setbuffer(); + test_setlinebuf(); + test_setvbuf(); + + // CHECK: setvbuf + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/sl_add.cc b/test/sanitizer_common/TestCases/Posix/sl_add.cc new file mode 100644 index 000000000000..4da70c7888f6 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/sl_add.cc @@ -0,0 +1,26 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, darwin, solaris + +#include <assert.h> +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <stringlist.h> + +int main(void) { + printf("sl_add\n"); + + StringList *sl = sl_init(); + assert(sl); + char *p = strdup("entry"); + assert(!sl_add(sl, p)); + char *entry = sl_find(sl, "entry"); + assert(!strcmp(entry, p)); + printf("Found '%s'\n", entry); + sl_free(sl, 1); + + return 0; + // CHECK: sl_add + // CHECK: Found '{{.*}}' +} diff --git a/test/sanitizer_common/TestCases/Posix/strtonum.cc b/test/sanitizer_common/TestCases/Posix/strtonum.cc new file mode 100644 index 000000000000..22346b2e111c --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/strtonum.cc @@ -0,0 +1,54 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, darwin, solaris + +#define _OPENBSD_SOURCE + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +int main(void) { + const char *errstr; + + printf("strtonum\n"); + + long long l = strtonum("100", 1, 100, &errstr); + assert(!errstr); + printf("%lld\n", l); + + l = strtonum("200", 1, 100, &errstr); + assert(errstr); + printf("%s\n", errstr); + + l = strtonum("300", 1000, 1001, &errstr); + assert(errstr); + printf("%s\n", errstr); + + l = strtonum("abc", 1000, 1001, &errstr); + assert(errstr); + printf("%s\n", errstr); + + l = strtonum("1000", 1001, 1000, &errstr); + assert(errstr); + printf("%s\n", errstr); + + l = strtonum("1000abc", 1000, 1001, &errstr); + assert(errstr); + printf("%s\n", errstr); + + l = strtonum("1000.0", 1000, 1001, &errstr); + assert(errstr); + printf("%s\n", errstr); + + // CHECK: strtonum + // CHECK: 100 + // CHECK: too large + // CHECK: too small + // CHECK: invalid + // CHECK: invalid + // CHECK: invalid + // CHECK: invalid + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/sysctl.cc b/test/sanitizer_common/TestCases/Posix/sysctl.cc new file mode 100644 index 000000000000..2cb8764f34b0 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/sysctl.cc @@ -0,0 +1,64 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, solaris + +#include <sys/param.h> +#include <sys/types.h> + +#include <sys/sysctl.h> + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + +#ifndef __arraycount +#define __arraycount(a) (sizeof(a) / sizeof(a[0])) +#endif + +void test_sysctl() { + char buf[100]; + size_t len = sizeof(buf); + int mib[] = {CTL_KERN, KERN_OSTYPE}; + int rv = sysctl(mib, __arraycount(mib), buf, &len, NULL, 0); + assert(!rv); + + printf("sysctl: '%s' size: '%zu'\n", buf, len); +} + +void test_sysctlbyname() { + char buf[100]; + size_t len = sizeof(buf); + int rv = sysctlbyname("kern.ostype", buf, &len, NULL, 0); + assert(!rv); + + printf("sysctlbyname: '%s' size: '%zu'\n", buf, len); +} + +void test_sysctlnametomib() { + int mib[CTL_MAXNAME]; + size_t mib_len = __arraycount(mib); + int rv = sysctlnametomib("kern.ostype", &mib[0], &mib_len); + assert(!rv); + + char buf[100]; + size_t len = sizeof(buf); + rv = sysctl(mib, mib_len, buf, &len, NULL, 0); + assert(!rv); + + printf("sysctlnametomib: '%s' size: '%zu'\n", buf, len); +} + +int main(void) { + printf("sysctl\n"); + + test_sysctl(); + test_sysctlbyname(); + test_sysctlnametomib(); + + // CHECK: sysctl + // CHECK: sysctl: '{{.*}}' size: '{{.*}}' + // CHECK: sysctlbyname: '{{.*}}' size: '{{.*}}' + // CHECK: sysctlnametomib: '{{.*}}' size: '{{.*}}' + + return 0; +} diff --git a/test/sanitizer_common/TestCases/Posix/vis.cc b/test/sanitizer_common/TestCases/Posix/vis.cc new file mode 100644 index 000000000000..15f1bc949023 --- /dev/null +++ b/test/sanitizer_common/TestCases/Posix/vis.cc @@ -0,0 +1,247 @@ +// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s +// +// UNSUPPORTED: linux, solaris, darwin + +#include <ctype.h> +#include <err.h> +#include <inttypes.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <vis.h> + +void test_vis() { + char visout[5]; + int ch = toascii(0x1); + vis(visout, ch, VIS_SAFE | VIS_NOSLASH, 0); + printf("vis: %s\n", visout); +} + +void test_nvis() { + char visout[5]; + int ch = toascii(0x2); + nvis(visout, sizeof visout, ch, VIS_SAFE | VIS_NOSLASH, 0); + printf("nvis: %s\n", visout); +} + +void test_strvis() { + char visout[5]; + strvis(visout, "\3", VIS_SAFE | VIS_NOSLASH); + printf("strvis: %s\n", visout); +} + +void test_stravis() { + char *visout; + stravis(&visout, "\4", VIS_SAFE | VIS_NOSLASH); + printf("stravis: %s\n", visout); + free(visout); +} + +void test_strnvis() { + char visout[5]; + strnvis(visout, sizeof visout, "\5", VIS_SAFE | VIS_NOSLASH); + printf("strnvis: %s\n", visout); +} + +void test_strvisx() { + char visout[5]; + char src[] = "\6"; + strvisx(visout, src, sizeof src - 1 /* skip final \0 */, + VIS_SAFE | VIS_NOSLASH); + printf("strvisx: %s\n", visout); +} + +void test_strnvisx() { + char visout[5]; + char src[] = "\1"; + strnvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */, + VIS_SAFE | VIS_NOSLASH); + printf("strnvisx: %s\n", visout); +} + +void test_strenvisx() { + char visout[5]; + char src[] = "\2"; + strenvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */, + VIS_SAFE | VIS_NOSLASH, NULL); + printf("strenvisx: %s\n", visout); +} + +void test_svis() { + char visout[5]; + int ch = toascii(0x3); + svis(visout, ch, VIS_SAFE | VIS_NOSLASH, 0, "x"); + printf("svis: %s\n", visout); +} + +void test_snvis() { + char visout[5]; + int ch = toascii(0x2); + snvis(visout, sizeof visout, ch, VIS_SAFE | VIS_NOSLASH, 0, "x"); + printf("snvis: %s\n", visout); +} + +void test_strsvis() { + char visout[5]; + strsvis(visout, "\4", VIS_SAFE | VIS_NOSLASH, "x"); + printf("strsvis: %s\n", visout); +} + +void test_strsnvis() { + char visout[5]; + strsnvis(visout, sizeof visout, "\5", VIS_SAFE | VIS_NOSLASH, "x"); + printf("strsnvis: %s\n", visout); +} + +void test_strsvisx() { + char visout[5]; + char src[] = "\5"; + strsvisx(visout, src, sizeof src - 1 /* skip final \0 */, + VIS_SAFE | VIS_NOSLASH, "x"); + printf("strsvisx: %s\n", visout); +} + +void test_strsnvisx() { + char visout[5]; + char src[] = "\6"; + strsnvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */, + VIS_SAFE | VIS_NOSLASH, "x"); + printf("strsnvisx: %s\n", visout); +} + +void test_strsenvisx() { + char visout[5]; + char src[] = "\1"; + strsenvisx(visout, sizeof visout, src, sizeof src - 1 /* skip final \0 */, + VIS_SAFE | VIS_NOSLASH, "x", NULL); + printf("strsenvisx: %s\n", visout); +} + +void test_unvis() { + char visout[5]; + int ch = toascii(0x1); + vis(visout, ch, VIS_SAFE, 0); + + int state = 0; + char out; + char *p = visout; + while ((ch = *(p++)) != '\0') { + again: + switch (unvis(&out, ch, &state, 0)) { + case 0: + case UNVIS_NOCHAR: + break; + case UNVIS_VALID: + printf("unvis: %" PRIx8 "\n", (unsigned char)out); + break; + case UNVIS_VALIDPUSH: + printf("unvis: %" PRIx8 "\n", (unsigned char)out); + goto again; + case UNVIS_SYNBAD: + errx(1, "Bad character sequence!"); + } + } + if (unvis(&out, '\0', &state, UNVIS_END) == UNVIS_VALID) + printf("unvis: %" PRIx8 "\n", (unsigned char)out); +} + +void test_strunvis() { + char visout[5]; + int ch = toascii(0x2); + vis(visout, ch, VIS_SAFE, 0); + + char p[5]; + strunvis(p, visout); + + char *pp = p; + while ((ch = *(pp++)) != '\0') + printf("strunvis: %" PRIx8 "\n", (unsigned char)ch); +} + +void test_strnunvis() { + char visout[5]; + int ch = toascii(0x3); + vis(visout, ch, VIS_SAFE, 0); + + char p[5]; + strnunvis(p, sizeof p, visout); + + char *pp = p; + while ((ch = *(pp++)) != '\0') + printf("strnunvis: %" PRIx8 "\n", (unsigned char)ch); +} + +void test_strunvisx() { + char visout[5]; + int ch = toascii(0x4); + vis(visout, ch, VIS_SAFE, 0); + + char p[5]; + strunvisx(p, visout, VIS_SAFE); + + char *pp = p; + while ((ch = *(pp++)) != '\0') + printf("strunvisx: %" PRIx8 "\n", (unsigned char)ch); +} + +void test_strnunvisx() { + char visout[5]; + int ch = toascii(0x5); + vis(visout, ch, VIS_SAFE, 0); + + char p[5]; + strnunvisx(p, sizeof p, visout, VIS_SAFE); + + char *pp = p; + while ((ch = *(pp++)) != '\0') + printf("strnunvisx: %" PRIx8 "\n", (unsigned char)ch); +} + +int main(void) { + printf("vis\n"); + + test_vis(); + test_nvis(); + test_strvis(); + test_stravis(); + test_strnvis(); + test_strvisx(); + test_strnvisx(); + test_strenvisx(); + test_svis(); + test_snvis(); + test_strsvis(); + test_strsnvis(); + test_strsvisx(); + test_strsnvisx(); + test_strsenvisx(); + test_unvis(); + test_strunvis(); + test_strnunvis(); + test_strunvisx(); + test_strnunvisx(); + + // CHECK: vis + // CHECK: vis: ^A + // CHECK: nvis: ^B + // CHECK: strvis: ^C + // CHECK: stravis: ^D + // CHECK: strnvis: ^E + // CHECK: strvisx: ^F + // CHECK: strnvisx: ^A + // CHECK: strenvisx: ^B + // CHECK: svis: ^C + // CHECK: snvis: ^B + // CHECK: strsvis: ^D + // CHECK: strsnvis: ^E + // CHECK: strsvisx: ^E + // CHECK: strsnvisx: ^F + // CHECK: strsenvisx: ^A + // CHECK: unvis: 1 + // CHECK: strunvis: 2 + // CHECK: strnunvis: 3 + // CHECK: strunvisx: 4 + // CHECK: strnunvisx: 5 + + return 0; +} |