Skip to content

Commit 7d4984f

Browse files
committed
C library: Implement strcat, strncat
1 parent 85193a0 commit 7d4984f

File tree

3 files changed

+70
-17
lines changed

3 files changed

+70
-17
lines changed

regression/cbmc/strcat1/main.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <string.h>
2+
#include <assert.h>
3+
4+
int main()
5+
{
6+
char A1[5] = {'a', 'b', '\0'};
7+
char B1[3] = {'c', 'd', '\0'};
8+
9+
strcat(A1, B1);
10+
assert(A1[3] == 'd');
11+
assert(strlen(A1) == 4);
12+
13+
char A2[5] = {'a', 'b', '\0'};
14+
char B2[3] = {'c', 'd', '\0'};
15+
16+
strncat(A2, B2, 2);
17+
assert(A2[3] == 'd');
18+
assert(strlen(A2) == 4);
19+
20+
char A3[5] = {'a', 'b', '\0'};
21+
char B3[3] = {'c', 'd', '\0'};
22+
23+
strncat(A3, B3, 1);
24+
assert(A3[3] == '\0');
25+
assert(strlen(A3) == 4); // expected to fail
26+
27+
return 0;
28+
}

regression/cbmc/strcat1/test.desc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
CORE
2+
main.c
3+
--unwind 10
4+
^EXIT=10$
5+
^SIGNAL=0$
6+
^VERIFICATION FAILED$
7+
\[main.assertion.6\] assertion strlen\(A3\) == 4: FAILURE
8+
\*\* 1 of 8 failed
9+
--
10+
^warning: ignoring

src/ansi-c/library/string.c

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,13 @@ __inline char *__builtin___strcat_chk(char *dst, const char *src, __CPROVER_size
5252
while(dst[i]!=0) i++;
5353

5454
__CPROVER_size_t j=0;
55-
char ch;
56-
do
55+
char ch = 1;
56+
for(; i < s && ch != (char)0; ++i, ++j)
5757
{
5858
ch=src[j];
5959
dst[i]=ch;
60-
i++;
61-
j++;
6260
}
63-
while(i<s && ch!=(char)0);
61+
dst[i] = '\0';
6462
#endif
6563
return dst;
6664
}
@@ -90,10 +88,19 @@ __inline char *__builtin___strncat_chk(
9088
#else
9189
__CPROVER_assert(__CPROVER_POINTER_OBJECT(dst)!=
9290
__CPROVER_POINTER_OBJECT(src), "strncat src/dst overlap");
93-
(void)*dst;
94-
(void)*src;
95-
(void)n;
96-
(void)s;
91+
92+
__CPROVER_size_t i = 0;
93+
while(dst[i] != 0)
94+
i++;
95+
96+
__CPROVER_size_t j = 0;
97+
char ch = 1;
98+
for(; i < s && j < n && ch != (char)0; ++i, ++j)
99+
{
100+
ch = src[j];
101+
dst[i] = ch;
102+
}
103+
dst[i] = '\0';
97104
#endif
98105
return dst;
99106
}
@@ -236,15 +243,13 @@ inline char *strcat(char *dst, const char *src)
236243
while(dst[i]!=0) i++;
237244

238245
__CPROVER_size_t j=0;
239-
char ch;
240-
do
246+
char ch = 1;
247+
for(; ch != (char)0; ++i, ++j)
241248
{
242249
ch=src[j];
243250
dst[i]=ch;
244-
i++;
245-
j++;
246251
}
247-
while(ch!=(char)0);
252+
dst[i] = '\0';
248253
#endif
249254
return dst;
250255
}
@@ -279,9 +284,19 @@ inline char *strncat(char *dst, const char *src, size_t n)
279284
#else
280285
__CPROVER_assert(__CPROVER_POINTER_OBJECT(dst)!=
281286
__CPROVER_POINTER_OBJECT(src), "strncat src/dst overlap");
282-
(void)*dst;
283-
(void)*src;
284-
(void)n;
287+
288+
__CPROVER_size_t i = 0;
289+
while(dst[i] != 0)
290+
i++;
291+
292+
__CPROVER_size_t j = 0;
293+
char ch = 1;
294+
for(; j < n && ch != (char)0; ++i, ++j)
295+
{
296+
ch = src[j];
297+
dst[i] = ch;
298+
}
299+
dst[i] = '\0';
285300
#endif
286301
return dst;
287302
}

0 commit comments

Comments
 (0)