strlcat.c
1 #include <mach/mach_types.h> 2 #include <sys/mman.h> 3 #include <string.h> 4 5 #include <darwintest.h> 6 7 static const char* qbf = "The quick brown fox jumps over the lazy dog"; 8 static const char* lynx = "Lynx c.q. vos prikt bh: dag zwemjuf!"; 9 10 T_DECL(strlcat, "strlcat(3)") 11 { 12 13 void *ptr = mmap(NULL, PAGE_SIZE*2, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); 14 T_ASSERT_NE(ptr, MAP_FAILED, NULL); 15 16 T_ASSERT_POSIX_ZERO(mprotect(ptr+PAGE_SIZE, PAGE_SIZE, PROT_READ), NULL); 17 18 size_t offset = strlen(qbf)+strlen(lynx)+1; 19 char *dst = (ptr+PAGE_SIZE)-offset; 20 strcpy(dst, qbf); 21 22 size_t res = strlcat(dst, lynx, offset); 23 T_ASSERT_EQ(res, offset-1, "strlcat"); 24 T_ASSERT_EQ(memcmp(dst, qbf, strlen(qbf)), 0, NULL); 25 T_ASSERT_EQ(memcmp(dst+strlen(qbf), lynx, strlen(lynx)), 0, NULL); 26 T_ASSERT_EQ(dst[offset], 0, "null-term"); 27 28 memset(ptr, '\0', PAGE_SIZE); 29 30 offset = strlen(qbf)+(strlen(lynx)/2)+1; 31 dst = (ptr+PAGE_SIZE)-offset; 32 strcpy(dst, qbf); 33 34 res = strlcat(dst, lynx, offset); 35 T_ASSERT_EQ(res, strlen(qbf)+strlen(lynx), "strlcat"); 36 T_ASSERT_EQ(memcmp(dst, qbf, strlen(qbf)), 0, NULL); 37 T_ASSERT_EQ(memcmp(dst+strlen(qbf), lynx, offset-strlen(qbf)-1), 0, NULL); 38 T_ASSERT_EQ(*(char*)(ptr+PAGE_SIZE), 0, NULL); 39 T_ASSERT_EQ(dst[offset], 0, "null-term"); 40 41 memset(ptr, '\0', PAGE_SIZE); 42 43 offset = strlen(qbf)-4; 44 dst = (ptr+PAGE_SIZE)-offset; 45 strncpy(dst, qbf, offset); 46 47 res = strlcat(dst, lynx, offset); 48 T_ASSERT_EQ(res, offset+strlen(lynx), "strlcat"); 49 T_ASSERT_EQ(memcmp(dst, qbf, offset), 0, NULL); 50 T_ASSERT_EQ(*(char*)(ptr+PAGE_SIZE), 0, NULL); 51 T_ASSERT_EQ(dst[offset], 0, "null-term"); 52 } 53 54 T_DECL(strlcat_overlap, "strlcat(3) with overlap: PR-20105548") 55 { 56 char buffer[21]; 57 memset(buffer,'x',sizeof(buffer)); 58 buffer[0]='\0'; 59 buffer[20]='\0'; 60 61 char *a = &buffer[0]; 62 char *b = &buffer[10]; 63 strlcat(a,b,10); 64 T_PASS("did not abort"); 65 }