Skip to content

Commit d41403f

Browse files
author
Thomas Kiley
authored
Merge pull request diffblue#1665 from romainbrenguier/bugfix/string-out-of-bound#TG-1808
Make clear that cbmc version of charAt and substring do not throw OutOfBound TG-1808
2 parents bcfaaa4 + ac7e649 commit d41403f

29 files changed

+94
-31
lines changed
Binary file not shown.

regression/jbmc-strings/StringLastIndexOf/Test.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public void check(String input_String1, String input_String2, int i) {
1313
// Contradiction with the previous condition (should fail).
1414
assert "foo".lastIndexOf("") != 3;
1515
} else if (i == 2 && input_String2.length() > 0) {
16-
int lio = input_String1.lastIndexOf(input_String2.charAt(0), fromIndex);
16+
int lio = input_String1.lastIndexOf(org.cprover.CProverString.charAt(input_String2, 0), fromIndex);
1717
if (input_String2.length() == 0)
1818
assert lio == fromIndex;
1919
} else if (i == 3) {
Binary file not shown.

regression/jbmc-strings/StringMiscellaneous04/StringMiscellaneous04.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,19 @@ public static char[] toCharArray(String s)
88
char arr[]=new char[s.length()];
99
// We limit arbitrarly the loop unfolding to 10
1010
for(int i=0; i<length && i<10; i++)
11-
arr[i]=s.charAt(i);
11+
arr[i]=org.cprover.CProverString.charAt(s, i);
1212
return arr;
1313
}
1414

1515
public static void main(String[] args)
1616
{
1717
String s1 = "diffblue";
1818
String s2 = "TESTGENERATION";
19-
String s3 = " automated ";
19+
String s3 = " automated ";
2020

2121
assert s1.equals("diffblue");
2222
assert s2.equals("TESTGENERATION");
23-
assert s3.equals(" automated ");
23+
assert s3.equals(" automated ");
2424

2525
System.out.printf(
2626
"Replace 'f' with 'F' in s1: %s\n\n", s1.replace('f', 'F'));
@@ -43,7 +43,7 @@ public static void main(String[] args)
4343
int i=0;
4444
for (char character : charArray)
4545
{
46-
assert character=="diffblue".charAt(i);
46+
assert character==org.cprover.CProverString.charAt("diffblue", i);
4747
++i;
4848
}
4949

Binary file not shown.
Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
public class SubString01
22
{
3-
public static void main(String[] args)
4-
{
5-
String letters = "automatictestcasegenerationatdiffblue";
3+
public static void main(String[] args)
4+
{
5+
String letters = "automatictestcasegenerationatdiffblue";
66

7-
String tmp=letters.substring(20);
8-
assert tmp.equals("erationatdiffblue");
9-
10-
tmp=letters.substring(9, 13);
11-
assert tmp.equals("test");
12-
}
7+
String tmp=org.cprover.CProverString.substring(letters, 20);
8+
assert tmp.equals("erationatdiffblue");
9+
tmp=org.cprover.CProverString.substring(letters, 9, 13);
10+
assert tmp.equals("test");
11+
}
1312
}
790 Bytes
Binary file not shown.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.cprover;
2+
3+
public final class CProverString {
4+
public static char charAt(String s, int i) {
5+
if (0 <= i && i < s.length())
6+
return s.charAt(i);
7+
else
8+
return '\u0000';
9+
}
10+
11+
public static String substring(String s, int i) {
12+
if (i <= 0)
13+
return s;
14+
else if (i >= s.length())
15+
return "";
16+
else
17+
return s.substring(i);
18+
}
19+
20+
public static String substring(String s, int i, int j) {
21+
if (i < 0)
22+
return substring(s, 0, j);
23+
if (j >= s.length())
24+
return substring(s, 0, s.length() - 1);
25+
if (i >= j)
26+
return "";
27+
return s.substring(i, j);
28+
}
29+
}
Binary file not shown.

regression/jbmc-strings/java_char_array_init/test_init.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public static String stringOfCharArray(char arr[])
1313

1414
public static String stringOfCharArray(char arr[], int i, int j)
1515
{
16-
return stringOfCharArray(arr).substring(i, i+j);
16+
return org.cprover.CProverString.substring(stringOfCharArray(arr), i, i+j);
1717
}
1818

1919
public static void main(int i)
Binary file not shown.

regression/jbmc-strings/java_concat/test_concat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public static void main(/*String[] argv*/)
66
int i = s.length();
77
String t = new String("ppo");
88
String u = s.concat(t);
9-
char c = u.charAt(i);
9+
char c = org.cprover.CProverString.charAt(u, i);
1010
assert(c == 'p');
1111
assert(c != 'p');
1212
}
Binary file not shown.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.cprover;
2+
3+
public final class CProverString {
4+
public static char charAt(String s, int i) {
5+
if (0 <= i && i < s.length())
6+
return s.charAt(i);
7+
else
8+
return '\u0000';
9+
}
10+
11+
public static String substring(String s, int i) {
12+
if (i <= 0)
13+
return s;
14+
else if (i >= s.length())
15+
return "";
16+
else
17+
return s.substring(i);
18+
}
19+
20+
public static String substring(String s, int i, int j) {
21+
if (i < 0)
22+
return substring(s, 0, j);
23+
if (j >= s.length())
24+
return substring(s, 0, s.length() - 1);
25+
if (i >= j)
26+
return "";
27+
return s.substring(i, j);
28+
}
29+
}
Binary file not shown.

regression/strings-smoke-tests/java_append_string/test_append_string.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static void check(StringBuilder sb, String str)
2020
sb.append(str, 2, 4);
2121
String res = sb.toString();
2222
assert(res.startsWith(init));
23-
assert(res.endsWith(str.substring(2, 4)));
23+
assert(res.endsWith(org.cprover.CProverString.substring(str, 2, 4)));
2424
assert(res.length() == init.length() + 2);
2525
assert(!res.equals("foobarfuz"));
2626
}
Binary file not shown.

regression/strings-smoke-tests/java_char_array/test_char_array.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ public static char[] toCharArray(String s)
88
char arr[] = new char[s.length()];
99
// We limit arbitrarly the loop unfolding to 5
1010
for(int i = 0; i < length && i < 5; i++)
11-
arr[i] = s.charAt(i);
11+
arr[i] = org.cprover.CProverString.charAt(s, i);
1212
return arr;
1313
}
1414

@@ -17,7 +17,7 @@ public static void main(int i)
1717
String s = "abc";
1818
char [] str = toCharArray(s);
1919
char c = str[2];
20-
char a = s.charAt(0);
20+
char a = org.cprover.CProverString.charAt(s, 0);
2121
assert(str.length == 3);
2222
assert(a == 'a');
2323
assert(c == 'c');
Binary file not shown.

regression/strings-smoke-tests/java_char_at/test_char_at.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ public class test_char_at {
22

33
public static void main(/*String[] argv*/) {
44
String s = new String("abc");
5-
assert(s.charAt(2)=='c');
5+
assert(org.cprover.CProverString.charAt(s, 2)=='c');
66
}
77
}
Binary file not shown.

regression/strings-smoke-tests/java_code_point/test_code_point.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@ public static void main(/*String[] argv*/)
99
assert(s.offsetByCodePoints(1,2) >= 3);
1010
StringBuilder sb = new StringBuilder();
1111
sb.appendCodePoint(0x10907);
12-
assert(s.charAt(1) == sb.charAt(0));
12+
assert(org.cprover.CProverString.charAt(s, 1) == org.cprover.CProverString.charAt(sb.toString(), 0));
1313
}
1414
}
Binary file not shown.

regression/strings-smoke-tests/java_concat/test_concat.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public static void main(/*String[] argv*/)
66
int i = s.length();
77
String t = new String("ppo");
88
String u = s.concat(t);
9-
char c = u.charAt(i);
9+
char c = org.cprover.CProverString.charAt(u, i);
1010
assert(c == 'p');
1111
assert(c == 'o');
1212
}
Binary file not shown.

regression/strings-smoke-tests/java_set_char_at/test_set_char_at.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ public class test_set_char_at
33
public static void main(/*String[] argv*/)
44
{
55
String s = new String("Abc");
6-
char c = s.charAt(1);
6+
char c = org.cprover.CProverString.charAt(s, 1);
77
StringBuilder sb = new StringBuilder(s);
88
sb.setCharAt(1,'w');
99
s = sb.toString();
1010
assert(s.equals("Awc"));
11-
assert(s.charAt(2)=='c');
11+
assert(org.cprover.CProverString.charAt(s, 2)=='c');
1212
}
1313
}
Binary file not shown.

regression/strings-smoke-tests/java_substring/test_substring.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ public class test_substring
33
public static void main(/*String[] argv*/)
44
{
55
String abcdef = "AbcDef";
6-
String cde = abcdef.substring(2,5);
7-
char c = cde.charAt(0);
8-
char d = cde.charAt(1);
9-
char e = cde.charAt(2);
6+
String cde = org.cprover.CProverString.substring(abcdef, 2,5);
7+
char c = org.cprover.CProverString.charAt(cde, 0);
8+
char d = org.cprover.CProverString.charAt(cde, 1);
9+
char e = org.cprover.CProverString.charAt(cde, 2);
1010
assert(c == 'c');
1111
assert(d == 'D');
1212
assert(e == 'e');

src/java_bytecode/java_string_library_preprocess.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1890,8 +1890,10 @@ void java_string_library_preprocesst::initialize_conversion_table()
18901890
["java::java.lang.String.<init>:()V"]=
18911891
ID_cprover_string_empty_string_func;
18921892

1893+
// CProverString.charAt differs from the Java String.charAt in that no
1894+
// exception is raised for the out of bounds case.
18931895
cprover_equivalent_to_java_function
1894-
["java::java.lang.String.charAt:(I)C"]=
1896+
["java::org.cprover.CProverString.charAt:(Ljava/lang/String;I)C"]=
18951897
ID_cprover_string_char_at_func;
18961898
cprover_equivalent_to_java_function
18971899
["java::java.lang.String.codePointAt:(I)I"]=
@@ -1999,11 +2001,15 @@ void java_string_library_preprocesst::initialize_conversion_table()
19992001
cprover_equivalent_to_java_string_returning_function
20002002
["java::java.lang.String.subSequence:(II)Ljava/lang/CharSequence;"]=
20012003
ID_cprover_string_substring_func;
2004+
// CProverString.substring differs from the Java String.substring in that no
2005+
// exception is raised for the out of bounds case.
20022006
cprover_equivalent_to_java_string_returning_function
2003-
["java::java.lang.String.substring:(II)Ljava/lang/String;"]=
2007+
["java::org.cprover.CProverString.substring:(Ljava/lang/String;II)"
2008+
"Ljava/lang/String;"]=
20042009
ID_cprover_string_substring_func;
20052010
cprover_equivalent_to_java_string_returning_function
2006-
["java::java.lang.String.substring:(I)Ljava/lang/String;"]=
2011+
["java::org.cprover.CProverString.substring:(Ljava/lang/String;I)"
2012+
"Ljava/lang/String;"]=
20072013
ID_cprover_string_substring_func;
20082014
cprover_equivalent_to_java_string_returning_function
20092015
["java::java.lang.String.toLowerCase:()Ljava/lang/String;"]=

0 commit comments

Comments
 (0)