From 45ab4741a5ace18e77b027a2f7e318327c33d4b7 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Mon, 30 Sep 2024 09:15:12 -0700 Subject: Tests for negative array size and runtime OOB --- .../main/java/com/seaofnodes/simple/Parser.java | 2 ++ .../com/seaofnodes/simple/node/ReturnNode.java | 3 ++- .../java/com/seaofnodes/simple/Chapter15Test.java | 28 ++++++++++++++++++++++ .../com/seaofnodes/simple/evaluator/Evaluator.java | 4 +++- 4 files changed, 35 insertions(+), 2 deletions(-) (limited to 'chapter15/src') diff --git a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java index d9726d28..ec040b4f 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/Parser.java @@ -711,6 +711,8 @@ public class Parser { private Node newArray(Type t) { Node len = parseExpression().keep(); + if( !(len._type instanceof TypeInteger) ) + throw error("Cannot allocate an array with length "+len._type); TypeStruct ary = (TypeStruct)TYPES.get("[]"+t.str()); if( ary == null ) { TYPES.put("[]"+t.str(), ary = TypeStruct.makeAry(TypeInteger.BOT,ALIAS++,t,ALIAS++)); diff --git a/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java b/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java index 444b76a8..e12f1fef 100644 --- a/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java +++ b/chapter15/src/main/java/com/seaofnodes/simple/node/ReturnNode.java @@ -17,7 +17,8 @@ public class ReturnNode extends CFGNode { public ReturnNode(Node ctrl, Node data, ScopeNode scope) { super(ctrl, data); - // We lookup memory slices by the naming convention that they start with $ + // Add memory slices to Return, so all memory updates are live-on-exit. + // We look up memory slices by the naming convention that they start with $. // We could also use implicit knowledge that all memory projects are at offset >= 2 if( scope != null ) { String[] names = scope.reverseNames(); diff --git a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java index 2955361a..a3dd48d0 100644 --- a/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java +++ b/chapter15/src/test/java/com/seaofnodes/simple/Chapter15Test.java @@ -89,4 +89,32 @@ int is = new int[2]; try { parser.parse(false).iterate(false); fail(); } catch( Exception e ) { assertEquals("Type *[]int is not of declared type int",e.getMessage()); } } + + @Test + public void testBad2() { + Parser parser = new Parser( +""" +int[] is = new int[3.14]; +return is[1]; +"""); + try { parser.parse(false).iterate(false); fail(); } + catch( Exception e ) { assertEquals("Cannot allocate an array with length 3.14",e.getMessage()); } + } + + @Test + public void testBad3() { + Parser parser = new Parser( +""" +int[] is = new int[arg]; +return is[1]; +"""); + StopNode stop = parser.parse(false).iterate(false); + assertEquals("return 0;", stop.toString()); + assertEquals(0L, Evaluator.evaluate(stop, 4)); + try { Evaluator.evaluate(stop,0); } + catch( ArrayIndexOutOfBoundsException e ) { assertEquals("Array index 1 out of bounds for array length 0",e.getMessage()); } + try { Evaluator.evaluate(stop,-1); } + catch( NegativeArraySizeException e ) { assertEquals("-1",e.getMessage()); } + } + } diff --git a/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java b/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java index 40d73b19..e59017e7 100644 --- a/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java +++ b/chapter15/src/test/java/com/seaofnodes/simple/evaluator/Evaluator.java @@ -91,6 +91,8 @@ public class Evaluator { int base = alloc._ptr._obj.aryBase(); int scale = alloc._ptr._obj.aryScale(); long n = (sz-base)>>scale; + if( n < 0 ) + throw new NegativeArraySizeException(""+n); body = new Object[(int)n+1]; // Array body body[0] = n; // Array length } else { @@ -113,7 +115,7 @@ public class Evaluator { int scale = from.struct.aryScale(); long i = ((Long)off - base)>>scale; if( i < 0 || i >= len ) - throw new RuntimeException("Array index out of bounds " + off + " <= " + len); + throw new ArrayIndexOutOfBoundsException("Array index out of bounds " + off + " <= " + len); return from.fields[(int)i+1]; } else -- cgit v1.2.3