diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-07-17 14:30:17 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-07-17 14:30:17 -0700 |
commit | 551d155c663a7478efd08fac2db35eda096bef97 (patch) | |
tree | 691273968193068d004d7a4c1c7b82503f048798 /030container.cc | |
parent | 32cd40ec3c9dad33738caf6f55fb742a316bd5be (diff) | |
download | mu-551d155c663a7478efd08fac2db35eda096bef97.tar.gz |
1800 - ah, found the bounds-checking bug
I was counting locations when I should have been counting elements.
Diffstat (limited to '030container.cc')
-rw-r--r-- | 030container.cc | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/030container.cc b/030container.cc index 4b013450..f90e92ba 100644 --- a/030container.cc +++ b/030container.cc @@ -112,15 +112,17 @@ case GET: { assert(is_literal(current_instruction().ingredients.at(1))); assert(scalar(ingredients.at(1))); long long int offset = ingredients.at(1).at(0); - assert(offset >= 0); - assert(offset < size_of(base)); long long int src = base_address; for (long long int i = 0; i < offset; ++i) { src += size_of(Type[base_type].elements.at(i)); } trace(Primitive_recipe_depth, "run") << "address to copy is " << src; assert(Type[base_type].kind == container); - assert(SIZE(Type[base_type].elements) > offset); + if (offset < 0 || offset >= SIZE(Type[base_type].elements)) { + raise << current_recipe_name() << ": invalid offset " << offset << " for " << Type[base_type].name << '\n'; + products.resize(1); + break; + } type_ordinal src_type = Type[base_type].elements.at(offset).at(0); trace(Primitive_recipe_depth, "run") << "its type is " << Type[src_type].name; reagent tmp; @@ -149,6 +151,26 @@ recipe main [ ] +mem: storing 13 in location 15 +:(scenario get_out_of_bounds) +% Hide_warnings = true; +recipe main [ + 12:number <- copy 34:literal + 13:number <- copy 35:literal + 14:number <- copy 36:literal + get 12:point-number/raw, 2:offset # point-number occupies 3 locations but has only 2 fields; out of bounds +] ++warn: main: invalid offset 2 for point-number + +:(scenario get_out_of_bounds2) +% Hide_warnings = true; +recipe main [ + 12:number <- copy 34:literal + 13:number <- copy 35:literal + 14:number <- copy 36:literal + get 12:point-number/raw, -1:offset +] ++warn: main: invalid offset -1 for point-number + :(before "End Primitive Recipe Declarations") GET_ADDRESS, :(before "End Primitive Recipe Numbers") @@ -163,8 +185,11 @@ case GET_ADDRESS: { assert(is_literal(current_instruction().ingredients.at(1))); assert(scalar(ingredients.at(1))); long long int offset = ingredients.at(1).at(0); - assert(offset >= 0); - assert(offset < size_of(base)); + if (offset < 0 || offset >= SIZE(Type[base_type].elements)) { + raise << "invalid offset " << offset << " for " << Type[base_type].name << '\n'; + products.resize(1); + break; + } long long int result = base_address; for (long long int i = 0; i < offset; ++i) { result += size_of(Type[base_type].elements.at(i)); @@ -175,6 +200,26 @@ case GET_ADDRESS: { break; } +:(scenario get_address_out_of_bounds) +% Hide_warnings = true; +recipe main [ + 12:number <- copy 34:literal + 13:number <- copy 35:literal + 14:number <- copy 36:literal + get-address 12:point-number/raw, 2:offset # point-number occupies 3 locations but has only 2 fields; out of bounds +] ++warn: invalid offset 2 for point-number + +:(scenario get_address_out_of_bounds2) +% Hide_warnings = true; +recipe main [ + 12:number <- copy 34:literal + 13:number <- copy 35:literal + 14:number <- copy 36:literal + get-address 12:point-number/raw, -1:offset +] ++warn: invalid offset -1 for point-number + //:: Allow containers to be defined in mu code. :(scenarios load) |