static void one_test (const char *message, int error_code, const wchar_t *expected) { wchar_t *buffer = NULL; size_t length = 0; FILE *fp = open_wmemstream (&buffer, &length); TEST_VERIFY_EXIT (fp != NULL); FILE *old_stderr = stderr; stderr = fp; errno = error_code; switch (error_code) { case E2BIG: warn ("%s with padding " PADDING, message); break; case EAGAIN: warn ("%s", message); break; case -1: warnx ("%s", message); break; case -2: warnx ("%s with padding " PADDING, message); break; } stderr = old_stderr; TEST_VERIFY_EXIT (!ferror (fp)); TEST_COMPARE (fclose (fp), 0); if (wcscmp (buffer, expected) != 0) FAIL_EXIT1 ("unexpected output: %ls", buffer); free (buffer); }
static int do_test (void) { TEST_VERIFY_EXIT (setlocale (LC_ALL, "de_DE.UTF-8") != NULL); /* Fill the stdio buffer and advance the read pointer. */ TEST_VERIFY_EXIT (fgetwc (stdin) != WEOF); /* This calls _IO_wfile_sync, it should not crash. */ TEST_VERIFY_EXIT (setvbuf (stdin, NULL, _IONBF, 0) == 0); /* Verify that the external file offset has been synchronized. */ TEST_COMPARE (xlseek (0, 0, SEEK_CUR), 1); return 0; }
int do_test (void) { /* The easiest way to set up the conditions under which you can notice whether the end-of-file indicator is sticky, is with a pseudo-tty. This is also the case which applications are most likely to care about. And it avoids any question of whether and how it is legitimate to access the same physical file with two independent FILE objects. */ int outer_fd, inner_fd; FILE *fp; support_openpty (&outer_fd, &inner_fd, 0, 0, 0); fp = fdopen (inner_fd, "r+"); if (!fp) { perror ("fdopen"); return 1; } XWRITE (outer_fd, "abc\n\004", "first line + EOF"); TEST_COMPARE (fgetwc (fp), L'a'); TEST_COMPARE (fgetwc (fp), L'b'); TEST_COMPARE (fgetwc (fp), L'c'); TEST_COMPARE (fgetwc (fp), L'\n'); TEST_COMPARE (fgetwc (fp), WEOF); TEST_VERIFY_EXIT (feof (fp)); TEST_VERIFY_EXIT (!ferror (fp)); XWRITE (outer_fd, "d\n", "second line"); /* At this point, there is a new full line of input waiting in the kernelside input buffer, but we should still observe EOF from stdio, because the end-of-file indicator has not been cleared. */ TEST_COMPARE (fgetwc (fp), WEOF); /* Clearing EOF should reveal the next line of input. */ clearerr (fp); TEST_COMPARE (fgetwc (fp), L'd'); TEST_COMPARE (fgetwc (fp), L'\n'); fclose (fp); close (outer_fd); return 0; }
static int do_test (void) { char const pattern[] = "0|()0|\\1|0"; regex_t r; TEST_VERIFY_EXIT (regcomp (&r, pattern, REG_EXTENDED) == REG_ESUBREG); return 0; }
static int do_test (void) { /* It first allocates a open file description lock range which can not be represented in a 32 bit struct flock. */ struct flock64 lck64 = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = (off64_t)INT32_MAX + 1024, .l_len = 1024, }; int ret = fcntl64 (temp_fd, F_OFD_SETLKW, &lck64); if (ret == -1 && errno == EINVAL) /* OFD locks are only available on Linux 3.15. */ FAIL_UNSUPPORTED ("fcntl (F_OFD_SETLKW) not supported"); TEST_VERIFY_EXIT (ret == 0); /* Open file description locks placed through the same open file description (either by same file descriptor or a duplicated one created by fork, dup, fcntl F_DUPFD, etc.) overwrites then old lock. To force a conflicting lock combination, it creates a new file descriptor. */ int fd = open64 (temp_filename, O_RDWR, 0666); TEST_VERIFY_EXIT (fd != -1); /* It tries then to allocate another open file descriptior with a valid non-LFS bits struct flock but which will result in a conflicted region which can not be represented in a non-LFS struct flock. */ struct flock lck = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = INT32_MAX - 1024, .l_len = 4 * 1024, }; int r = fcntl (fd, F_OFD_GETLK, &lck); if (sizeof (off_t) != sizeof (off64_t)) TEST_VERIFY (r == -1 && errno == EOVERFLOW); else TEST_VERIFY (r == 0); return 0; }
bool support_enter_network_namespace (void) { #ifdef CLONE_NEWUTS if (unshare (CLONE_NEWUTS) == 0) in_uts_namespace = true; else printf ("warning: unshare (CLONE_NEWUTS) failed: %m\n"); #endif #ifdef CLONE_NEWNET if (unshare (CLONE_NEWNET) == 0) { /* Bring up the loopback interface. */ int fd = xsocket (AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); struct ifreq req; strcpy (req.ifr_name, "lo"); TEST_VERIFY_EXIT (ioctl (fd, SIOCGIFFLAGS, &req) == 0); bool already_up = req.ifr_flags & IFF_UP; if (already_up) /* This means that we likely have not achieved isolation from the parent namespace. */ printf ("warning: loopback interface already exists" " in new network namespace\n"); else { req.ifr_flags |= IFF_UP | IFF_RUNNING; TEST_VERIFY_EXIT (ioctl (fd, SIOCSIFFLAGS, &req) == 0); } close (fd); return !already_up; } #endif printf ("warning: could not enter network namespace\n"); return false; }
int do_test (void) { TEST_VERIFY_EXIT (setlocale (LC_COLLATE, "en_GB.UTF-8") != NULL); char *p = malloc (SIZE); if (p == NULL) { puts ("info: could not allocate memory, cannot run test"); return EXIT_UNSUPPORTED; } memset (p, 'x', SIZE - 1); p[SIZE - 1] = 0; printf ("info: strcoll result: %d\n", strcoll (p, p)); return 0; }
static int do_test (void) { char *path; { int fd = create_temp_file ("tst-bz24153-", &path); TEST_VERIFY_EXIT (fd >= 0); xwrite (fd, "abcdef", strlen ("abcdef")); xclose (fd); } narrow (path); wide (path); free (path); return 0; }
static int do_test (void) { char buf[4]; if (scanf ("%3s", buf) != 1) FAIL_UNSUPPORTED ("IBT not supported"); if (strcmp (buf, "IBT") != 0) FAIL_UNSUPPORTED ("IBT not supported"); TEST_VERIFY_EXIT (signal (SIGSEGV, &sig_handler) != SIG_ERR); /* Call bar via a function pointer to force an IBT violation. */ test (bar); return EXIT_FAILURE; }
static int do_test (void) { char *tempfile; int fd; /* Create a temporary file and open it in read-only mode. */ TEST_VERIFY_EXIT (create_temp_file ("tst-bz11319", &tempfile)); fd = xopen (tempfile, O_RDONLY, 0660); /* Try and write to the temporary file to intentionally fail, then check that dprintf (or __dprintf_chk) return EOF. */ TEST_COMPARE (dprintf (fd, "%d", 0), EOF); xclose (fd); free (tempfile); return 0; }
static int do_test (void) { const struct cpu_features *cpu_features = __get_cpu_features (); switch (cpu_features->basic.kind) { case arch_kind_intel: case arch_kind_amd: case arch_kind_other: printf ("Vendor: %s\n", cpu_kinds[cpu_features->basic.kind]); printf ("Family: 0x%x\n", cpu_features->basic.family); printf ("Model: 0x%x\n", cpu_features->basic.model); printf ("Stepping: 0x%x\n", cpu_features->basic.stepping); break; default: abort (); } #ifdef __SSE2__ TEST_VERIFY_EXIT (HAS_CPU_FEATURE (SSE2)); #endif printf ("CPU features:\n"); CHECK_CPU_FEATURE (SSE3); CHECK_CPU_FEATURE (PCLMULQDQ); CHECK_CPU_FEATURE (DTES64); CHECK_CPU_FEATURE (MONITOR); CHECK_CPU_FEATURE (DS_CPL); CHECK_CPU_FEATURE (VMX); CHECK_CPU_FEATURE (SMX); CHECK_CPU_FEATURE (EST); CHECK_CPU_FEATURE (TM2); CHECK_CPU_FEATURE (SSSE3); CHECK_CPU_FEATURE (CNXT_ID); CHECK_CPU_FEATURE (SDBG); CHECK_CPU_FEATURE (FMA); CHECK_CPU_FEATURE (CMPXCHG16B); CHECK_CPU_FEATURE (XTPRUPDCTRL); CHECK_CPU_FEATURE (PDCM); CHECK_CPU_FEATURE (PCID); CHECK_CPU_FEATURE (DCA); CHECK_CPU_FEATURE (SSE4_1); CHECK_CPU_FEATURE (SSE4_2); CHECK_CPU_FEATURE (X2APIC); CHECK_CPU_FEATURE (MOVBE); CHECK_CPU_FEATURE (POPCNT); CHECK_CPU_FEATURE (TSC_DEADLINE); CHECK_CPU_FEATURE (AES); CHECK_CPU_FEATURE (XSAVE); CHECK_CPU_FEATURE (OSXSAVE); CHECK_CPU_FEATURE (AVX); CHECK_CPU_FEATURE (F16C); CHECK_CPU_FEATURE (RDRAND); CHECK_CPU_FEATURE (FPU); CHECK_CPU_FEATURE (VME); CHECK_CPU_FEATURE (DE); CHECK_CPU_FEATURE (PSE); CHECK_CPU_FEATURE (TSC); CHECK_CPU_FEATURE (MSR); CHECK_CPU_FEATURE (PAE); CHECK_CPU_FEATURE (MCE); CHECK_CPU_FEATURE (CX8); CHECK_CPU_FEATURE (APIC); CHECK_CPU_FEATURE (SEP); CHECK_CPU_FEATURE (MTRR); CHECK_CPU_FEATURE (PGE); CHECK_CPU_FEATURE (MCA); CHECK_CPU_FEATURE (CMOV); CHECK_CPU_FEATURE (PAT); CHECK_CPU_FEATURE (PSE_36); CHECK_CPU_FEATURE (PSN); CHECK_CPU_FEATURE (CLFSH); CHECK_CPU_FEATURE (DS); CHECK_CPU_FEATURE (ACPI); CHECK_CPU_FEATURE (MMX); CHECK_CPU_FEATURE (FXSR); CHECK_CPU_FEATURE (SSE); CHECK_CPU_FEATURE (SSE2); CHECK_CPU_FEATURE (SS); CHECK_CPU_FEATURE (HTT); CHECK_CPU_FEATURE (TM); CHECK_CPU_FEATURE (PBE); CHECK_CPU_FEATURE (FSGSBASE); CHECK_CPU_FEATURE (TSC_ADJUST); CHECK_CPU_FEATURE (SGX); CHECK_CPU_FEATURE (BMI1); CHECK_CPU_FEATURE (HLE); CHECK_CPU_FEATURE (AVX2); CHECK_CPU_FEATURE (SMEP); CHECK_CPU_FEATURE (BMI2); CHECK_CPU_FEATURE (ERMS); CHECK_CPU_FEATURE (INVPCID); CHECK_CPU_FEATURE (RTM); CHECK_CPU_FEATURE (PQM); CHECK_CPU_FEATURE (MPX); CHECK_CPU_FEATURE (PQE); CHECK_CPU_FEATURE (AVX512F); CHECK_CPU_FEATURE (AVX512DQ); CHECK_CPU_FEATURE (RDSEED); CHECK_CPU_FEATURE (ADX); CHECK_CPU_FEATURE (SMAP); CHECK_CPU_FEATURE (AVX512_IFMA); CHECK_CPU_FEATURE (CLFLUSHOPT); CHECK_CPU_FEATURE (CLWB); CHECK_CPU_FEATURE (TRACE); CHECK_CPU_FEATURE (AVX512PF); CHECK_CPU_FEATURE (AVX512ER); CHECK_CPU_FEATURE (AVX512CD); CHECK_CPU_FEATURE (SHA); CHECK_CPU_FEATURE (AVX512BW); CHECK_CPU_FEATURE (AVX512VL); CHECK_CPU_FEATURE (PREFETCHWT1); CHECK_CPU_FEATURE (AVX512_VBMI); CHECK_CPU_FEATURE (UMIP); CHECK_CPU_FEATURE (PKU); CHECK_CPU_FEATURE (OSPKE); CHECK_CPU_FEATURE (WAITPKG); CHECK_CPU_FEATURE (AVX512_VBMI2); CHECK_CPU_FEATURE (SHSTK); CHECK_CPU_FEATURE (GFNI); CHECK_CPU_FEATURE (VAES); CHECK_CPU_FEATURE (VPCLMULQDQ); CHECK_CPU_FEATURE (AVX512_VNNI); CHECK_CPU_FEATURE (AVX512_BITALG); CHECK_CPU_FEATURE (AVX512_VPOPCNTDQ); CHECK_CPU_FEATURE (RDPID); CHECK_CPU_FEATURE (CLDEMOTE); CHECK_CPU_FEATURE (MOVDIRI); CHECK_CPU_FEATURE (MOVDIR64B); CHECK_CPU_FEATURE (SGX_LC); CHECK_CPU_FEATURE (AVX512_4VNNIW); CHECK_CPU_FEATURE (AVX512_4FMAPS); CHECK_CPU_FEATURE (FSRM); CHECK_CPU_FEATURE (PCONFIG); CHECK_CPU_FEATURE (IBT); CHECK_CPU_FEATURE (IBRS_IBPB); CHECK_CPU_FEATURE (STIBP); CHECK_CPU_FEATURE (CAPABILITIES); CHECK_CPU_FEATURE (SSBD); CHECK_CPU_FEATURE (LAHF64_SAHF64); CHECK_CPU_FEATURE (SVM); CHECK_CPU_FEATURE (LZCNT); CHECK_CPU_FEATURE (SSE4A); CHECK_CPU_FEATURE (PREFETCHW); CHECK_CPU_FEATURE (XOP); CHECK_CPU_FEATURE (LWP); CHECK_CPU_FEATURE (FMA4); CHECK_CPU_FEATURE (TBM); CHECK_CPU_FEATURE (SYSCALL_SYSRET); CHECK_CPU_FEATURE (NX); CHECK_CPU_FEATURE (PAGE1GB); CHECK_CPU_FEATURE (RDTSCP); CHECK_CPU_FEATURE (LM); CHECK_CPU_FEATURE (XSAVEOPT); CHECK_CPU_FEATURE (XSAVEC); CHECK_CPU_FEATURE (XGETBV_ECX_1); CHECK_CPU_FEATURE (XSAVES); CHECK_CPU_FEATURE (INVARIANT_TSC); CHECK_CPU_FEATURE (WBNOINVD); printf ("Usable CPU features:\n"); CHECK_CPU_FEATURE_USABLE (SSE3); CHECK_CPU_FEATURE_USABLE (PCLMULQDQ); CHECK_CPU_FEATURE_USABLE (SSSE3); CHECK_CPU_FEATURE_USABLE (FMA); CHECK_CPU_FEATURE_USABLE (CMPXCHG16B); CHECK_CPU_FEATURE_USABLE (SSE4_1); CHECK_CPU_FEATURE_USABLE (SSE4_2); CHECK_CPU_FEATURE_USABLE (MOVBE); CHECK_CPU_FEATURE_USABLE (POPCNT); CHECK_CPU_FEATURE_USABLE (AES); CHECK_CPU_FEATURE_USABLE (XSAVE); CHECK_CPU_FEATURE_USABLE (OSXSAVE); CHECK_CPU_FEATURE_USABLE (AVX); CHECK_CPU_FEATURE_USABLE (F16C); CHECK_CPU_FEATURE_USABLE (RDRAND); CHECK_CPU_FEATURE_USABLE (FPU); CHECK_CPU_FEATURE_USABLE (TSC); CHECK_CPU_FEATURE_USABLE (MSR); CHECK_CPU_FEATURE_USABLE (CX8); CHECK_CPU_FEATURE_USABLE (SEP); CHECK_CPU_FEATURE_USABLE (CMOV); CHECK_CPU_FEATURE_USABLE (CLFSH); CHECK_CPU_FEATURE_USABLE (MMX); CHECK_CPU_FEATURE_USABLE (FXSR); CHECK_CPU_FEATURE_USABLE (SSE); CHECK_CPU_FEATURE_USABLE (SSE2); CHECK_CPU_FEATURE_USABLE (FSGSBASE); CHECK_CPU_FEATURE_USABLE (BMI1); CHECK_CPU_FEATURE_USABLE (HLE); CHECK_CPU_FEATURE_USABLE (AVX2); CHECK_CPU_FEATURE_USABLE (BMI2); CHECK_CPU_FEATURE_USABLE (ERMS); CHECK_CPU_FEATURE_USABLE (AVX512F); CHECK_CPU_FEATURE_USABLE (AVX512DQ); CHECK_CPU_FEATURE_USABLE (RDSEED); CHECK_CPU_FEATURE_USABLE (ADX); CHECK_CPU_FEATURE_USABLE (AVX512_IFMA); CHECK_CPU_FEATURE_USABLE (CLFLUSHOPT); CHECK_CPU_FEATURE_USABLE (CLWB); CHECK_CPU_FEATURE_USABLE (AVX512PF); CHECK_CPU_FEATURE_USABLE (AVX512ER); CHECK_CPU_FEATURE_USABLE (AVX512CD); CHECK_CPU_FEATURE_USABLE (SHA); CHECK_CPU_FEATURE_USABLE (AVX512BW); CHECK_CPU_FEATURE_USABLE (AVX512VL); CHECK_CPU_FEATURE_USABLE (PREFETCHWT1); CHECK_CPU_FEATURE_USABLE (AVX512_VBMI); CHECK_CPU_FEATURE_USABLE (AVX512_VBMI2); CHECK_CPU_FEATURE_USABLE (GFNI); CHECK_CPU_FEATURE_USABLE (VAES); CHECK_CPU_FEATURE_USABLE (VPCLMULQDQ); CHECK_CPU_FEATURE_USABLE (AVX512_VNNI); CHECK_CPU_FEATURE_USABLE (AVX512_BITALG); CHECK_CPU_FEATURE_USABLE (AVX512_VPOPCNTDQ); CHECK_CPU_FEATURE_USABLE (RDPID); CHECK_CPU_FEATURE_USABLE (CLDEMOTE); CHECK_CPU_FEATURE_USABLE (MOVDIRI); CHECK_CPU_FEATURE_USABLE (MOVDIR64B); CHECK_CPU_FEATURE_USABLE (AVX512_4VNNIW); CHECK_CPU_FEATURE_USABLE (AVX512_4FMAPS); CHECK_CPU_FEATURE_USABLE (FSRM); CHECK_CPU_FEATURE_USABLE (LAHF64_SAHF64); CHECK_CPU_FEATURE_USABLE (LZCNT); CHECK_CPU_FEATURE_USABLE (SSE4A); CHECK_CPU_FEATURE_USABLE (PREFETCHW); CHECK_CPU_FEATURE_USABLE (XOP); CHECK_CPU_FEATURE_USABLE (FMA4); CHECK_CPU_FEATURE_USABLE (TBM); CHECK_CPU_FEATURE_USABLE (SYSCALL_SYSRET); CHECK_CPU_FEATURE_USABLE (RDTSCP); CHECK_CPU_FEATURE_USABLE (XSAVEOPT); CHECK_CPU_FEATURE_USABLE (XSAVEC); CHECK_CPU_FEATURE_USABLE (XGETBV_ECX_1); CHECK_CPU_FEATURE_USABLE (XSAVES); CHECK_CPU_FEATURE_USABLE (INVARIANT_TSC); CHECK_CPU_FEATURE_USABLE (WBNOINVD); return 0; }
/* Check allocation failures for int arrays (without an element free function). */ static void test_int_fail (void) { /* Exercise failure in add/emplace. do_add: Use emplace (false) or add (true) to add elements. do_finalize: Perform finalization at the end (instead of free). */ for (int do_add = 0; do_add < 2; ++do_add) for (int do_finalize = 0; do_finalize < 2; ++do_finalize) { struct dynarray_int dyn; dynarray_int_init (&dyn); size_t count = 0; while (true) { if (do_add) { dynarray_int_add (&dyn, 0); if (dynarray_int_has_failed (&dyn)) break; } else { int *place = dynarray_int_emplace (&dyn); if (place == NULL) break; TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); *place = 0; } ++count; } printf ("info: %s: failure after %zu elements\n", __func__, count); TEST_VERIFY_EXIT (dynarray_int_has_failed (&dyn)); if (do_finalize) { struct int_array result = { (int *) (uintptr_t) -1, -1 }; TEST_VERIFY_EXIT (!dynarray_int_finalize (&dyn, &result)); TEST_VERIFY_EXIT (result.array == (int *) (uintptr_t) -1); TEST_VERIFY_EXIT (result.length == (size_t) -1); } else dynarray_int_free (&dyn); CHECK_INIT_STATE (int, &dyn); } /* Exercise failure in finalize. */ for (int do_add = 0; do_add < 2; ++do_add) { struct dynarray_int dyn; dynarray_int_init (&dyn); for (unsigned int i = 0; i < 10000; ++i) { if (do_add) { dynarray_int_add (&dyn, i); TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); } else { int *place = dynarray_int_emplace (&dyn); TEST_VERIFY_EXIT (place != NULL); *place = i; } } TEST_VERIFY_EXIT (!dynarray_int_has_failed (&dyn)); struct heap_filler *heap_filler = fill_heap (); struct int_array result = { (int *) (uintptr_t) -1, -1 }; TEST_VERIFY_EXIT (!dynarray_int_finalize (&dyn, &result)); TEST_VERIFY_EXIT (result.array == (int *) (uintptr_t) -1); TEST_VERIFY_EXIT (result.length == (size_t) -1); CHECK_INIT_STATE (int, &dyn); free_fill_heap (heap_filler); } /* Exercise failure in resize. */ { struct dynarray_int dyn; dynarray_int_init (&dyn); struct heap_filler *heap_filler = fill_heap (); TEST_VERIFY (!dynarray_int_resize (&dyn, 1000)); TEST_VERIFY (dynarray_int_has_failed (&dyn)); free_fill_heap (heap_filler); dynarray_int_init (&dyn); TEST_VERIFY (dynarray_int_resize (&dyn, 1)); heap_filler = fill_heap (); TEST_VERIFY (!dynarray_int_resize (&dyn, 1000)); TEST_VERIFY (dynarray_int_has_failed (&dyn)); free_fill_heap (heap_filler); dynarray_int_init (&dyn); TEST_VERIFY (dynarray_int_resize (&dyn, 1000)); heap_filler = fill_heap (); TEST_VERIFY (!dynarray_int_resize (&dyn, 2000)); TEST_VERIFY (dynarray_int_has_failed (&dyn)); free_fill_heap (heap_filler); } }
/* Check allocation failures for char * arrays (which automatically free the pointed-to strings). */ static void test_str_fail (void) { /* Exercise failure in add/emplace. do_add: Use emplace (false) or add (true) to add elements. do_finalize: Perform finalization at the end (instead of free). */ for (int do_add = 0; do_add < 2; ++do_add) for (int do_finalize = 0; do_finalize < 2; ++do_finalize) { struct dynarray_str dyn; dynarray_str_init (&dyn); size_t count = 0; while (true) { char **place; if (do_add) { dynarray_str_add (&dyn, NULL); if (dynarray_str_has_failed (&dyn)) break; else place = dynarray_str_at (&dyn, dynarray_str_size (&dyn) - 1); } else { place = dynarray_str_emplace (&dyn); if (place == NULL) break; } TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); TEST_VERIFY_EXIT (*place == NULL); *place = strdup ("placeholder"); if (*place == NULL) { /* Second loop to wait for failure of dynarray_str_emplace. */ while (true) { if (do_add) { dynarray_str_add (&dyn, NULL); if (dynarray_str_has_failed (&dyn)) break; } else { char **place = dynarray_str_emplace (&dyn); if (place == NULL) break; TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); *place = NULL; } ++count; } break; } ++count; } printf ("info: %s: failure after %zu elements\n", __func__, count); TEST_VERIFY_EXIT (dynarray_str_has_failed (&dyn)); if (do_finalize) { struct str_array result = { (char **) (uintptr_t) -1, -1 }; TEST_VERIFY_EXIT (!dynarray_str_finalize (&dyn, &result)); TEST_VERIFY_EXIT (result.array == (char **) (uintptr_t) -1); TEST_VERIFY_EXIT (result.length == (size_t) -1); } else dynarray_str_free (&dyn); TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch); TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0); TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0); } /* Exercise failure in finalize. */ for (int do_add = 0; do_add < 2; ++do_add) { struct dynarray_str dyn; dynarray_str_init (&dyn); for (unsigned int i = 0; i < 1000; ++i) { if (do_add) dynarray_str_add (&dyn, xstrdup ("placeholder")); else { char **place = dynarray_str_emplace (&dyn); TEST_VERIFY_EXIT (place != NULL); TEST_VERIFY_EXIT (*place == NULL); *place = xstrdup ("placeholder"); } } TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); struct heap_filler *heap_filler = fill_heap (); struct str_array result = { (char **) (uintptr_t) -1, -1 }; TEST_VERIFY_EXIT (!dynarray_str_finalize (&dyn, &result)); TEST_VERIFY_EXIT (result.array == (char **) (uintptr_t) -1); TEST_VERIFY_EXIT (result.length == (size_t) -1); TEST_VERIFY_EXIT (!dynarray_str_has_failed (&dyn)); TEST_VERIFY_EXIT (dyn.dynarray_header.array == dyn.scratch); TEST_VERIFY_EXIT (dynarray_str_size (&dyn) == 0); TEST_VERIFY_EXIT (dyn.dynarray_header.allocated > 0); free_fill_heap (heap_filler); } /* Exercise failure in resize. */ { struct dynarray_str dyn; dynarray_str_init (&dyn); struct heap_filler *heap_filler = fill_heap (); TEST_VERIFY (!dynarray_str_resize (&dyn, 1000)); TEST_VERIFY (dynarray_str_has_failed (&dyn)); free_fill_heap (heap_filler); dynarray_str_init (&dyn); TEST_VERIFY (dynarray_str_resize (&dyn, 1)); *dynarray_str_at (&dyn, 0) = xstrdup ("allocated"); heap_filler = fill_heap (); TEST_VERIFY (!dynarray_str_resize (&dyn, 1000)); TEST_VERIFY (dynarray_str_has_failed (&dyn)); free_fill_heap (heap_filler); dynarray_str_init (&dyn); TEST_VERIFY (dynarray_str_resize (&dyn, 1000)); *dynarray_str_at (&dyn, 0) = xstrdup ("allocated"); heap_filler = fill_heap (); TEST_VERIFY (!dynarray_str_resize (&dyn, 2000)); TEST_VERIFY (dynarray_str_has_failed (&dyn)); free_fill_heap (heap_filler); } }
static void do_prepare (int argc, char **argv) { temp_fd = create_temp_file ("tst-ofdlocks.", &temp_filename); TEST_VERIFY_EXIT (temp_fd != -1); }
static int do_test (void) { mtrace (); char *temp_file; TEST_VERIFY_EXIT (create_temp_file ("tst-bz22145.", &temp_file)); char buf[BUFSIZ]; { /* Check if backup buffer is correctly freed and changing back to normal buffer does not trigger an invalid free in case of static buffer set by setvbuf. */ FILE *f = fopen (temp_file, "w+b"); TEST_VERIFY_EXIT (f != NULL); TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); TEST_VERIFY_EXIT (ungetc ('x', f) == 'x'); TEST_VERIFY_EXIT (fseek (f, 0L, SEEK_SET) == 0); TEST_VERIFY_EXIT (fputc ('y', f) == 'y'); TEST_VERIFY_EXIT (fclose (f) == 0); } { /* Check if backup buffer is correctly freed and changing back to normal buffer does not trigger an invalid free in case of static buffer set by setvbuf. */ FILE *f = fopen (temp_file, "w+b"); TEST_VERIFY_EXIT (f != NULL); TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); TEST_VERIFY_EXIT (ungetc ('x', f) == 'x'); TEST_VERIFY_EXIT (fputc ('y', f) == 'y'); TEST_VERIFY_EXIT (fclose (f) == 0); } { FILE *f = fopen (temp_file, "w+b"); TEST_VERIFY_EXIT (f != NULL); TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); TEST_VERIFY_EXIT (ungetwc (L'x', f) == L'x'); TEST_VERIFY_EXIT (fseek (f, 0L, SEEK_SET) == 0); TEST_VERIFY_EXIT (fputwc (L'y', f) == L'y'); TEST_VERIFY_EXIT (fclose (f) == 0); } { FILE *f = fopen (temp_file, "w+b"); TEST_VERIFY_EXIT (f != NULL); TEST_VERIFY_EXIT (setvbuf (f, buf, _IOFBF, BUFSIZ) == 0); TEST_VERIFY_EXIT (ungetwc (L'x', f) == L'x'); TEST_VERIFY_EXIT (fputwc (L'y', f) == L'y'); TEST_VERIFY_EXIT (fclose (f) == 0); } free (temp_file); return 0; }