__inline char *__builtin___strncat_chk( char *dst, const char *src, __CPROVER_size_t n, __CPROVER_size_t s) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_size_t additional, new_size; __CPROVER_assert(__CPROVER_is_zero_string(dst), "strncat zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(src) || __CPROVER_buffer_size(src)>=n, "strncat zero-termination of 2nd argument"); __CPROVER_assert(__CPROVER_buffer_size(dst)==s, "builtin object size"); additional=(n<__CPROVER_zero_string_length(src))?n:__CPROVER_zero_string_length(src); new_size=__CPROVER_is_zero_string(dst)+additional; __CPROVER_assert(__CPROVER_buffer_size(dst)>new_size, "strncat buffer overflow"); __CPROVER_size_t dest_len=__CPROVER_zero_string_length(dst); __CPROVER_size_t i; for (i = 0 ; i < n && i<__CPROVER_zero_string_length(src) ; i++) dst[dest_len + i] = src[i]; dst[dest_len + i] = 0; __CPROVER_is_zero_string(dst)=1; __CPROVER_zero_string_length(dst)=new_size; #else __CPROVER_assert(__CPROVER_POINTER_OBJECT(dst)!= __CPROVER_POINTER_OBJECT(src), "strncat src/dst overlap"); (void)*dst; (void)*src; (void)n; (void)s; #endif return dst; }
inline char *__builtin___strncpy_chk(char *dst, const char *src, size_t n, size_t object_size) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(src), "strncpy zero-termination of 2nd argument"); __CPROVER_assert(__CPROVER_buffer_size(dst)>=n, "strncpy buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(dst)==object_size, "builtin object size"); __CPROVER_is_zero_string(dst)=__CPROVER_zero_string_length(src)<n; __CPROVER_zero_string_length(dst)=__CPROVER_zero_string_length(src); #else __CPROVER_assert(__CPROVER_POINTER_OBJECT(dst)!= __CPROVER_POINTER_OBJECT(src), "strncpy src/dst overlap"); __CPROVER_size_t i=0; char ch; _Bool end; (void)object_size; // We use a single loop to make bounds checking etc easier. // Note that strncpy _always_ writes 'n' characters into 'dst'. for(end=0; i<n; i++) { ch=end?0:src[i]; dst[i]=ch; end=end || ch==(char)0; } #endif return dst; }
void *__builtin___memcpy_chk(void *dst, const void *src, __CPROVER_size_t n, __CPROVER_size_t size) { __CPROVER_HIDE: #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_buffer_size(src)>=n, "memcpy buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(dst)>=n, "memcpy buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(dst)==s, "builtin object size"); // for(size_t i=0; i<n ; i++) dst[i]=src[i]; if(__CPROVER_is_zero_string(src) && n > __CPROVER_zero_string_length(src)) { __CPROVER_is_zero_string(dst)=1; __CPROVER_zero_string_length(dst)=__CPROVER_zero_string_length(src); } else if(!(__CPROVER_is_zero_string(dst) && n <= __CPROVER_zero_string_length(dst))) __CPROVER_is_zero_string(dst)=0; #else __CPROVER_assert(__CPROVER_POINTER_OBJECT(dst)!= __CPROVER_POINTER_OBJECT(src), "memcpy src/dst overlap"); (void)size; //for(__CPROVER_size_t i=0; i<n ; i++) ((char *)dst)[i]=((const char *)src)[i]; char src_n[n]; __CPROVER_array_copy(src_n, (char*)src); __CPROVER_array_replace((char*)dst, src_n); #endif return dst; }
void *__builtin___memset_chk(void *s, int c, __CPROVER_size_t n, __CPROVER_size_t size) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_buffer_size(s)>=n, "memset buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(s)==size, "builtin object size"); // for(size_t i=0; i<n ; i++) s[i]=c; if(__CPROVER_is_zero_string(s) && n > __CPROVER_zero_string_length(s)) { __CPROVER_is_zero_string(s)=1; } else if(c==0) { __CPROVER_is_zero_string(s)=1; __CPROVER_zero_string_length(s)=0; } else __CPROVER_is_zero_string(s)=0; #else (void)size; //char *sp=s; //for(__CPROVER_size_t i=0; i<n ; i++) sp[i]=c; unsigned char s_n[n]; __CPROVER_array_set(s_n, (unsigned char)c); __CPROVER_array_replace((unsigned char*)s, s_n); #endif return s; }
inline int strncmp(const char *s1, const char *s2, size_t n) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(s1) || __CPROVER_buffer_size(s1)>=n, "strncmp zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(s2) || __CPROVER_buffer_size(s2)>=n, "strncmp zero-termination of 2nd argument"); #else __CPROVER_size_t i=0; unsigned char ch1, ch2; do { ch1=s1[i]; ch2=s2[i]; if(ch1==ch2) { } else if(ch1<ch2) return -1; else return 1; i++; } while(ch1!=0 && ch2!=0 && i<n); return 0; #endif }
inline int strncasecmp(const char *s1, const char *s2, size_t n) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION int retval; __CPROVER_assert(__CPROVER_is_zero_string(s1), "strncasecmp zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(s2), "strncasecmp zero-termination of 2nd argument"); return retval; #else __CPROVER_size_t i=0; unsigned char ch1, ch2; do { ch1=s1[i]; ch2=s2[i]; if(ch1>='A' && ch1<='Z') ch1+=('a'-'A'); if(ch2>='A' && ch2<='Z') ch2+=('a'-'A'); if(ch1==ch2) { } else if(ch1<ch2) return -1; else return 1; i++; } while(ch1!=0 && ch2!=0 && i<n); return 0; #endif }
inline int strcmp(const char *s1, const char *s2) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION int retval; __CPROVER_assert(__CPROVER_is_zero_string(s1), "strcmp zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(s2), "strcmp zero-termination of 2nd argument"); if(__CPROVER_zero_string_length(s1) != __CPROVER_zero_string_length(s2)) __CPROVER_assume(retval!=0); return retval; #else __CPROVER_size_t i=0; unsigned char ch1, ch2; do { ch1=s1[i]; ch2=s2[i]; if(ch1==ch2) { } else if(ch1<ch2) return -1; else return 1; i++; } while(ch1!=0 && ch2!=0); return 0; #endif }
inline char *strcat(char *dst, const char *src) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_size_t new_size; __CPROVER_assert(__CPROVER_is_zero_string(dst), "strcat zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(src), "strcat zero-termination of 2nd argument"); new_size=__CPROVER_zero_string_length(dst)+__CPROVER_zero_string_length(src); __CPROVER_assert(__CPROVER_buffer_size(dst)>new_size, "strcat buffer overflow"); __CPROVER_size_t old_size=__CPROVER_zero_string_length(dst); //" for(size_t i=0; i<__CPROVER_zero_string_length(src); i++) //" dst[old_size+i]; dst[new_size]=0; __CPROVER_is_zero_string(dst)=1; __CPROVER_zero_string_length(dst)=new_size; #else __CPROVER_assert(__CPROVER_POINTER_OBJECT(dst)!= __CPROVER_POINTER_OBJECT(src), "strcat src/dst overlap"); __CPROVER_size_t i=0; while(dst[i]!=0) i++; __CPROVER_size_t j=0; char ch; do { ch=src[j]; dst[i]=ch; i++; j++; } while(ch!=(char)0); #endif return dst; }
inline char *__builtin___strcpy_chk(char *dst, const char *src, __CPROVER_size_t s) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(src), "strcpy zero-termination of 2nd argument"); __CPROVER_assert(__CPROVER_buffer_size(dst)>__CPROVER_zero_string_length(src), "strcpy buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(dst)==s, "builtin object size"); dst[__CPROVER_zero_string_length(src)]=0; __CPROVER_is_zero_string(dst)=1; __CPROVER_zero_string_length(dst)=__CPROVER_zero_string_length(src); #else __CPROVER_assert(__CPROVER_POINTER_OBJECT(dst)!= __CPROVER_POINTER_OBJECT(src), "strcpy src/dst overlap"); __CPROVER_size_t i=0; char ch; do { ch=src[i]; dst[i]=ch; i++; } while(i<s && ch!=(char)0); #endif return dst; }
inline FILE *fopen(const char *filename, const char *mode) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(filename), "fopen zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(mode), "fopen zero-termination of 2nd argument"); #endif FILE *f=malloc(sizeof(FILE)); return f; }
int main() { char * x; char * y; char * z; x = (void*) 0; __CPROVER_assume(__CPROVER_is_zero_string(x)); y = "bla"; z = (char*) 0; __CPROVER_assume(__CPROVER_is_zero_string(z)); assert(__CPROVER_is_zero_string(x)); assert(__CPROVER_is_zero_string(y)); assert(__CPROVER_is_zero_string(x)); return 0; }
inline char *fgets(char *str, int size, FILE *stream) { __CPROVER_HIDE:; __CPROVER_bool error; (void)size; (void)*stream; #ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS __CPROVER_assert(__CPROVER_get_must(stream, "open"), "fgets file must be open"); #endif #ifdef __CPROVER_STRING_ABSTRACTION int resulting_size; __CPROVER_assert(__CPROVER_buffer_size(str)>=size, "buffer-overflow in fgets"); if(size>0) { __CPROVER_assume(resulting_size<size); __CPROVER_is_zero_string(str)=!error; __CPROVER_zero_string_length(str)=resulting_size; } #endif return error?0:str; }
void unlink(const char *s) { __CPROVER_hide:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(s), "unlink zero-termination"); #endif }
str_struct_t * foo() { str_struct_t * retval; retval = malloc(sizeof(str_struct_t)); retval->str = malloc(2); retval->str[1] = 0; __CPROVER_is_zero_string(retval->str) = 1; return retval; }
int main(int argc, char* argv[]) { char dest[10]; __CPROVER_assert(__CPROVER_buffer_size(dest) == 10, "CBMC failed to track char array size"); dest[9] = '\0'; __CPROVER_assert(__CPROVER_is_zero_string(dest), "CBMC failed to track char array (2)"); return 0; }
int fputs(const char *s, FILE *stream) { // just return nondet int return_value; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(s), "fputs zero-termination of 1st argument"); #endif *stream; return return_value; }
int unlink(const char *s) { __CPROVER_HIDE:; (void)*s; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(s), "unlink zero-termination"); #endif int retval; return retval; }
inline long atol(const char *nptr) { __CPROVER_HIDE:; long res; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(nptr), "zero-termination of argument of atol"); #endif return res; }
void *memmove(void *dest, const void *src, size_t n) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_buffer_size(src)>=n, "memmove buffer overflow"); // dst = src (with overlap allowed) if(__CPROVER_is_zero_string(src) && n > __CPROVER_zero_string_length(src)) { __CPROVER_is_zero_string(src)=1; __CPROVER_zero_string_length(dest)=__CPROVER_zero_string_length(src); } else __CPROVER_is_zero_string(dest)=0; #else char src_n[n]; __CPROVER_array_copy(src_n, (char*)src); __CPROVER_array_replace((char*)dest, src_n); #endif return dest; }
inline int getopt(int argc, char * const argv[], const char *optstring) { __CPROVER_HIDE:; unsigned result_index; __CPROVER_assume(result_index<argc); #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(optstring), "getopt zero-termination of 3rd argument"); #endif optarg = argv[result_index]; }
inline void *memcpy(void *dst, const void *src, size_t n) { __CPROVER_HIDE: #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_buffer_size(src)>=n, "memcpy buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(dst)>=n, "memcpy buffer overflow"); // for(size_t i=0; i<n ; i++) dst[i]=src[i]; if(__CPROVER_is_zero_string(src) && n > __CPROVER_zero_string_length(src)) { __CPROVER_is_zero_string(dst)=1; __CPROVER_zero_string_length(dst)=__CPROVER_zero_string_length(src); } else if(!(__CPROVER_is_zero_string(dst) && n <= __CPROVER_zero_string_length(dst))) __CPROVER_is_zero_string(dst)=0; #else for(__CPROVER_size_t i=0; i<n ; i++) ((char *)dst)[i]=((const char *)src)[i]; #endif return dst; }
inline size_t strlen(const char *s) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(s), "strlen zero-termination"); return __CPROVER_zero_string_length(s); #else __CPROVER_size_t len=0; while(s[len]!=0) len++; return len; #endif }
inline int strcasecmp(const char *s1, const char *s2) { __CPROVER_HIDE:; #if !defined(__linux__) || defined(__GLIBC__) if(s1!=0 && s1==s2) return 0; #else // musl guarantees non-null of s1 if(s1==s2) return 0; #endif #ifdef __CPROVER_STRING_ABSTRACTION int retval; __CPROVER_assert(__CPROVER_is_zero_string(s1), "strcasecmp zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(s2), "strcasecmp zero-termination of 2nd argument"); if(__CPROVER_zero_string_length(s1) != __CPROVER_zero_string_length(s2)) __CPROVER_assume(retval!=0); return retval; #else __CPROVER_size_t i=0; unsigned char ch1, ch2; do { ch1=s1[i]; ch2=s2[i]; if(ch1>='A' && ch1<='Z') ch1+=('a'-'A'); if(ch2>='A' && ch2<='Z') ch2+=('a'-'A'); if(ch1==ch2) { } else if(ch1<ch2) return -1; else return 1; i++; } while(ch1!=0 && ch2!=0); return 0; #endif }
inline char *strcpy(char *dst, const char *src) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(src), "strcpy zero-termination of 2nd argument"); __CPROVER_assert(__CPROVER_buffer_size(dst)>__CPROVER_zero_string_length(src), "strcpy buffer overflow"); dst[__CPROVER_zero_string_length(src)]=0; __CPROVER_is_zero_string(dst)=1; __CPROVER_zero_string_length(dst)=__CPROVER_zero_string_length(src); #else __CPROVER_size_t i=0; char ch; do { ch=src[i]; dst[i]=ch; i++; } while(ch!=(char)0); #endif return dst; }
inline FILE *fopen(const char *filename, const char *mode) { __CPROVER_HIDE:; (void)*filename; (void)*mode; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(filename), "fopen zero-termination of 1st argument"); __CPROVER_assert(__CPROVER_is_zero_string(mode), "fopen zero-termination of 2nd argument"); #endif FILE *fopen_result; _Bool fopen_error; fopen_result=fopen_error?NULL:malloc(sizeof(FILE)); #ifdef __CPROVER_CUSTOM_BITVECTOR_ANALYSIS __CPROVER_set_must(fopen_result, "open"); __CPROVER_cleanup(fopen_result, fclose_cleanup); #endif return fopen_result; }
char * make_str() { unsigned short len; char * str; __CPROVER_assume(len > 0); str = malloc(len); __CPROVER_assume(__CPROVER_buffer_size(str) == len); str[len - 1] = '\0'; __CPROVER_is_zero_string(str) = 1; __CPROVER_zero_string_length(str) = len - 1; return str; }
inline FILE *fdopen(int handle, const char *mode) { __CPROVER_HIDE:; (void)handle; (void)*mode; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(mode), "fdopen zero-termination of 2nd argument"); #endif FILE *f=malloc(sizeof(FILE)); return f; }
void *__builtin___memcpy_chk(void *dst, const void *src, __CPROVER_size_t n, __CPROVER_size_t size) { __CPROVER_HIDE: #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_buffer_size(src)>=n, "memcpy buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(dst)>=n, "memcpy buffer overflow"); __CPROVER_assert(__CPROVER_buffer_size(dst)==s, "builtin object size"); // for(size_t i=0; i<n ; i++) dst[i]=src[i]; if(__CPROVER_is_zero_string(src) && n > __CPROVER_zero_string_length(src)) { __CPROVER_is_zero_string(dst)=1; __CPROVER_zero_string_length(dst)=__CPROVER_zero_string_length(src); } else if(!(__CPROVER_is_zero_string(dst) && n <= __CPROVER_zero_string_length(dst))) __CPROVER_is_zero_string(dst)=0; #else (void)size; for(__CPROVER_size_t i=0; i<n ; i++) ((char *)dst)[i]=((const char *)src)[i]; #endif return dst; }
void perror(const char *s) { __CPROVER_HIDE:; if(s!=0) { #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_is_zero_string(s), "perror zero-termination"); #endif // should go to stderr if(s[0]!=0) printf("%s: ", s); } // TODO: print errno error }
inline void *memset(void *s, int c, size_t n) { __CPROVER_HIDE:; #ifdef __CPROVER_STRING_ABSTRACTION __CPROVER_assert(__CPROVER_buffer_size(s)>=n, "memset buffer overflow"); // for(size_t i=0; i<n ; i++) s[i]=c; if(__CPROVER_is_zero_string(s) && n > __CPROVER_zero_string_length(s)) { __CPROVER_is_zero_string(s)=1; } else if(c==0) { __CPROVER_is_zero_string(s)=1; __CPROVER_zero_string_length(s)=0; } else __CPROVER_is_zero_string(s)=0; #else char *sp=s; for(__CPROVER_size_t i=0; i<n ; i++) sp[i]=c; #endif return s; }