While StringV's are mostly stored in .args[0], we store the true length of the string in .args[1]; the extra bytes are implicit null bytes at the end of .args[0].
For example:
claripy.StringV("a", 3") represents a\0\0.
This information is not passed to z3 in any capacity.
If z3 does not allow null bytes within strings then perhaps we should disallow implicit trailing nulls in claripy, not use strings in z3, or find some hybrid String/BV approach?
Description
StringV
's with implicit trailing zero values not stored explicitly in.args[0]
do not have those trailing zeros passed toz3
.We do this conversion here: https://github.com/angr/claripy/blob/728cc9d1bedc7c19aa1a6a318262e83e69be0a00/claripy/backends/backend_z3.py#L355 Note no where do we use
ast.args[1]
.While
StringV
's are mostly stored in.args[0]
, we store the true length of the string in.args[1]
; the extra bytes are implicit null bytes at the end of.args[0]
.For example:
claripy.StringV("a", 3")
representsa\0\0
.This information is not passed to z3 in any capacity.
Steps to reproduce the bug
This yields:
c_uint(1)
If z3 supports null bytes in strings this should yield
c_uint(10)
after https://github.com/Z3Prover/z3/issues/6442 is resolved andc_uint(77)
until then.Environment
Claripy master: https://github.com/angr/claripy/commit/bd9b5975787398ee72022ab4cbdc1609ac0dea6d
Additional context
If
z3
strings allow null bytes within them, the fix would be to replaceast.args[0]
withast.args[0].ljust(ast.args[1], '\0')
in https://github.com/angr/claripy/blob/728cc9d1bedc7c19aa1a6a318262e83e69be0a00/claripy/backends/backend_z3.py#L355If
z3
does not allow null bytes within strings then perhaps we should disallow implicit trailing nulls in claripy, not use strings in z3, or find some hybrid String/BV approach?