Repository navigation
Escape non-ASCII characters in SMT-LIB string literals - #1850
Draft
agusaldasoro wants to merge 1 commit into
Draft
agusaldasoro wants to merge 1 commit into
agusaldasoro wants to merge 1 commit into
Conversation
agusaldasoro
added this pull request to stack #1839
October 7, 2026 15:57
…m from the Z3 model
arcuri82
force-pushed
the
fix/smtlib-non-ascii-strings
branch
from
October 7, 2026 19:20
3ba31d5 to
726a693
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #1838.
Problem
Z3 reads an SMT-LIB string literal byte by byte, and it always prints characters outside printable ASCII as
\u{X}escapes. A literal written as raw UTF-8 therefore changes on the round trip.'ORDINÆR'was sent as 8 bytes, and the model returned"ORDIN\u{c3}\u{86}R", one escape per UTF-8 byte.SMTResultParserused that text as the value.So a row generated to satisfy
CHECK (kategori IN ('ORDINÆR', 'EØS'))broke that same CHECK, and the database rejected its INSERT. The same happened to a row forWHERE kategori = 'EØS'. Enumerations with such values are common in non-English schemas: in familie-ba-sak (EMB), 29 of the 48 CHECK constraints have one.A backslash had a related problem. Z3 reads
\u{...}inside a literal as an escape, so a value containing that text was changed too.Fix
SMTConditionVisitor.stringLiteralwrites every code point outside printable ASCII, and the backslash, as\u{X}. Z3 then reads the literal as the same sequence of characters the query has.SMTResultParser.unescapeStringdecodes\u{X}back into the character, after turning""into"as before (Escape quotes in SMT-LIB string literals #1838).Tests
StringLiteralTranslationTest:NAME = 'ORDINÆR \ 😀'is written as"ORDIN\u{c6}R \u{5c} \u{1f600}".SMTResultParserTest.testParseComposedTypeWithUnicodeEscapes: escapes are decoded, including a code point outside the BMP and an escaped backslash.New
NonAsciiLiteralSolvingTest(H2, Z3 Docker): for a table with that CHECK, the solved row is inserted and satisfies the query. It covers a query that only fixes the id and one that fixes the value. On Escape quotes in SMT-LIB string literals #1838 both cases fail.H2 2.x reports the constraint with unicode-escaped literals (
IN(U&'ORDIN\00c6R', ...)), which the CHECK parser does not read. PostgreSQL and H2 1.4 report the characters as they are, so the test gives the constraint in that form. H2 still enforces the real constraint on insertion.All tests in
core-extra/solverand underorg.evomaster.core.database.sql.solverpass.