Skip to content

Commit 16c29aa

Browse files
add atoi() and atol() wrappers
1 parent e0afbb6 commit 16c29aa

File tree

3 files changed

+220
-0
lines changed

3 files changed

+220
-0
lines changed

runtime/LibcWrappers.cpp

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,4 +471,168 @@ uint32_t SYM(strlen)(const char *s) {
471471

472472
return (result - s);
473473
}
474+
475+
int SYM(atoi)(const char *s) {
476+
tryAlternative(s, _sym_get_parameter_expression(0), SYM(strlen));
477+
478+
// HACK! we mimic the libc function summary in klee
479+
/* int atoi(const char *str) {
480+
* return (int)strtol(str, (char **)NULL, 10);
481+
* }
482+
* */
483+
auto result = strtol(s, (char **)NULL, 10);
484+
_sym_set_return_expression(nullptr);
485+
486+
if (isConcrete(s, strlen(s)))
487+
return result;
488+
489+
size_t length = strlen(s);
490+
size_t num_len = 0;
491+
for (size_t i = 0; i < length; i++) {
492+
if ('0' <= (char)s[i] && (char)s[i] <= '9') {
493+
num_len++;
494+
} else {
495+
break;
496+
}
497+
}
498+
auto shadow = ReadOnlyShadow(s, length);
499+
auto shadowIt = shadow.begin();
500+
for (size_t i = 0; i < num_len; i++) {
501+
int res = (char)s[i];
502+
auto *cExpr = _sym_build_integer(res, 8);
503+
_sym_push_path_constraint(
504+
_sym_build_equal(
505+
(*shadowIt != nullptr) ? *shadowIt : _sym_build_integer(s[i], 8),
506+
cExpr),
507+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
508+
++shadowIt;
509+
}
510+
511+
// The value of tail must be non-num
512+
auto *tailExpr_0 = _sym_build_integer(48, 8); // '0'
513+
auto *tailExpr_1 = _sym_build_integer(49, 8); // '1'
514+
auto *tailExpr_2 = _sym_build_integer(50, 8); // '2'
515+
auto *tailExpr_3 = _sym_build_integer(51, 8); // '3'
516+
auto *tailExpr_4 = _sym_build_integer(52, 8); // '4'
517+
auto *tailExpr_5 = _sym_build_integer(53, 8); // '5'
518+
auto *tailExpr_6 = _sym_build_integer(54, 8); // '6'
519+
auto *tailExpr_7 = _sym_build_integer(55, 8); // '7'
520+
auto *tailExpr_8 = _sym_build_integer(56, 8); // '8'
521+
auto *tailExpr_9 = _sym_build_integer(57, 8); // '9'
522+
523+
_sym_push_path_constraint(
524+
_sym_build_not_equal(*shadowIt, tailExpr_0),
525+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
526+
_sym_push_path_constraint(
527+
_sym_build_not_equal(*shadowIt, tailExpr_1),
528+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
529+
_sym_push_path_constraint(
530+
_sym_build_not_equal(*shadowIt, tailExpr_2),
531+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
532+
_sym_push_path_constraint(
533+
_sym_build_not_equal(*shadowIt, tailExpr_3),
534+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
535+
_sym_push_path_constraint(
536+
_sym_build_not_equal(*shadowIt, tailExpr_4),
537+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
538+
_sym_push_path_constraint(
539+
_sym_build_not_equal(*shadowIt, tailExpr_5),
540+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
541+
_sym_push_path_constraint(
542+
_sym_build_not_equal(*shadowIt, tailExpr_6),
543+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
544+
_sym_push_path_constraint(
545+
_sym_build_not_equal(*shadowIt, tailExpr_7),
546+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
547+
_sym_push_path_constraint(
548+
_sym_build_not_equal(*shadowIt, tailExpr_8),
549+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
550+
_sym_push_path_constraint(
551+
_sym_build_not_equal(*shadowIt, tailExpr_9),
552+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
553+
554+
return result;
555+
}
556+
557+
long int SYM(atol)(const char *s) {
558+
tryAlternative(s, _sym_get_parameter_expression(0), SYM(strlen));
559+
560+
// HACK! we mimic the libc function summary in klee
561+
/* int atoi(const char *str) {
562+
* return (int)strtol(str, (char **)NULL, 10);
563+
* }
564+
* */
565+
auto result = strtol(s, (char **)NULL, 10);
566+
_sym_set_return_expression(nullptr);
567+
568+
if (isConcrete(s, strlen(s)))
569+
return result;
570+
571+
size_t length = strlen(s);
572+
size_t num_len = 0;
573+
for (size_t i = 0; i < length; i++) {
574+
if ('0' <= (char)s[i] && (char)s[i] <= '9') {
575+
num_len++;
576+
} else {
577+
break;
578+
}
579+
}
580+
auto shadow = ReadOnlyShadow(s, length);
581+
auto shadowIt = shadow.begin();
582+
for (size_t i = 0; i < num_len; i++) {
583+
int res = (char)s[i];
584+
auto *cExpr = _sym_build_integer(res, 8);
585+
_sym_push_path_constraint(
586+
_sym_build_equal(
587+
(*shadowIt != nullptr) ? *shadowIt : _sym_build_integer(s[i], 8),
588+
cExpr),
589+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
590+
++shadowIt;
591+
}
592+
593+
// The value of tail must be non-num
594+
auto *tailExpr_0 = _sym_build_integer(48, 8); // '0'
595+
auto *tailExpr_1 = _sym_build_integer(49, 8); // '1'
596+
auto *tailExpr_2 = _sym_build_integer(50, 8); // '2'
597+
auto *tailExpr_3 = _sym_build_integer(51, 8); // '3'
598+
auto *tailExpr_4 = _sym_build_integer(52, 8); // '4'
599+
auto *tailExpr_5 = _sym_build_integer(53, 8); // '5'
600+
auto *tailExpr_6 = _sym_build_integer(54, 8); // '6'
601+
auto *tailExpr_7 = _sym_build_integer(55, 8); // '7'
602+
auto *tailExpr_8 = _sym_build_integer(56, 8); // '8'
603+
auto *tailExpr_9 = _sym_build_integer(57, 8); // '9'
604+
605+
_sym_push_path_constraint(
606+
_sym_build_not_equal(*shadowIt, tailExpr_0),
607+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
608+
_sym_push_path_constraint(
609+
_sym_build_not_equal(*shadowIt, tailExpr_1),
610+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
611+
_sym_push_path_constraint(
612+
_sym_build_not_equal(*shadowIt, tailExpr_2),
613+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
614+
_sym_push_path_constraint(
615+
_sym_build_not_equal(*shadowIt, tailExpr_3),
616+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
617+
_sym_push_path_constraint(
618+
_sym_build_not_equal(*shadowIt, tailExpr_4),
619+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
620+
_sym_push_path_constraint(
621+
_sym_build_not_equal(*shadowIt, tailExpr_5),
622+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
623+
_sym_push_path_constraint(
624+
_sym_build_not_equal(*shadowIt, tailExpr_6),
625+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
626+
_sym_push_path_constraint(
627+
_sym_build_not_equal(*shadowIt, tailExpr_7),
628+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
629+
_sym_push_path_constraint(
630+
_sym_build_not_equal(*shadowIt, tailExpr_8),
631+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
632+
_sym_push_path_constraint(
633+
_sym_build_not_equal(*shadowIt, tailExpr_9),
634+
/*taken*/ 1, reinterpret_cast<uintptr_t>(SYM(strchr)));
635+
636+
return result;
637+
}
474638
}

runtime/test_wrappers/test_atoi.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <stdarg.h>
4+
#include <stdlib.h>
5+
#include <stdint.h>
6+
#include <unistd.h>
7+
int main(int argc, char *argv[]) {
8+
9+
char buf[1024];
10+
ssize_t i;
11+
if ((i = read(0, buf, sizeof(buf) - 1)) < 24) return 0;
12+
buf[i] = 0;
13+
if (buf[0] != 'A') return 0;
14+
if (buf[1] != 'B') return 0;
15+
if (buf[2] != 'C') return 0;
16+
if (buf[3] != 'D') return 0;
17+
if (memcmp(buf + 4, "1234", 4) || memcmp(buf + 8, "EFGH", 4)) return 0;
18+
if (atoi(buf + 12) == 678) {
19+
printf("The result of atoi(buf+12) is: %lu\n", atoi(buf+12));
20+
printf("HIT!\n");
21+
} else {
22+
printf("The result of atoi(buf+12) is: %lu\n", atoi(buf+12));
23+
printf("NOT HIT!\n");
24+
}
25+
26+
return 0;
27+
28+
}

runtime/test_wrappers/test_atol.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <stdarg.h>
4+
#include <stdlib.h>
5+
#include <stdint.h>
6+
#include <unistd.h>
7+
int main(int argc, char *argv[]) {
8+
9+
char buf[1024];
10+
ssize_t i;
11+
if ((i = read(0, buf, sizeof(buf) - 1)) < 24) return 0;
12+
buf[i] = 0;
13+
if (buf[0] != 'A') return 0;
14+
if (buf[1] != 'B') return 0;
15+
if (buf[2] != 'C') return 0;
16+
if (buf[3] != 'D') return 0;
17+
if (memcmp(buf + 4, "1234", 4) || memcmp(buf + 8, "EFGH", 4)) return 0;
18+
if (atol(buf + 12) == 99999999) {
19+
printf("The result of atoi(buf+12) is: %lu\n", atol(buf+12));
20+
printf("HIT!\n");
21+
} else {
22+
printf("The result of atoi(buf+12) is: %lu\n", atol(buf+12));
23+
printf("NOT HIT!\n");
24+
}
25+
26+
return 0;
27+
28+
}

0 commit comments

Comments
 (0)