3131import org .sosy_lab .java_smt .api .SolverContext .ProverOptions ;
3232import org .sosy_lab .java_smt .api .SolverException ;
3333import org .sosy_lab .java_smt .api .StringFormula ;
34+ import org .sosy_lab .java_smt .basicimpl .AbstractStringFormulaManager ;
3435
3536@ SuppressWarnings ("ConstantConditions" )
3637@ SuppressFBWarnings (value = "DLS_DEAD_LOCAL_STORE" , justification = "test code" )
@@ -111,6 +112,15 @@ private void assertDistinct(StringFormula str1, StringFormula str2)
111112 assertThatFormula (smgr .equal (str1 , str2 )).isUnsatisfiable ();
112113 }
113114
115+ /**
116+ * Resolve any SMTLIB escape sequences and create a new String constant.
117+ *
118+ * <p>The input String may still contain Unicode characters.
119+ */
120+ private StringFormula makeStringEscaped (String pString ) {
121+ return smgr .makeString (AbstractStringFormulaManager .unescapeUnicodeForSmtlib (pString ));
122+ }
123+
114124 private void requireVariableStringLiterals () {
115125 // FIXME: Remove once support for operations on non-singleton Strings has been added
116126 // See https://github.com/uuverifiers/ostrich/issues/88
@@ -126,12 +136,15 @@ private void requireVariableStringLiterals() {
126136
127137 @ Test
128138 public void testInputEscape () throws SolverException , InterruptedException {
129- // Test if SMTLIB Unicode literals are recognized and converted to their Unicode characters.
130- assertEqual (smgr .length (smgr .makeString ("\\ u{39E}" )), imgr .makeNumber (1 ));
131- assertEqual (smgr .length (smgr .makeString ("Ξ" )), imgr .makeNumber (1 ));
139+ // Check that escape sequences are not substituted
140+ assertEqual (smgr .length (smgr .makeString ("\\ u{39E}" )), imgr .makeNumber (7 ));
141+ // ...unless we're doing so explicitly:
142+ assertEqual (smgr .length (makeStringEscaped ("\\ u{39E}" )), imgr .makeNumber (1 ));
132143
133- // Test with a character that is not in the BMP
144+ // Test that Unicode characters are working
145+ assertEqual (smgr .length (smgr .makeString ("Ξ" )), imgr .makeNumber (1 ));
134146 if (solver != Solvers .PRINCESS ) {
147+ // Test with a character that is not in the BMP
135148 String str = Character .toString (0x200cb );
136149 assertEqual (smgr .length (smgr .makeString (str )), imgr .makeNumber (1 ));
137150 }
@@ -143,8 +156,9 @@ public void testOutputUnescape() throws SolverException, InterruptedException {
143156 try (ProverEnvironment prover = context .newProverEnvironment (ProverOptions .GENERATE_MODELS )) {
144157 assertThat (!prover .isUnsat ()).isTrue ();
145158 try (Model model = prover .getModel ()) {
146- assertThat (model .evaluate (smgr .makeString ("\\ u{39E}" ))).isEqualTo ("Ξ" );
147- assertThat (model .evaluate (smgr .concat (smgr .makeString ("\\ u{39E" ), smgr .makeString ("}" ))))
159+ assertThat (model .evaluate (makeStringEscaped ("\\ u{39E}" ))).isEqualTo ("Ξ" );
160+ assertThat (
161+ model .evaluate (smgr .concat (makeStringEscaped ("\\ u{39E" ), makeStringEscaped ("}" ))))
148162 .isEqualTo ("\\ u{39E}" );
149163
150164 // Test with a character that is not in the BMP
@@ -197,18 +211,18 @@ public void testRegexAllCharUnicode() throws SolverException, InterruptedExcepti
197211 // special single characters.
198212
199213 // Greek Capital Letter Delta
200- assertThatFormula (smgr .in (smgr . makeString ("\\ u0394" ), regexAllChar )).isTautological ();
201- assertThatFormula (smgr .in (smgr . makeString ("Δ" ), regexAllChar )).isTautological ();
214+ assertThatFormula (smgr .in (makeStringEscaped ("\\ u0394" ), regexAllChar )).isTautological ();
215+ assertThatFormula (smgr .in (makeStringEscaped ("Δ" ), regexAllChar )).isTautological ();
202216 // CJK Compatibility Ideograph from Basic Multilingual Plane.
203- assertThatFormula (smgr .in (smgr . makeString ("\\ u{fa6a}" ), regexAllChar )).isTautological ();
217+ assertThatFormula (smgr .in (makeStringEscaped ("\\ u{fa6a}" ), regexAllChar )).isTautological ();
204218 // Xiangqi Black Horse from Supplementary Multilingual Plane
205- assertThatFormula (smgr .in (smgr . makeString ("\\ u{1fa6a}" ), regexAllChar )).isTautological ();
219+ assertThatFormula (smgr .in (makeStringEscaped ("\\ u{1fa6a}" ), regexAllChar )).isTautological ();
206220
207221 // Combining characters are not matched as one character.
208- assertThatFormula (smgr .in (smgr . makeString ("ab" ), regexAllChar )).isUnsatisfiable ();
209- assertThatFormula (smgr .in (smgr . makeString ("abcdefgh" ), regexAllChar )).isUnsatisfiable ();
210- assertThatFormula (smgr .in (smgr . makeString ("a\\ u0336" ), regexAllChar )).isUnsatisfiable ();
211- assertThatFormula (smgr .in (smgr . makeString ("\\ n" ), regexAllChar )).isUnsatisfiable ();
222+ assertThatFormula (smgr .in (makeStringEscaped ("ab" ), regexAllChar )).isUnsatisfiable ();
223+ assertThatFormula (smgr .in (makeStringEscaped ("abcdefgh" ), regexAllChar )).isUnsatisfiable ();
224+ assertThatFormula (smgr .in (makeStringEscaped ("a\\ u0336" ), regexAllChar )).isUnsatisfiable ();
225+ assertThatFormula (smgr .in (makeStringEscaped ("\\ n" ), regexAllChar )).isUnsatisfiable ();
212226
213227 StringFormula x = smgr .makeVariable ("x" );
214228 assertThatFormula (smgr .in (x , smgr .range ('a' , 'z' ))).isSatisfiable ();
@@ -400,7 +414,7 @@ public void testStringLength() throws SolverException, InterruptedException {
400414 assertEqual (imgr .makeNumber (1 ), smgr .length (smgr .makeString ("\n " )));
401415 assertEqual (imgr .makeNumber (1 ), smgr .length (smgr .makeString ("\t " )));
402416
403- assertEqual (imgr .makeNumber (1 ), smgr .length (smgr . makeString ("\\ u{20AC}" )));
417+ assertEqual (imgr .makeNumber (1 ), smgr .length (makeStringEscaped ("\\ u{20AC}" )));
404418 assertEqual (imgr .makeNumber (1 ), smgr .length (smgr .makeString ("€" )));
405419 assertEqual (imgr .makeNumber (1 ), smgr .length (smgr .makeString ("Δ" )));
406420
@@ -905,8 +919,8 @@ public void testCharAtWithSpecialCharacters() throws SolverException, Interrupte
905919 String workaround = "au{1234}" ;
906920 StringFormula au1234WOEscapeCurly = smgr .makeString (workaround );
907921 StringFormula backSlash = smgr .makeString ("\\ " );
908- StringFormula u1234 = smgr . makeString ("\\ u{1234}" );
909- StringFormula au1234b = smgr . makeString ("a\\ u{1234}b" );
922+ StringFormula u1234 = makeStringEscaped ("\\ u{1234}" );
923+ StringFormula au1234b = makeStringEscaped ("a\\ u{1234}b" );
910924
911925 assertEqual (smgr .length (backSlash ), imgr .makeNumber (1 ));
912926 assertEqual (smgr .charAt (au1234b , imgr .makeNumber (0 )), a );
@@ -936,22 +950,22 @@ public void testCharAtWithSpecialCharacters() throws SolverException, Interrupte
936950 @ Test
937951 public void testUnicodeEscaping () throws SolverException , InterruptedException {
938952 // SMTLIB has different representations for the same symbol
939- assertEqual (a , smgr . makeString ("\u0061 " ));
940- assertEqual (a , smgr . makeString ("\\ u0061" ));
941- assertEqual (a , smgr . makeString ("\\ u{61}" ));
942- assertEqual (a , smgr . makeString ("\\ u{00061}" ));
953+ assertEqual (a , makeStringEscaped ("\u0061 " ));
954+ assertEqual (a , makeStringEscaped ("\\ u0061" ));
955+ assertEqual (a , makeStringEscaped ("\\ u{61}" ));
956+ assertEqual (a , makeStringEscaped ("\\ u{00061}" ));
943957 assertEqual (smgr .length (a ), imgr .makeNumber (1 ));
944958
945- StringFormula u0 = smgr . makeString ("\\ u0000" );
946- assertEqual (u0 , smgr . makeString ("\u0000 " ));
947- assertEqual (u0 , smgr . makeString ("\\ u{0}" ));
948- assertEqual (u0 , smgr . makeString ("\\ u{00000}" ));
959+ StringFormula u0 = makeStringEscaped ("\\ u0000" );
960+ assertEqual (u0 , makeStringEscaped ("\u0000 " ));
961+ assertEqual (u0 , makeStringEscaped ("\\ u{0}" ));
962+ assertEqual (u0 , makeStringEscaped ("\\ u{00000}" ));
949963 assertEqual (smgr .length (u0 ), imgr .makeNumber (1 ));
950964
951- StringFormula u1 = smgr . makeString ("\\ u1234" );
952- assertEqual (u1 , smgr . makeString ("\u1234 " ));
953- assertEqual (u1 , smgr . makeString ("\\ u{1234}" ));
954- assertEqual (u1 , smgr . makeString ("\\ u{01234}" ));
965+ StringFormula u1 = makeStringEscaped ("\\ u1234" );
966+ assertEqual (u1 , makeStringEscaped ("\u1234 " ));
967+ assertEqual (u1 , makeStringEscaped ("\\ u{1234}" ));
968+ assertEqual (u1 , makeStringEscaped ("\\ u{01234}" ));
955969 assertEqual (smgr .length (u1 ), imgr .makeNumber (1 ));
956970
957971 if (solverToUse () == Solvers .PRINCESS ) {
@@ -961,10 +975,10 @@ public void testUnicodeEscaping() throws SolverException, InterruptedException {
961975 Character .toString (0x10000 ),
962976 "\\ u{2FFFF}" ,
963977 Character .toString (0x2FFFF ))) {
964- assertThrows (IllegalArgumentException .class , () -> smgr . makeString (invalidStr ));
978+ assertThrows (IllegalArgumentException .class , () -> makeStringEscaped (invalidStr ));
965979 }
966980 } else {
967- StringFormula u2 = smgr . makeString ("\\ u{2FFFF}" );
981+ StringFormula u2 = makeStringEscaped ("\\ u{2FFFF}" );
968982 assertEqual (u2 , smgr .makeString (Character .toString (0x2FFFF )));
969983 assertEqual (smgr .length (u2 ), imgr .makeNumber (1 ));
970984 }
@@ -978,10 +992,10 @@ public void testUnicodeEscaping() throws SolverException, InterruptedException {
978992 public void testCharAtWithSpecialCharacters2Byte () throws SolverException , InterruptedException {
979993 StringFormula num7 = smgr .makeString ("7" );
980994 StringFormula u = smgr .makeString ("u" );
981- StringFormula curlyOpen2BUnicode = smgr . makeString ("\\ u{7B}" );
982- StringFormula curlyClose2BUnicode = smgr . makeString ("\\ u{7D}" );
983- StringFormula acurlyClose2BUnicodeb = smgr . makeString ("a\\ u{7D}b" );
984- StringFormula acurlyOpen2BUnicodeWOEscapeCurly = smgr . makeString ("au{7B}" );
995+ StringFormula curlyOpen2BUnicode = makeStringEscaped ("\\ u{7B}" );
996+ StringFormula curlyClose2BUnicode = makeStringEscaped ("\\ u{7D}" );
997+ StringFormula acurlyClose2BUnicodeb = makeStringEscaped ("a\\ u{7D}b" );
998+ StringFormula acurlyOpen2BUnicodeWOEscapeCurly = makeStringEscaped ("au{7B}" );
985999 StringFormula backSlash = smgr .makeString ("\\ " );
9861000
9871001 assertEqual (smgr .length (backSlash ), imgr .makeNumber (1 ));
@@ -1070,10 +1084,10 @@ public void testConstStringContains() throws SolverException, InterruptedExcepti
10701084 StringFormula abbbbbb = smgr .makeString ("abbbbbb" );
10711085 StringFormula aaaaaaaB = smgr .makeString ("aaaaaaaB" );
10721086 StringFormula abcAndSoOn = smgr .makeString ("abcdefghijklmnopqrstuVwxyz" );
1073- StringFormula curlyOpen2BUnicode = smgr . makeString ("\\ u{7B}" );
1074- StringFormula curlyClose2BUnicode = smgr . makeString ("\\ u{7D}" );
1075- StringFormula multipleCurlys2BUnicode = smgr . makeString ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
1076- StringFormula curlyClose2BUnicodeEncased = smgr . makeString ("blabla\\ u{7D}bla" );
1087+ StringFormula curlyOpen2BUnicode = makeStringEscaped ("\\ u{7B}" );
1088+ StringFormula curlyClose2BUnicode = makeStringEscaped ("\\ u{7D}" );
1089+ StringFormula multipleCurlys2BUnicode = makeStringEscaped ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
1090+ StringFormula curlyClose2BUnicodeEncased = makeStringEscaped ("blabla\\ u{7D}bla" );
10771091
10781092 assertThatFormula (smgr .contains (empty , empty )).isSatisfiable ();
10791093 assertThatFormula (smgr .contains (empty , a )).isUnsatisfiable ();
@@ -1113,8 +1127,8 @@ public void testStringVariableContains() throws SolverException, InterruptedExce
11131127 StringFormula bUppercase = smgr .makeString ("B" );
11141128 StringFormula bbbbbb = smgr .makeString ("bbbbbb" );
11151129 StringFormula abbbbbb = smgr .makeString ("abbbbbb" );
1116- StringFormula curlyOpen2BUnicode = smgr . makeString ("\\ u{7B}" );
1117- StringFormula curlyClose2BUnicode = smgr . makeString ("\\ u{7D}" );
1130+ StringFormula curlyOpen2BUnicode = makeStringEscaped ("\\ u{7B}" );
1131+ StringFormula curlyClose2BUnicode = makeStringEscaped ("\\ u{7D}" );
11181132
11191133 assertThatFormula (
11201134 bmgr .and (smgr .contains (var1 , empty ), imgr .equal (imgr .makeNumber (0 ), smgr .length (var1 ))))
@@ -1175,10 +1189,10 @@ public void testConstStringIndexOf() throws SolverException, InterruptedExceptio
11751189 StringFormula bbbbbbb = smgr .makeString ("bbbbbbb" );
11761190 StringFormula abbbbbb = smgr .makeString ("abbbbbb" );
11771191 StringFormula abcAndSoOn = smgr .makeString ("abcdefghijklmnopqrstuVwxyz" );
1178- StringFormula curlyOpen2BUnicode = smgr . makeString ("\\ u{7B}" );
1179- StringFormula curlyClose2BUnicode = smgr . makeString ("\\ u{7D}" );
1180- StringFormula multipleCurlys2BUnicode = smgr . makeString ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
1181- StringFormula curlys2BUnicodeWOEscape = smgr . makeString ("\\ u7B\\ u7D" );
1192+ StringFormula curlyOpen2BUnicode = makeStringEscaped ("\\ u{7B}" );
1193+ StringFormula curlyClose2BUnicode = makeStringEscaped ("\\ u{7D}" );
1194+ StringFormula multipleCurlys2BUnicode = makeStringEscaped ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
1195+ StringFormula curlys2BUnicodeWOEscape = makeStringEscaped ("\\ u7B\\ u7D" );
11821196
11831197 IntegerFormula zero = imgr .makeNumber (0 );
11841198 IntegerFormula one = imgr .makeNumber (1 );
@@ -1213,7 +1227,7 @@ public void testStringVariableIndexOf() throws SolverException, InterruptedExcep
12131227 StringFormula var2 = smgr .makeVariable ("var2" );
12141228 IntegerFormula intVar = imgr .makeVariable ("intVar" );
12151229
1216- StringFormula curlyOpen2BUnicode = smgr . makeString ("\\ u{7B}" );
1230+ StringFormula curlyOpen2BUnicode = makeStringEscaped ("\\ u{7B}" );
12171231
12181232 IntegerFormula zero = imgr .makeNumber (0 );
12191233
@@ -1316,9 +1330,9 @@ public void testConstStringSubStrings() throws SolverException, InterruptedExcep
13161330 StringFormula aUppercase = smgr .makeString ("A" );
13171331 StringFormula bUppercase = smgr .makeString ("B" );
13181332 StringFormula bbbbbb = smgr .makeString ("bbbbbb" );
1319- StringFormula curlyOpen2BUnicode = smgr . makeString ("\\ u{7B}" );
1320- StringFormula curlyClose2BUnicode = smgr . makeString ("\\ u{7D}" );
1321- StringFormula multipleCurlys2BUnicode = smgr . makeString ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
1333+ StringFormula curlyOpen2BUnicode = makeStringEscaped ("\\ u{7B}" );
1334+ StringFormula curlyClose2BUnicode = makeStringEscaped ("\\ u{7D}" );
1335+ StringFormula multipleCurlys2BUnicode = makeStringEscaped ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
13221336
13231337 IntegerFormula zero = imgr .makeNumber (0 );
13241338 IntegerFormula one = imgr .makeNumber (1 );
@@ -1363,8 +1377,8 @@ public void testStringSubstringOutOfBounds() throws SolverException, Interrupted
13631377 StringFormula bbbbbb = smgr .makeString ("bbbbbb" );
13641378 StringFormula abbbbbb = smgr .makeString ("abbbbbb" );
13651379
1366- StringFormula multipleCurlys2BUnicode = smgr . makeString ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
1367- StringFormula multipleCurlys2BUnicodeFromIndex1 = smgr . makeString ("\\ u{7D}\\ u{7B}\\ u{7B}" );
1380+ StringFormula multipleCurlys2BUnicode = makeStringEscaped ("\\ u{7B}\\ u{7D}\\ u{7B}\\ u{7B}" );
1381+ StringFormula multipleCurlys2BUnicodeFromIndex1 = makeStringEscaped ("\\ u{7D}\\ u{7B}\\ u{7B}" );
13681382
13691383 assertEqual (smgr .substring (abbbbbb , imgr .makeNumber (0 ), imgr .makeNumber (10000 )), abbbbbb );
13701384 assertEqual (smgr .substring (abbbbbb , imgr .makeNumber (6 ), imgr .makeNumber (10000 )), b );
@@ -1760,11 +1774,11 @@ public void testStringVariableReplaceAllSubstring() throws SolverException, Inte
17601774 public void testStringConcatWUnicode () throws SolverException , InterruptedException {
17611775 StringFormula backslash = smgr .makeString ("\\ " );
17621776 StringFormula u = smgr .makeString ("u" );
1763- StringFormula curlyOpen = smgr . makeString ("\\ u{7B}" );
1777+ StringFormula curlyOpen = makeStringEscaped ("\\ u{7B}" );
17641778 StringFormula sevenB = smgr .makeString ("7B" );
1765- StringFormula curlyClose = smgr . makeString ("\\ u{7D}" );
1779+ StringFormula curlyClose = makeStringEscaped ("\\ u{7D}" );
17661780 StringFormula concat = smgr .concat (backslash , u , curlyOpen , sevenB , curlyClose );
1767- StringFormula complete = smgr . makeString ("\\ u{7B}" );
1781+ StringFormula complete = makeStringEscaped ("\\ u{7B}" );
17681782
17691783 // Concatting parts of unicode does not result in the unicode char!
17701784 assertDistinct (concat , complete );
0 commit comments