diff --git a/src/plugins/value/domains/cvalue/builtins_string.ml b/src/plugins/value/domains/cvalue/builtins_string.ml index 11ea3c4b8c3c2dbb859f5e7a0d65ec51e9a19184..612559fa56fcba1ecf2ee400c9e1251b01ce24c0 100644 --- a/src/plugins/value/domains/cvalue/builtins_string.ml +++ b/src/plugins/value/domains/cvalue/builtins_string.ml @@ -783,6 +783,8 @@ module Search_single_offset = struct (instead of relative ones) during the fold, and only at the end they are converted into relative bounds. *) try + if Int.(lt offset zero) then + raise (Bottom_val (None, false, IS.bottom, offset)); let acc = Bytecharmap.fold_itv ~direction:`LTR ~entire:false (fun (range_start, range_end) bs acc -> @@ -1194,8 +1196,6 @@ module Search_ranges = struct or [max_offset + max_n] for strnlen. For strnlen, max_byte_to_look may be adjusted by Search_single.search_and_acc to a more precise value. *) - (* [base] is only used to obtain the maximum validity, when the result is - imprecise *) let search bytecharmap ~ret_rel_offs base offset_ival offset_start offset_end ?n_len last_byte_to_look = fpf "@[by_offset_ival: offset_ival: %a, offset_start: %a, offset_end: %a, \ last_byte_to_look: %a@]" Ival.pretty offset_ival Int.pretty offset_start @@ -1226,25 +1226,40 @@ module Search_ranges = struct search_init bytecharmap ?n_len last_byte_to_look offset_end in fpf "search_init returned init_acc = %a" pp_acc init_acc; - let res_acc = - Bytecharmap.fold_itv ~direction:`RTL ~entire:false - (fun (range_start, range_end) bs acc -> - search_rtl range_start range_end bs ?n_len acc - ) (offset_start, (I.pred offset_end)) bytecharmap init_acc + let validity_alarm, valid_itv = + Tr_offset.trim_by_validity + Ival.(mul (of_int 8) offset_ival) + Int.eight (*sizeof(char)*) (Base.validity base) in - fpf "res_acc = %a" pp_acc res_acc; - match res_acc.best_min, res_acc.best_max with - | Some _, Some _ -> - (* for strnlen, adjust bounds according to the [n] argument *) - let (adj_min, adj_max) = - adjust_bounds res_acc.best_min res_acc.best_max n_len + fpf "trim_by_validity (%a, %a) returned = %b, %a" + Int.pretty offset_start Int.pretty offset_end + validity_alarm Tr_offset.pretty valid_itv; + match valid_itv with + | Tr_offset.Invalid -> (* no valid interval *) + let is = { init_acc.is with IS.maybe_indet = true } in + Never_ok is, Not_imprecise + | _ -> + let res_acc = + Bytecharmap.fold_itv ~direction:`RTL ~entire:false + (fun (range_start, range_end) bs acc -> + search_rtl range_start range_end bs ?n_len acc + ) (offset_start, (I.pred offset_end)) bytecharmap init_acc in - Maybe_ok (Ival.inject_range adj_min adj_max, - (*abs_offs not used by caller*)Ival.top, - (*fs not used by caller*)FS.Top, res_acc.maybe_not_found, - res_acc.best_es, res_acc.is), Not_imprecise - | _, _ -> - Never_ok (res_acc.is), Not_imprecise + fpf "res_acc = %a" pp_acc res_acc; + match res_acc.best_min, res_acc.best_max with + | Some _, Some _ -> + (* for strnlen, adjust bounds according to the [n] argument *) + let (adj_min, adj_max) = + adjust_bounds res_acc.best_min res_acc.best_max n_len + in + let maybe_indet = res_acc.is.IS.maybe_indet || validity_alarm in + Maybe_ok (Ival.inject_range adj_min adj_max, + (*abs_offs not used by caller*)Ival.top, + (*fs not used by caller*)FS.Top, res_acc.maybe_not_found, + res_acc.best_es, { res_acc.is with IS.maybe_indet }), + Not_imprecise + | _, _ -> + Never_ok (res_acc.is), Not_imprecise end in res diff --git a/tests/non-free/oracle/strlen.res.oracle b/tests/non-free/oracle/strlen.res.oracle index 9869e40a9dfabac35cc6298e7d771d0c4397e403..c1f907990e19b3c34302cba1c2b758e7a7a221c6 100644 --- a/tests/non-free/oracle/strlen.res.oracle +++ b/tests/non-free/oracle/strlen.res.oracle @@ -32,7 +32,7 @@ [11] ∈ {100} nondet ∈ [--..--] [value] computing for function small_sets <- main. - Called from tests/non-free/strlen.c:309. + Called from tests/non-free/strlen.c:334. tests/non-free/strlen.c:60:[value] Call to builtin Frama_C_strlen(({{ "abc" + {0; 1} }})) tests/non-free/strlen.c:61:[value] assertion got status valid. tests/non-free/strlen.c:65:[value] Call to builtin Frama_C_strlen(({{ "\000bc" + {0; 1} }})) @@ -47,7 +47,7 @@ tests/non-free/strlen.c:82:[value] assertion got status valid. [value] Recording results for small_sets [value] Done for function small_sets [value] computing for function zero_termination <- main. - Called from tests/non-free/strlen.c:310. + Called from tests/non-free/strlen.c:335. tests/non-free/strlen.c:89:[value] Call to builtin Frama_C_strlen(({{ &empty_or_non_terminated[0] }})) tests/non-free/strlen.c:89:[value] warning: builtin Frama_C_strlen: possibly reading indeterminate data tests/non-free/strlen.c:90:[value] assertion got status valid. @@ -58,7 +58,7 @@ tests/non-free/strlen.c:97:[value] warning: builtin Frama_C_strlen: reading inde [value] Recording results for zero_termination [value] Done for function zero_termination [value] computing for function strlen_initialization <- main. - Called from tests/non-free/strlen.c:311. + Called from tests/non-free/strlen.c:336. [value] computing for function my_strlen <- strlen_initialization <- main. Called from tests/non-free/strlen.c:105. tests/non-free/strlen.c:54:[value] Call to builtin Frama_C_strlen(({{ &empty_or_uninitialized[0] }})) @@ -86,7 +86,7 @@ tests/non-free/strlen.c:125:[value] assertion got status valid. [value] Recording results for strlen_initialization [value] Done for function strlen_initialization [value] computing for function strlen_large <- main. - Called from tests/non-free/strlen.c:312. + Called from tests/non-free/strlen.c:337. [value] computing for function init_array_nondet <- strlen_large <- main. Called from tests/non-free/strlen.c:168. tests/non-free/strlen.c:161:[value] Call to builtin memset(({{ (void *)&a }},{1; 2},{100})) @@ -147,7 +147,7 @@ tests/non-free/strlen.c:190:[value] assertion got status valid. [value] Recording results for strlen_large [value] Done for function strlen_large [value] computing for function strlen_large_uninit <- main. - Called from tests/non-free/strlen.c:313. + Called from tests/non-free/strlen.c:338. [value] computing for function init_array_nondet <- strlen_large_uninit <- main. Called from tests/non-free/strlen.c:197. tests/non-free/strlen.c:161:[value] Call to builtin memset(({{ (void *)&a }},{1; 2},{40})) @@ -188,7 +188,7 @@ tests/non-free/strlen.c:213:[value] assertion got status valid. [value] Recording results for strlen_large_uninit [value] Done for function strlen_large_uninit [value] computing for function misc <- main. - Called from tests/non-free/strlen.c:314. + Called from tests/non-free/strlen.c:339. tests/non-free/strlen.c:241:[value] Call to builtin Frama_C_strlen(({{ &unterminated_string[0] }})) tests/non-free/strlen.c:241:[value] warning: builtin Frama_C_strlen: reading indeterminate data tests/non-free/strlen.c:244:[value] Call to builtin Frama_C_strlen(({{ "Hello World\n" ; "Bonjour Monde\n" }})) @@ -229,19 +229,19 @@ tests/non-free/strlen.c:278:[value] assertion got status valid. [value] Recording results for misc [value] Done for function misc [value] computing for function bitfields <- main. - Called from tests/non-free/strlen.c:315. + Called from tests/non-free/strlen.c:340. tests/non-free/strlen.c:140:[value] Call to builtin Frama_C_strlen(({{ (char const *)&s }})) tests/non-free/strlen.c:140:[value] warning: builtin Frama_C_strlen: reading indeterminate data [value] Recording results for bitfields [value] Done for function bitfields [value] computing for function bitfields2 <- main. - Called from tests/non-free/strlen.c:316. + Called from tests/non-free/strlen.c:341. tests/non-free/strlen.c:155:[value] Call to builtin Frama_C_strlen(({{ (char const *)&s }})) tests/non-free/strlen.c:156:[value] assertion got status valid. [value] Recording results for bitfields2 [value] Done for function bitfields2 [value] computing for function escaping <- main. - Called from tests/non-free/strlen.c:317. + Called from tests/non-free/strlen.c:342. tests/non-free/strlen.c:222:[value] warning: locals {x} escaping the scope of a block of escaping through s tests/non-free/strlen.c:225:[value] Call to builtin Frama_C_strlen(({{ &s[0] }})) tests/non-free/strlen.c:225:[value] warning: builtin Frama_C_strlen: possible escaping addresses @@ -251,7 +251,7 @@ tests/non-free/strlen.c:229:[value] assertion got status valid. [value] Recording results for escaping [value] Done for function escaping [value] computing for function big_array <- main. - Called from tests/non-free/strlen.c:318. + Called from tests/non-free/strlen.c:343. tests/non-free/strlen.c:287:[value] warning: out of bounds write. assert \valid(p); tests/non-free/strlen.c:289:[value] warning: out of bounds write. assert \valid(p); tests/non-free/strlen.c:291:[value] warning: out of bounds write. assert \valid(p); @@ -281,6 +281,49 @@ tests/non-free/strlen.c:304:[value] warning: builtin Frama_C_strlen: tests/non-free/strlen.c:305:[value] Frama_C_show_each: {0; 1; 2; 3}, [0..800], [0..3999996] [value] Recording results for big_array [value] Done for function big_array +[value] computing for function negative_offsets <- main. + Called from tests/non-free/strlen.c:344. +tests/non-free/strlen.c:310:[value] entering loop for the first time +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strlen.c:314. +[value] Done for function Frama_C_interval +tests/non-free/strlen.c:315:[value] Call to builtin Frama_C_strlen(({{ &buf{[-10], [-9], [-8]} }})) +tests/non-free/strlen.c:315:[value] warning: builtin Frama_C_strlen: reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strlen.c:318. +[value] Done for function Frama_C_interval +tests/non-free/strlen.c:319:[value] Call to builtin Frama_C_strlen(({{ &buf{[-2], [-1]} }})) +tests/non-free/strlen.c:319:[value] warning: builtin Frama_C_strlen: reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strlen.c:321. +[value] Done for function Frama_C_interval +tests/non-free/strlen.c:322:[value] Call to builtin Frama_C_strlen(({{ &buf{[-1], [0]} }})) +tests/non-free/strlen.c:322:[value] warning: builtin Frama_C_strlen: + possible uninitialized values + possibly reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strlen.c:323. +[value] Done for function Frama_C_interval +tests/non-free/strlen.c:324:[value] Call to builtin Frama_C_strlen(({{ &buf{[-1], [0], [1], [2]} }})) +tests/non-free/strlen.c:324:[value] warning: builtin Frama_C_strlen: + possible uninitialized values + possibly reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strlen.c:325. +[value] Done for function Frama_C_interval +tests/non-free/strlen.c:326:[value] Call to builtin Frama_C_strlen(({{ &buf + [-4..7] }})) +tests/non-free/strlen.c:326:[value] warning: builtin Frama_C_strlen: + possible uninitialized values + possibly reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strlen.c:327. +[value] Done for function Frama_C_interval +tests/non-free/strlen.c:329:[value] Call to builtin Frama_C_strlen(({{ &buf + [-10..0] }})) +tests/non-free/strlen.c:329:[value] warning: builtin Frama_C_strlen: + possible uninitialized values + possibly reading indeterminate data +[value] Recording results for negative_offsets +[value] Done for function negative_offsets [value] Recording results for main [value] done for function main [value] ====== VALUES COMPUTED ====== @@ -348,6 +391,21 @@ tests/non-free/strlen.c:305:[value] Frama_C_show_each: {0; 1; 2; 3}, [0..800], [ [1] ∈ {0} [value:final-states] Values at end of function my_strlen: __retres ∈ [0..54] +[value:final-states] Values at end of function negative_offsets: + Frama_C_entropy_source ∈ [--..--] + buf[0..98] ∈ {65} or UNINITIALIZED + [99] ∈ {0} + len1 ∈ UNINITIALIZED + len2 ∈ UNINITIALIZED + len3 ∈ {99} + len4 ∈ {97; 98; 99} + len5 ∈ {92; 93; 94; 95; 96; 97; 98; 99} + len6 ∈ {99} + offset3 ∈ {-1; 0} + offset4 ∈ {-1; 0; 1; 2} + offset5 ∈ [-4..7] + offset6 ∈ [-10..0] + p ∈ {{ &buf + [-10..0] }} [value:final-states] Values at end of function small_sets: s ∈ {{ "b\000c" }} p ∈ {{ "b\000c" + {0; 2} }} @@ -426,6 +484,8 @@ tests/non-free/strlen.c:305:[value] Frama_C_show_each: {0; 1; 2; 3}, [0..800], [ [from] Done for function misc [from] Computing for function my_strlen [from] Done for function my_strlen +[from] Computing for function negative_offsets +[from] Done for function negative_offsets [from] Computing for function small_sets [from] Done for function small_sets [from] Computing for function strlen_initialization @@ -453,7 +513,7 @@ tests/non-free/strlen.c:305:[value] Frama_C_show_each: {0; 1; 2; 3}, [0..800], [ non_terminated2[2..3]; empty_or_uninitialized[0]; uninitialized[0]; s[0..1]; t[0..3]; s; s; a[3..99]; a[3..99]; s[0..3]; loc_char_array[0..4]; x; maybe_init[0..1]; - t[0..999999]; u[0..199]; r[0..200]; + t[0..999999]; u[0..199]; r[0..200]; buf[0..99]; "Hello World\n"[bits 0 to 103]; "abc\000\000\000abc"[bits 0 to 79]; ""[bits 0 to 7]; "a"[bits 0 to 15]; "aa"[bits 0 to 23]; "aaa"; @@ -492,6 +552,8 @@ tests/non-free/strlen.c:305:[value] Frama_C_show_each: {0; 1; 2; 3}, [0..800], [ "Bonjour Monde\n"[bits 0 to 119]; "abc"; "ABCD"[bits 0 to 39]; "efg"[bits 8 to 31]; "EFGH"[bits 8 to 39]; "mno\000pqr"[bits 0 to 63]; "MNOP\000QRS"[bits 0 to 71] +[from] Function negative_offsets: + Frama_C_entropy_source FROM Frama_C_entropy_source; nondet (and SELF) [from] Function small_sets: NO EFFECTS [from] Function strlen_initialization: @@ -503,7 +565,7 @@ tests/non-free/strlen.c:305:[value] Frama_C_show_each: {0; 1; 2; 3}, [0..800], [ [from] Function zero_termination: NO EFFECTS [from] Function main: - Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) + Frama_C_entropy_source FROM Frama_C_entropy_source; nondet (and SELF) \result FROM \nothing [from] ====== END OF DEPENDENCIES ====== [inout] Out (internal) for function big_array: @@ -546,6 +608,11 @@ tests/non-free/strlen.c:305:[value] Frama_C_show_each: {0; 1; 2; 3}, [0..800], [ [inout] Inputs for function my_strlen: empty_or_uninitialized[0]; uninitialized[0]; s[0..1]; t[0..3]; a[0..99]; a[0..99] +[inout] Out (internal) for function negative_offsets: + Frama_C_entropy_source; buf[0..99]; i; len1; len2; len3; len4; len5; + len6; offset1; offset2; offset3; offset4; offset5; offset6; p +[inout] Inputs for function negative_offsets: + Frama_C_entropy_source; nondet [inout] Out (internal) for function small_sets: s; p; tmp; z1; tmp_0; z2; tmp_1; z3; tmp_2; z4; tmp_3; t[0..3]; z5; tmp_4 [inout] Inputs for function small_sets: diff --git a/tests/non-free/oracle/strnlen2.res.oracle b/tests/non-free/oracle/strnlen2.res.oracle index e6ca5c2a224fa8befbb03cdb19c9f92eb64faf75..d1fb216242b3020a454d59945922e72b26b3eac0 100644 --- a/tests/non-free/oracle/strnlen2.res.oracle +++ b/tests/non-free/oracle/strnlen2.res.oracle @@ -32,7 +32,7 @@ [11] ∈ {100} nondet ∈ [--..--] [value] computing for function small_sets <- main. - Called from tests/non-free/strnlen2.c:488. + Called from tests/non-free/strnlen2.c:513. tests/non-free/strnlen2.c:45:[value] Call to builtin Frama_C_strnlen(({{ "abc" + {0; 1} }},{3})) tests/non-free/strnlen2.c:46:[value] assertion got status valid. tests/non-free/strnlen2.c:49:[value] Call to builtin Frama_C_strnlen(({{ "\000bc" + {0; 1} }},{2})) @@ -46,7 +46,7 @@ tests/non-free/strnlen2.c:62:[value] assertion got status valid. [value] Recording results for small_sets [value] Done for function small_sets [value] computing for function zero_termination <- main. - Called from tests/non-free/strnlen2.c:489. + Called from tests/non-free/strnlen2.c:514. tests/non-free/strnlen2.c:68:[value] Call to builtin Frama_C_strnlen(({{ &empty_or_non_terminated[0] }},{1})) tests/non-free/strnlen2.c:69:[value] assertion got status valid. tests/non-free/strnlen2.c:73:[value] Call to builtin Frama_C_strnlen(({{ &non_terminated[0] }},{2})) @@ -56,7 +56,7 @@ tests/non-free/strnlen2.c:79:[value] warning: builtin Frama_C_strnlen: reading i [value] Recording results for zero_termination [value] Done for function zero_termination [value] computing for function initialization <- main. - Called from tests/non-free/strnlen2.c:491. + Called from tests/non-free/strnlen2.c:516. tests/non-free/strnlen2.c:85:[value] Call to builtin Frama_C_strnlen(({{ &empty_or_uninitialized[0] }},{1})) tests/non-free/strnlen2.c:85:[value] warning: builtin Frama_C_strnlen: possible uninitialized values tests/non-free/strnlen2.c:86:[value] assertion got status valid. @@ -71,7 +71,7 @@ tests/non-free/strnlen2.c:102:[value] assertion got status valid. [value] Recording results for initialization [value] Done for function initialization [value] computing for function large <- main. - Called from tests/non-free/strnlen2.c:492. + Called from tests/non-free/strnlen2.c:517. [value] computing for function init_array_nondet <- large <- main. Called from tests/non-free/strnlen2.c:144. tests/non-free/strnlen2.c:138:[value] Call to builtin memset(({{ (void *)&a }},{1; 2},{100})) @@ -114,7 +114,7 @@ tests/non-free/strnlen2.c:166:[value] assertion got status valid. [value] Recording results for large [value] Done for function large [value] computing for function large_uninit <- main. - Called from tests/non-free/strnlen2.c:493. + Called from tests/non-free/strnlen2.c:518. [value] computing for function init_array_nondet <- large_uninit <- main. Called from tests/non-free/strnlen2.c:171. tests/non-free/strnlen2.c:138:[value] Call to builtin memset(({{ (void *)&a }},{1; 2},{40})) @@ -148,7 +148,7 @@ tests/non-free/strnlen2.c:187:[value] assertion got status valid. [value] Recording results for large_uninit [value] Done for function large_uninit [value] computing for function misc <- main. - Called from tests/non-free/strnlen2.c:494. + Called from tests/non-free/strnlen2.c:519. tests/non-free/strnlen2.c:215:[value] Call to builtin Frama_C_strnlen(({{ &unterminated_string[0] }},{13})) tests/non-free/strnlen2.c:215:[value] warning: builtin Frama_C_strnlen: reading indeterminate data tests/non-free/strnlen2.c:218:[value] Call to builtin Frama_C_strnlen(({{ "Hello World\n" ; "Bonjour Monde\n" }}, @@ -193,19 +193,19 @@ tests/non-free/strnlen2.c:252:[value] assertion got status valid. [value] Recording results for misc [value] Done for function misc [value] computing for function bitfields <- main. - Called from tests/non-free/strnlen2.c:495. + Called from tests/non-free/strnlen2.c:520. tests/non-free/strnlen2.c:117:[value] Call to builtin Frama_C_strnlen(({{ (char const *)&s }},{3})) tests/non-free/strnlen2.c:117:[value] warning: builtin Frama_C_strnlen: reading indeterminate data [value] Recording results for bitfields [value] Done for function bitfields [value] computing for function bitfields2 <- main. - Called from tests/non-free/strnlen2.c:496. + Called from tests/non-free/strnlen2.c:521. tests/non-free/strnlen2.c:132:[value] Call to builtin Frama_C_strnlen(({{ (char const *)&s }},{3})) tests/non-free/strnlen2.c:133:[value] assertion got status valid. [value] Recording results for bitfields2 [value] Done for function bitfields2 [value] computing for function escaping <- main. - Called from tests/non-free/strnlen2.c:497. + Called from tests/non-free/strnlen2.c:522. tests/non-free/strnlen2.c:196:[value] warning: locals {x} escaping the scope of a block of escaping through s tests/non-free/strnlen2.c:199:[value] Call to builtin Frama_C_strnlen(({{ &s[0] }},{4})) tests/non-free/strnlen2.c:199:[value] warning: builtin Frama_C_strnlen: possible escaping addresses @@ -215,7 +215,7 @@ tests/non-free/strnlen2.c:203:[value] assertion got status valid. [value] Recording results for escaping [value] Done for function escaping [value] computing for function big_array <- main. - Called from tests/non-free/strnlen2.c:498. + Called from tests/non-free/strnlen2.c:523. tests/non-free/strnlen2.c:261:[value] warning: out of bounds write. assert \valid(p); tests/non-free/strnlen2.c:263:[value] warning: out of bounds write. assert \valid(p); tests/non-free/strnlen2.c:265:[value] warning: out of bounds write. assert \valid(p); @@ -297,7 +297,7 @@ tests/non-free/strnlen2.c:314:[value] Frama_C_show_each: [0..799], [0..803], [0. [value] Recording results for big_array [value] Done for function big_array [value] computing for function no_zero_but_ok <- main. - Called from tests/non-free/strnlen2.c:500. + Called from tests/non-free/strnlen2.c:525. tests/non-free/strnlen2.c:325:[value] Call to builtin Frama_C_strnlen(({{ &s[0] }},{5})) tests/non-free/strnlen2.c:326:[value] assertion got status valid. tests/non-free/strnlen2.c:327:[value] Call to builtin Frama_C_strnlen(({{ &s[0] }},{10})) @@ -312,7 +312,7 @@ tests/non-free/strnlen2.c:337:[value] assertion got status valid. [value] Recording results for no_zero_but_ok [value] Done for function no_zero_but_ok [value] computing for function small_sets_n <- main. - Called from tests/non-free/strnlen2.c:501. + Called from tests/non-free/strnlen2.c:526. tests/non-free/strnlen2.c:345:[value] Call to builtin Frama_C_strnlen(({{ "abcde" + {0; 1} }},{2; 5})) tests/non-free/strnlen2.c:346:[value] assertion got status valid. tests/non-free/strnlen2.c:351:[value] Call to builtin Frama_C_strnlen(({{ "\000bcdef" + {0; 1} }},{1; 4})) @@ -326,7 +326,7 @@ tests/non-free/strnlen2.c:367:[value] assertion got status valid. [value] Recording results for small_sets_n [value] Done for function small_sets_n [value] computing for function large_n <- main. - Called from tests/non-free/strnlen2.c:502. + Called from tests/non-free/strnlen2.c:527. [value] computing for function init_array_nondet <- large_n <- main. Called from tests/non-free/strnlen2.c:372. tests/non-free/strnlen2.c:138:[value] Call to builtin memset(({{ (void *)&a }},{1; 2},{100})) @@ -386,7 +386,7 @@ tests/non-free/strnlen2.c:415:[value] assertion got status valid. [value] Recording results for large_n [value] Done for function large_n [value] computing for function unbounded_n <- main. - Called from tests/non-free/strnlen2.c:504. + Called from tests/non-free/strnlen2.c:529. tests/non-free/strnlen2.c:423:[value] Call to builtin Frama_C_strnlen(({{ "abc" }},[0..2147483647])) tests/non-free/strnlen2.c:424:[value] assertion got status valid. tests/non-free/strnlen2.c:426:[value] Call to builtin Frama_C_strnlen(({{ "abc" + {0; 1} }},[0..2147483647])) @@ -396,7 +396,7 @@ tests/non-free/strnlen2.c:430:[value] assertion got status valid. [value] Recording results for unbounded_n [value] Done for function unbounded_n [value] computing for function intervals <- main. - Called from tests/non-free/strnlen2.c:505. + Called from tests/non-free/strnlen2.c:530. [value] computing for function init_array_nondet <- intervals <- main. Called from tests/non-free/strnlen2.c:435. tests/non-free/strnlen2.c:138:[value] Call to builtin memset(({{ (void *)&a }},{0; 1},{10})) @@ -516,6 +516,49 @@ tests/non-free/strnlen2.c:483:[value] warning: builtin Frama_C_strnlen: tests/non-free/strnlen2.c:484:[value] assertion got status valid. [value] Recording results for intervals [value] Done for function intervals +[value] computing for function negative_offsets <- main. + Called from tests/non-free/strnlen2.c:532. +tests/non-free/strnlen2.c:489:[value] entering loop for the first time +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strnlen2.c:493. +[value] Done for function Frama_C_interval +tests/non-free/strnlen2.c:494:[value] Call to builtin Frama_C_strnlen(({{ &buf{[-10], [-9], [-8]} }},{100})) +tests/non-free/strnlen2.c:494:[value] warning: builtin Frama_C_strnlen: reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strnlen2.c:497. +[value] Done for function Frama_C_interval +tests/non-free/strnlen2.c:498:[value] Call to builtin Frama_C_strnlen(({{ &buf{[-2], [-1]} }},{100})) +tests/non-free/strnlen2.c:498:[value] warning: builtin Frama_C_strnlen: reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strnlen2.c:500. +[value] Done for function Frama_C_interval +tests/non-free/strnlen2.c:501:[value] Call to builtin Frama_C_strnlen(({{ &buf{[-1], [0]} }},{100})) +tests/non-free/strnlen2.c:501:[value] warning: builtin Frama_C_strnlen: + possible uninitialized values + possibly reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strnlen2.c:502. +[value] Done for function Frama_C_interval +tests/non-free/strnlen2.c:503:[value] Call to builtin Frama_C_strnlen(({{ &buf{[-1], [0], [1], [2]} }},{100})) +tests/non-free/strnlen2.c:503:[value] warning: builtin Frama_C_strnlen: + possible uninitialized values + possibly reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strnlen2.c:504. +[value] Done for function Frama_C_interval +tests/non-free/strnlen2.c:505:[value] Call to builtin Frama_C_strnlen(({{ &buf + [-4..7] }},{100})) +tests/non-free/strnlen2.c:505:[value] warning: builtin Frama_C_strnlen: + possible uninitialized values + possibly reading indeterminate data +[value] computing for function Frama_C_interval <- negative_offsets <- main. + Called from tests/non-free/strnlen2.c:506. +[value] Done for function Frama_C_interval +tests/non-free/strnlen2.c:508:[value] Call to builtin Frama_C_strnlen(({{ &buf + [-10..0] }},{100})) +tests/non-free/strnlen2.c:508:[value] warning: builtin Frama_C_strnlen: + possible uninitialized values + possibly reading indeterminate data +[value] Recording results for negative_offsets +[value] Done for function negative_offsets [value] Recording results for main [value] done for function main [value] ====== VALUES COMPUTED ====== @@ -661,6 +704,21 @@ tests/non-free/strnlen2.c:484:[value] assertion got status valid. s2 ∈ {{ "efg" + {1; 2} ; "EFGH" + {1; 2} }} maybe_init[0] ∈ {65} or UNINITIALIZED [1] ∈ {0} +[value:final-states] Values at end of function negative_offsets: + Frama_C_entropy_source ∈ [--..--] + buf[0..98] ∈ {65} or UNINITIALIZED + [99] ∈ {0} + len1 ∈ UNINITIALIZED + len2 ∈ UNINITIALIZED + len3 ∈ {99} + len4 ∈ {97; 98; 99} + len5 ∈ {92; 93; 94; 95; 96; 97; 98; 99} + len6 ∈ {99} + offset3 ∈ {-1; 0} + offset4 ∈ {-1; 0; 1; 2} + offset5 ∈ [-4..7] + offset6 ∈ [-10..0] + p ∈ {{ &buf + [-10..0] }} [value:final-states] Values at end of function no_zero_but_ok: s[0..9] ∈ {1} [10] ∈ {0} @@ -738,6 +796,8 @@ tests/non-free/strnlen2.c:484:[value] assertion got status valid. [from] Done for function large_uninit [from] Computing for function misc [from] Done for function misc +[from] Computing for function negative_offsets +[from] Done for function negative_offsets [from] Computing for function no_zero_but_ok [from] Done for function no_zero_but_ok [from] Computing for function small_sets @@ -771,7 +831,7 @@ tests/non-free/strnlen2.c:484:[value] assertion got status valid. uninitialized[0]; s[0..1]; t[0..3]; s; s; a[3..99]; a[3..99]; s[0..3]; loc_char_array[0..4]; x; maybe_init[0..1]; u[0..199]; r[0..200]; t[0..999999]; s[0..19]; a[0..99]; a[0..99]; - "Hello World\n"[bits 0 to 103]; + buf[0..99]; "Hello World\n"[bits 0 to 103]; "abc\000\000\000abc"[bits 0 to 79]; ""[bits 0 to 7]; "a"[bits 0 to 15]; "aa"[bits 0 to 23]; "aaa"; "aaaa"[bits 0 to 39]; "aaaaa"[bits 0 to 47]; @@ -812,6 +872,8 @@ tests/non-free/strnlen2.c:484:[value] assertion got status valid. Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) [from] Function misc: Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) +[from] Function negative_offsets: + Frama_C_entropy_source FROM Frama_C_entropy_source; nondet (and SELF) [from] Function no_zero_but_ok: NO EFFECTS [from] Function small_sets: @@ -823,7 +885,7 @@ tests/non-free/strnlen2.c:484:[value] assertion got status valid. [from] Function zero_termination: NO EFFECTS [from] Function main: - Frama_C_entropy_source FROM Frama_C_entropy_source (and SELF) + Frama_C_entropy_source FROM Frama_C_entropy_source; nondet (and SELF) \result FROM \nothing [from] ====== END OF DEPENDENCIES ====== [inout] Out (internal) for function bitfields: @@ -888,6 +950,11 @@ tests/non-free/strnlen2.c:484:[value] assertion got status valid. "Bonjour Monde\n"[bits 0 to 119]; "abc"; "ABCD"[bits 0 to 39]; "efg"[bits 8 to 31]; "EFGH"[bits 8 to 39]; "mno\000pqr"[bits 0 to 63]; "MNOP\000QRS"[bits 0 to 71] +[inout] Out (internal) for function negative_offsets: + Frama_C_entropy_source; buf[0..99]; i; len1; len2; len3; len4; len5; + len6; offset1; offset2; offset3; offset4; offset5; offset6; p +[inout] Inputs for function negative_offsets: + Frama_C_entropy_source; nondet [inout] Out (internal) for function no_zero_but_ok: s[0..19]; z1; tmp; z2; tmp_0; p; tmp_1; z3; tmp_2; z4; tmp_3; z5; tmp_4 [inout] Inputs for function no_zero_but_ok: diff --git a/tests/non-free/strlen.c b/tests/non-free/strlen.c index 887f163f6eae93b2333a19a3480361564ea430ac..f45980a6d36ce2b4637e4827c2f8881abf05de35 100644 --- a/tests/non-free/strlen.c +++ b/tests/non-free/strlen.c @@ -305,6 +305,31 @@ void big_array () { Frama_C_show_each(len_u, len_r, len_t); } +void negative_offsets() { + char buf[100]; + for (int i = 0; i < 100; i++) buf[i] = 'A'; //avoid memset due to C++ oracles + buf[99] = 0; + unsigned len1, len2, len3, len4, len5, len6; + if (nondet) { + int offset1 = Frama_C_interval(-10, -8); + len1 = strlen(buf + offset1); + } + if (nondet) { + int offset2 = Frama_C_interval(-2, -1); + len2 = strlen(buf + offset2); + } + int offset3 = Frama_C_interval(-1, -0); + len3 = strlen(buf + offset3); + int offset4 = Frama_C_interval(-1, 2); + len4 = strlen(buf + offset4); + int offset5 = Frama_C_interval(-4, 7); + len5 = strlen(buf + offset5); + int offset6 = Frama_C_interval(-10, 0); + char *p = buf + offset6; + len6 = strlen(p); + char dest[100 * 2]; +} + int main (int c) { small_sets(); zero_termination(); @@ -316,5 +341,6 @@ int main (int c) { bitfields2(); escaping(); big_array(); + negative_offsets(); return 0; } diff --git a/tests/non-free/strnlen2.c b/tests/non-free/strnlen2.c index 375dcf635618716ee4942c368bc3ea8b86a10cbf..dd3a006258be37a2e31b3427f42df228f6bbcd31 100644 --- a/tests/non-free/strnlen2.c +++ b/tests/non-free/strnlen2.c @@ -484,6 +484,31 @@ void intervals() { //@ assert z9 >= 0 && z9 <= 9; } +void negative_offsets() { + char buf[100]; + for (int i = 0; i < 100; i++) buf[i] = 'A'; //avoid memset due to C++ oracles + buf[99] = 0; + unsigned len1, len2, len3, len4, len5, len6; + if (nondet) { + int offset1 = Frama_C_interval(-10, -8); + len1 = strnlen(buf + offset1, 100); + } + if (nondet) { + int offset2 = Frama_C_interval(-2, -1); + len2 = strnlen(buf + offset2, 100); + } + int offset3 = Frama_C_interval(-1, -0); + len3 = strnlen(buf + offset3, 100); + int offset4 = Frama_C_interval(-1, 2); + len4 = strnlen(buf + offset4, 100); + int offset5 = Frama_C_interval(-4, 7); + len5 = strnlen(buf + offset5, 100); + int offset6 = Frama_C_interval(-10, 0); + char *p = buf + offset6; + len6 = strnlen(p, 100); + char dest[100 * 2]; +} + int main (int c) { small_sets(); zero_termination(); @@ -504,5 +529,6 @@ int main (int c) { unbounded_n(); intervals(); + negative_offsets(); return 0; }