/ tests / strlcat.c
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  }