def getTypedZ3ValFromIdentifier(identifier, types): if type(identifier) == dict: # FIXME how can we handle this here raise NotSupportedException('Complex objects as base for operations cannot be modelled in z3') if type(identifier) == list: arr = z3.Array('ignore_helper_constant_array_' + randomString(), z3.IntSort(), z3.StringSort()) for i, arg in enumerate(identifier): GLOBAL_CONSTRAINTS.append(z3.Select(arr, i) == createZ3ExpressionFromConstraint(arg, types)) ARRAY_LENGTHS[str(arr.decl())] = len(identifier) return arr cur_types = types GLOBAL_IDENTIFIER.add(identifier) cur_types = infered_types[identifier] # if cur_types == 'object': # infered_types[identifier] = '' # cur_types = '' if identifier.endswith('.length'): return z3.Length(z3.String(identifier[:-7])) if cur_types == 'string': return z3.String(identifier) elif cur_types == 'number': return z3.Int(identifier) elif cur_types == 'boolean': return z3.Bool(identifier) elif cur_types == 'array': return z3.Array(identifier, z3.IntSort(), z3.StringSort()) if 'event.data' in identifier or 'event.origin' in identifier or 'event' == identifier: return z3.String(identifier) else: MAKE_UNSOLVABLE.add(identifier) return z3.String(identifier)
def create_word(data, model): count = 0 input_data = [] output_data = [] numberOfInflections = len(data[0]) for i in range(len(data)): for inflectionIndex, observation in enumerate(data[i]): if len(observation) == 0: continue inflectionCode = chr(ord('A') + inflectionIndex) surface = convert_str(str(model[z3.String('pre' + inflectionCode)]),m) + \ convert_str(str(model[z3.String('pvar' + str(count) + inflectionCode)]),m) + \ convert_str(str(model[z3.String('stem' + str(count) + 'A')]),m) + \ convert_str(str(model[z3.String('var' + str(count) + inflectionCode)]),m) + \ convert_str(str(model[z3.String('suf' + inflectionCode)]),m).strip('"') underlying = convert_str(str(model[z3.String('pre' + inflectionCode)]),m) + \ convert_str(str(model[z3.String('pstem' + str(count) + 'B')]),m) + \ convert_str(str(model[z3.String('stem' + str(count) + 'A')]),m) + \ convert_str(str(model[z3.String('stem' + str(count) + 'B')]),m) + \ convert_str(str(model[z3.String('suf' + inflectionCode)]),m) print(surface) output_data.append(surface) input_data.append(underlying) count += 1 words = list(zip(input_data, output_data)) return words
def generateSelectTemplates(): initZ3() qry_str = "SELECT * FROM student WHERE name='" qry_int = "SELECT * FROM student WHERE id=" # qry = "select sqlite_version(); " z3_name = z3.String("NAME") z3_id = z3.Int("ID") str_constraints = [ z3.Contains(z3_name, ";"), z3.Contains(z3_name, " drop"), z3.Contains(z3_name, " table") ] int_constraints = [z3_id < 1000, z3_id > 25] all_constraints = str_constraints + int_constraints solutions = solveConstraintsWithZ3(all_constraints) for solve in solutions: if solve.isnumeric(): the_qry = qry_int + solve + ";" else: the_qry = qry_str + solve + "';" print("The query:" + the_qry) execQuery(the_qry)
def get_z3_var(vartype, name, datatype_name=None, ctx=None): var = None if isinstance(vartype, z3.z3.DatatypeSortRef): # discrete values datatype var = z3.Const(name, vartype) elif vartype is Types.INT: var = z3.BitVec(name, 32, ctx=ctx) elif vartype is Types.INTEGER: var = z3.Int(name, ctx=ctx) elif vartype is Types.FLOAT: var = z3.FP(name, z3.Float32(), ctx=ctx) elif vartype is Types.REAL: var = z3.Real(name, ctx=ctx) elif vartype is Types.BOOL: var = z3.Bool(name, ctx=ctx) elif vartype is Types.STRING: var = z3.String(name, ctx=ctx) elif isinstance(vartype, list): datatype = _get_datatype_from_list(vartype, datatype_name) var = z3.Const(name, datatype) vartype = datatype else: raise ValueError( f"I do not know how to create a z3-variable for type {vartype} (name: {name})" ) assert var is not None, f"Var wasn't converted: vartype: {vartype}, name: {name}" var.type = vartype return var
def transformNonBooleanLazyEvaluations(var): if z3.is_or(var): # in this case it needs to be the first child since we are using it as a first child when coercing any expression to bool left = var.children()[0].children()[0] if len(var.children()[1].children()) == 0: if str(var.children()[1]) == 'False': return left else: raise Exception('Why would the lazy side of the or be a truthy value?') else: right = var.children()[1].children()[0] sub = z3.String('__ignore({}||{})'.format(str(left), str(right))) GLOBAL_CONSTRAINTS.append(z3.Or(left == sub, right == sub)) return sub if z3.is_and(var): # FIXME what about the first child # in this case it needs to be the first child since we are using it as a first child when coercing any expression to bool right = var.children()[1].children()[0] # this is by construction the not null of the first GLOBAL_CONSTRAINTS.append(var.children()[0]) return right return var
def __parse_literal__(self, symbol_node: jcmuta.SymbolNode): """ :param symbol_node: :return: literal of z3.String """ unique_name = self.__unique_name__(symbol_node) return z3.String(unique_name)
def execCosntraintManually(): initZ3() ''' initialize variables ''' z_sp = z3.Int('sp') z_l = z3.Int('l') z_buf = z3.String('buf') ''' this one is not solvable as contradicting predicates exist ''' all_constraints = [ z3.And( z3.Not( z_sp == -1 ) , z_l > 32 , z3.Contains( z_buf, "%n" ) ) , z3.And( z3.Not( z_sp == -1 ) , z_l > 32 , z3.Not( z3.Contains( z_buf, "%n" ) )), z3.And( z3.Not( z_sp == -1 ) , z_l <= 32 , z3.Contains( z_buf, "%n" ) ) , z3.And( z3.Not( z_sp == -1 ) , z_l <= 32 , z3.Not( z3.Contains( z_buf, "%n" ) )) , z3.And( z_sp == -1 , z_l > 32 , z3.Contains( z_buf, "%n" ) ) , z3.And( z_sp == -1 , z_l > 32 , z3.Not( z3.Contains( z_buf, "%n" ) )) , z3.And( z_sp == -1 , z_l <= 32 , z3.Contains( z_buf, "%n" ) ) , z3.And( z_sp == -1 , z_l <= 32 , z3.Not( z3.Contains( z_buf, "%n" ) )) ] ''' this one is solvable ''' all_constraints = [ z3.And( z3.Not( z_sp == -1 ) , z_l > 32 , z3.Contains( z_buf, "%n" ) ) , z3.And( z3.Not( z_sp == -1 ) , z_l < 132 , z3.Contains( z_buf, "lol" ) ) ] solveConstraintsWithZ3( all_constraints )
def dimvar(var, idx): newvar = z3.String(str(uuid.uuid4())) # todo, split is now harcoded '.' -> this could also be a variable a = z3.parse_smt2_string( '(assert (seq.in.re a (re.++ (re.loop (re.++ (re.* (re.union (re.range " " "-") (re.range "/" "~") ) ) (str.to.re ".")) %d 0 ) (str.to.re b) (re.* (re.++ (str.to.re ".") (re.* (re.range " " "~")) )) )))' % (idx), decls={ 'a': var, 'b': newvar }) return (a, newvar)
def binary_in(left, right): if right.decl().kind() == z3.Z3_OP_UNINTERPRETED and z3.is_string_value(left): identifer = str(right.decl()) accessed = left.as_string() st = z3.String(identifer + '.' + accessed) GLOBAL_CONSTRAINTS.append(createZ3ForBool(st)) else: # When this is not the case we cannot enforce any constraints so it is up to the application ot have these properties pass return z3.BoolVal(True)
def multi_distinguish(self, regexes): start = time.time() # Problem: cannot distinguish more than 4 regexes at once: it takes forever. # Solution: use only 4 randomly selected regexes for the SMT maximization, # and then add the others to the solution. if len(regexes) <= 4: selected_regexes = regexes others = [] else: random.seed('regex') random.shuffle(regexes) selected_regexes = regexes[:4] others = regexes[4:] solver = z3.Optimize() z3_regexes = [] for regex in selected_regexes: z3_regex = self._toz3.eval(regex) z3_regexes.append(z3_regex) dist = z3.String("distinguishing") # solver.add(z3.Length(dist) <= 6) ro_z3 = [] for i, z3_regex in enumerate(z3_regexes): ro = z3.Bool(f"ro_{i}") ro_z3.append(ro) solver.add(ro == z3.InRe(dist, z3_regex)) # ro_z3[i] == true if dist matches regex[i]. big_or = [] for ro_i, ro_j in combinations(ro_z3, 2): big_or.append(z3.Xor(ro_i, ro_j)) solver.add_soft(z3.Xor(ro_i, ro_j)) solver.add(z3.Or(big_or)) # at least one regex is distinguished if solver.check() == z3.sat: # print(solver.model()) print("took", round(time.time() - start, 2), "seconds") keep_if_valid = [] keep_if_invalid = [] dist_input = str(solver.model()[dist]).strip('"') for i, ro in enumerate(ro_z3): if solver.model()[ro]: keep_if_valid.append(selected_regexes[i]) else: keep_if_invalid.append(selected_regexes[i]) smallest_regex = min(selected_regexes, key=lambda r: len(self._printer.eval(r))) return dist_input, keep_if_valid, keep_if_invalid, others else: return None, None, None, None
def binary_instanceof(left, right): if z3.is_string_value(right) and right.as_string() == '': right = None if left.decl().kind() == z3.Z3_OP_UNINTERPRETED: typ_val = z3.String('type:' + str(left.decl())) if right is None: return typ_val == z3.StringVal('undefined') else: raise Exception( 'we have not yet seen', right, 'as type') else: raise Exception( 'We probably need to introduce intermediary variables here and assert that their type is something specific')
def solve(self, state, conditions): self._state = state logger.log('CONDITIONS', json.dumps(conditions, indent=4), Logger.PROGRESS) solver = z3.Solver() self._solver = solver logger.log('BASE VARS', json.dumps(state._lookup_map, indent=4), Logger.PROGRESS) for var_id, var in state._lookup_map.iteritems(): if var['type'] in ('string', 'unknown'): # Type could be unknown if newly discovered and we did not get a typehint yet self._base_var[var_id] = z3.String(var_id) elif var['type'] == 'integer': self._base_var[var_id] = z3.Int(var_id) else: logger.log( 'Ignoring unknown type %s while passing to Z3' % var['type'], '', Logger.DEBUG) z3_solved = False try: for condition in conditions: solver.add(self.solve_rec(condition)) solve_result = solver.check() logger.log('SOLVER RESULT', solve_result, Logger.PROGRESS) if solve_result == z3.sat: z3_solved = True model = solver.model() logger.log('SOLVER MODEL', model, Logger.PROGRESS) for var_id, var in self._base_var.iteritems(): var_ref = self._state.get_var_ref(var_id) var_ref['value'] = self.get_z3_value(model[var]) except z3.z3types.Z3Exception as e: print 'Got Z3Exception: %s' % str(e)
def coerceTypesIfPossible(var, other_var): if z3.is_or(other_var) and not z3.is_bool(var): other_var = transformNonBooleanLazyEvaluations(other_var) if z3.is_or(var) and not z3.is_bool(other_var): var = transformNonBooleanLazyEvaluations(var) if z3.is_and(other_var) and not z3.is_bool(var): other_var = transformNonBooleanLazyEvaluations(other_var) if z3.is_and(var) and not z3.is_bool(other_var): var = transformNonBooleanLazyEvaluations(var) if var.decl().kind() == z3.Z3_OP_UNINTERPRETED: if z3.is_bool(other_var) and not z3.is_bool(var): infered_types[str(var)] = 'boolean' return z3.Bool(str(var)), other_var if z3.is_string(other_var) and not z3.is_string(var): if other_var.as_string() == '': # we probably dont want to coerce in this specific case as this is merely a non empty check if z3.is_bool(var): return var, z3.BoolVal(False) if z3.is_int(var): return var, z3.IntVal(0) else: infered_types[str(var)] = 'string' return z3.String(str(var)), other_var if z3.is_int(other_var) and not z3.is_int(var): infered_types[str(var)] = 'number' return z3.Int(str(var)), other_var elif var.decl().kind() == z3.Z3_OP_UNINTERPRETED: if z3.is_bool(var): infered_types[str(var)] = 'boolean' if z3.is_string(var): infered_types[str(var)] = 'string' if z3.is_int(var): infered_types[str(var)] = 'number' else: # this means that it is non-interpreted and we need to coerce other var to the type of var if z3.is_string(var) and z3.is_int_value(other_var): other_var = z3.StringVal(str(other_var)) if z3.is_arith(var) and z3.is_string(other_var): other_var = z3.IntVal(int(other_var.as_string())) return var, other_var
def string_search(x, args): new_val = z3.String('__ignore_search_helper_' + randomString()) regex = args[0] startsWith = False endsWith = False if regex[0] == '^': startsWith = True regex = regex[1:] if regex[-1] == '$': endsWith = True regex = regex[:-1] GLOBAL_CONSTRAINTS.append(z3.InRe(new_val, regex_to_z3(args[0]))) if startsWith and endsWith: # we need to return the index which should be 0 iff it matches GLOBAL_CONSTRAINTS.append(x == new_val) return z3.IntVal(0) elif startsWith: GLOBAL_CONSTRAINTS.append(z3.PrefixOf(new_val, x)) elif endsWith: GLOBAL_CONSTRAINTS.append(z3.SuffixOf(new_val, x)) return z3.IndexOf(x, new_val, 0)
def set_value(self, value): if self.z3_enabled: import z3 if value is None: raise ValueError('value cannot be none in assignment') self.value = value if self.variable.python_type is None: self.z3_obj = None return if not isinstance(value, self.variable.python_type): raise ValueError( f'value is not of type {self.variable.python_type}') if self.z3_enabled: if self.variable.python_type == int: self.z3_obj = z3.Int(int(value)) elif self.variable.python_type == bool: self.z3_obj = z3.Bool(bool(value)) elif self.variable.python_type == float: self.z3_obj = z3.Float(float(value)) elif self.variable.python_type == str: self.z3_obj = z3.String(str(value)) else: raise ValueError('invalid python type provided')
def create_word(data,model): input_data = [] output_data = [] I = len(data[0]) for count in range(len(data)): surface = [convert_str(str(model[z3.String('unch1' + str(count) + chr(ord('A') + i))]),m) + \ convert_str(str(model[z3.String('var' + str(count) + chr(ord('A') + i))]),m) + \ convert_str(str(model[z3.String('unch2' + str(count) + chr(ord('A') + i))]),m) for i in range(I) ] underlying = [convert_str(str(model[z3.String('unch1' + str(count) + chr(ord('A') + i))]),m) + \ convert_str(str(model[z3.String('ch' + str(count) + chr(ord('A') + i))]),m) + \ convert_str(str(model[z3.String('unch2' + str(count) + chr(ord('A') + i))]),m) for i in range(I) ] nur = [""]*I ns = [""]*I for i in range(I): if len(surface[i]) < len(underlying[i]) and not(any(elem in diacritics for elem in surface[i])) and not(any(elem in diacritics for elem in underlying[i])): ns[i] = insert_or_delete(surface[i],underlying[i],'∅') for i in range(I): if len(surface[i]) > len(underlying[i]) and not(any(elem in diacritics for elem in surface[i])) and not(any(elem in diacritics for elem in underlying[i])): nur[i] = insert_or_delete(underlying[i],surface[i],'∅') for i in range(I): if ns[i] != "": output_data.append(ns[i]) else: output_data.append(surface[i]) for i in range(I): if nur[i] != "": input_data.append(nur[i]) else: input_data.append(underlying[i]) words = list(zip(list(map(lambda x: x.replace('"',""), input_data)),list(map(lambda x: x.replace('"',""), output_data)))) return words
def unary_typeof(val): typo = z3.String('type:' + str(val.decl())) return z3.String('type:' + str(val.decl()))
def createZ3ExpressionFromConstraint(constraint, types, emitParentConstraint=True): if type(constraint) != dict: if type(constraint) == str: return z3.StringVal(constraint) if type(constraint) == int: return z3.IntVal(constraint) if type(constraint) == bool: return z3.BoolVal(constraint) if constraint is None: return None raise Exception('Dealing with non-int non-string basic values, aborting!', constraint) if 'type' not in constraint: if 'isRealValue' in constraint: if 'value' in constraint: var = getZ3ValFromJSVal(constraint['value']) elif 'val' in constraint: var = getZ3ValFromJSVal(constraint['val']) else: raise Exception('Should not encounter realValue without reference to the real value...') else: if 'identifier' in constraint: var = getTypedZ3ValFromIdentifier(constraint['identifier'], types) else: # probably the empty object when we have something || {} return None for op in constraint['ops']: if 'val' not in op: op['val'] = '' if op['type'] == 'ops_on_parent_element': val = resolveOpsOnParent(op, types) if z3.is_array(val): accesed = constraint['identifier'].split('.')[-1] if accesed == 'length': raise NotSupportedException( 'z3 cannot use the length of arrays due to their representation as functions') if int(accesed) < 0 and str(val.decl()) in ARRAY_LENGTHS: var = z3.Select(val, ARRAY_LENGTHS[str(val.decl())] + int(accesed)) else: var = z3.Select(val, int(accesed)) elif val is not None: key = str(val) if key not in identifier_substitutions: identifier_substitutions[key] = '__substitute_values_' + randomString() identifier = identifier_substitutions[key] GLOBAL_CONSTRAINTS.append(val == z3.StringVal(identifier)) accesed = constraint['identifier'].split('.')[-1] if accesed == 'length': var = z3.Length(z3.String(identifier)) else: var = z3.String(identifier + '.' + accesed) # GLOBAL_CONSTRAINTS.append(var == val) elif op['type'] == 'member_function': var = transformNonBooleanLazyEvaluations(var) if op['function_name'] in StringFunctions: var = StringFunctions[op['function_name']](var, op['args']) elif op['function_name'] in ArrayFunctions: var = ArrayFunctions[op['function_name']](var, op['args']) else: if op['function_name'] in ['call', 'apply', 'bind']: raise NotSupportedException('We do not support function calls over function pointer') raise Exception('String function not supported! ' + op['function_name']) elif op['type'] == 'Binary': other_var = createZ3ExpressionFromConstraint(op['val'], types) if other_var is None: # this is the case when we compare something to null if op['op'] == '===' or op['op'] == '==': var = createZ3ForBool(var) var = z3.Not(var) continue var, other_var = coerceTypesIfPossible(var, other_var) changed = checkForTypeEqualToString(var, other_var, op) if changed is not None: var = changed elif op['side'] == 'left': var = BinaryFunctions[op['op']](var, other_var) elif op['side'] == 'right': var = BinaryFunctions[op['op']](other_var, var) else: var = BinaryFunctions[op['op']](var, other_var) elif op['type'] == 'Unary': var = UnaryFunctions[op['op']](var) elif op['type'] == 'iterator': if z3.is_array(var): var = z3.Select(var, op['accessed_elem']) else: raise Exception('This should always be an array', var, infered_types) elif op['type'] == 'external_function': if op['function_name'] == 'JSON.parse': infered_types[constraint['identifier']] = 'JSON' var = z3.String(constraint['identifier']) else: logging.debug('Arbitrary external functions not yet support ' + op['function_name']) elif op['type'] == 'Logical': if op['side'] == 'left' or op['side'] == 'both': l_c = createZ3ForBool(var) r_c = createZ3ForBool(createZ3ExpressionFromConstraint(op['val'], types)) else: l_c = createZ3ForBool(createZ3ExpressionFromConstraint(op['val'], types)) r_c = createZ3ForBool(var) if l_c is None or r_c is None: if l_c is None: var = r_c if r_c is None: var = l_c continue if op['op'] == '&&': var = z3.And(l_c, r_c) else: var = z3.Or(l_c, r_c) else: logging.debug('Not supported type ' + op['type']) return var elif constraint['type'] == 'Logical': l_c = createZ3ForBool(createZ3ExpressionFromConstraint(constraint['l_val'], types)) r_c = createZ3ForBool(createZ3ExpressionFromConstraint(constraint['r_val'], types)) if l_c is None or r_c is None: return l_c or r_c if constraint['op'] == '&&': return z3.And(l_c, r_c) else: return z3.Or(l_c, r_c) elif constraint['type'] == 'Binary': return BinaryFunctions[constraint['op']](createZ3ExpressionFromConstraint(constraint['l_val'], types), createZ3ExpressionFromConstraint(constraint['r_val'], types)) elif constraint['type'] == 'Unary': return UnaryFunctions[constraint['op']](createZ3ExpressionFromConstraint(constraint['val'], types)) else: raise Exception('Unexpected constraint type')
def solveConstrains(constraints, types, shouldPrint=True): if type(types) == dict: addTypesFromTaintAnalysis('event', types['event']) else: for [iden, typo] in types: if type(iden) == str: infered_types[iden] = typo logging.debug(infered_types) c = True for constraint in constraints: cc = createZ3ForIf(constraint, types) logging.debug(cc) if z3.is_int(cc): cc = cc != 0 elif z3.is_string(cc): cc = cc != z3.StringVal('') c = z3.And(c, cc) for cc in GLOBAL_CONSTRAINTS: logging.debug(cc) c = z3.And(c, cc) for type_info in infered_types: if infered_types[type_info] == '': continue cc = z3.String('type:' + type_info) == z3.StringVal(infered_types[type_info]) logging.debug(cc) c = z3.And(c, cc) for identifier in MAKE_UNSOLVABLE: cc = z3.String(identifier) == z3.StringVal('') logging.debug(cc) c = z3.And(c, cc) # solver = z3.SolverFor('QF_LIA') solver = z3.Solver() solver.add(c) r = solver.check() if r == z3.unsat: if shouldPrint: eprint("no solution") return 'unsat' elif r == z3.unknown: if shouldPrint: eprint("failed to solve") return 'unsat' try: eprint(solver.model()) except Exception: return else: model = solver.model() assignement = dict() types = dict() for decl in model.decls(): if str(decl) == 'event': continue if str(decl)[:5] == 'type:': types[str(decl)[5:]] = AssignementsToString(model.get_interp(decl), model) else: assignement[str(decl)] = AssignementsToString(model.get_interp(decl), model) for identifier in GLOBAL_IDENTIFIER: if identifier not in assignement: if identifier == 'event': continue logging.debug('Adding empty shizzle') assignement[identifier] = '' logging.debug(GLOBAL_IDENTIFIER) if shouldPrint: print(json.dumps({'assignements': assignement, 'types': types})) return {'assignements': assignement, 'types': types}
def distinguish2(self, r1, r2): global use_derivatives solver = z3.Solver() solver.set('random_seed', 7) solver.set('sat.random_seed', 7) if use_derivatives: try: solver.set('smt.seq.use_derivatives', True) solver.check() except: pass z3_r1 = self._toz3.eval(r1[0]) z3_r2 = self._toz3.eval(r2[0]) dist = z3.String("distinguishing") ro_1 = z3.Bool(f"ro_1") solver.add(ro_1 == z3.InRe(dist, z3_r1)) ro_2 = z3.Bool(f"ro_2") solver.add(ro_2 == z3.InRe(dist, z3_r2)) solver.add(ro_1 != ro_2) if solver.check() == z3.sat: if len(r1[2][0]) == 0 and len(r2[2][0]) == 0: dist_input = solver.model()[dist].as_string() if solver.model()[ro_1]: return dist_input, [r1], [r2], [] else: return dist_input, [r2], [r1], [] # Find dist_input that respects conditions r1_str = self._printer.eval(r1[0], captures=r1[2][1]) r1_conditions = list(map(lambda c: " ".join(map(str, c)), r1[2][0])) r2_str = self._printer.eval(r2[0], captures=r2[2][1]) r2_conditions = list(map(lambda c: " ".join(map(str, c)), r2[2][0])) while True: dist_input = solver.model()[dist].as_string() match = re.fullmatch(r1_str, dist_input) if match is not None and check_conditions( r1_conditions, match): break match = re.fullmatch(r2_str, dist_input) if match is not None and check_conditions( r2_conditions, match): break solver.add(dist != z3.StringVal(dist_input)) if not solver.check() == z3.sat: return None, None, None, None if solver.model()[ro_1]: return dist_input, [r1], [r2], [] else: return dist_input, [r2], [r1], [] else: return None, None, None, None
def __parse_literal__(self, symbol_node: jcmuta.SymbolNode): return z3.String(self.__new_default_name__(symbol_node))
# print res # # ERR_PERM = res.sort().accessor(1, 1)(res).sort().constructor(0)() # # s = z3.Solver() # # s.add(s0 != s1) # # s.add(res.sort().recognizer(0)(res)) # s.add(res.sort().recognizer(1)(res)) # s.add(res.sort().accessor(1, 1)(res) == ERR_PERM) # print 'Check:', s.check() stateSort = sym.z3_sort(stateType) current_state = z3.Const('s_init', stateSort) ## Invariant: GETATTR cannot return both ERR_STALE and OK in the same state fh = z3.String("getattr_fh") #getattr_step, _ = m.get_term("getattr_step") #step = jc.reduce({ # 'what': 'expr:apply', # 'args': [fh], # 'func': getattr_step, #}) #_, res0 = sym.proc(step, current_state) #_, res1 = sym.proc(step, current_state) #s = z3.Solver() #s.add(res0.sort().recognizer(0)(res0)) #s.add(res1.sort().recognizer(1)(res1)) #assert(s.check() == z3.unsat) def lift_ftype(t):
def generate_constraints(data): inflections = len(data[0]) count = 0 cost_constraint = 0 cc = [0] * inflections constraints = [] for example in data: suffixes = [ z3.String('suf' + chr(ord('A') + i)) for i in range(inflections) ] prefixes = [ z3.String('pre' + chr(ord('A') + i)) for i in range(inflections) ] stemA = z3.String('stem' + str(count) + 'A') variables = [ z3.String('var' + str(count) + chr(ord('A') + i)) for i in range(inflections) ] pvariables = [ z3.String('pvar' + str(count) + chr(ord('A') + i)) for i in range(inflections) ] pstemB = z3.String('pstem' + str(count) + 'B') stemB = z3.String('stem' + str(count) + 'B') sc = [ z3.Int('sc' + str(count) + chr(ord('A') + i)) for i in range(inflections) ] pc = [ z3.Int('pc' + str(count) + chr(ord('A') + i)) for i in range(inflections) ] for v in variables: constraints.append(z3.Length(v) <= 1) for v in pvariables: constraints.append(z3.Length(v) <= 1) for i in range(inflections): if len(example[i]) > 0: print(example[i], convert_ipa(example[i], m)) constraints.append( z3.StringVal(convert_ipa(example[i], m)) == z3.Concat( prefixes[i], pvariables[i], stemA, variables[i], suffixes[i])) for v in variables: constraints.append(z3.Length(stemB) == z3.Length(v)) for v in pvariables: constraints.append(z3.Length(pstemB) == z3.Length(v)) for i in range(inflections): constraints.append(z3.If(stemB == variables[i], 0, 1) == sc[i]) for i in range(inflections): constraints.append(z3.If(pstemB == pvariables[i], 0, 1) == pc[i]) for cost_variable in sc + pc: cost_constraint = cost_constraint + cost_variable count += 1 return constraints, cost_constraint
def _gen_string_var(self): x = z3.String('_x_{}'.format(self.string_var_count)) self.string_var_count += 1 return x
solver.pop() def check_formulae(solver, *formulae): with solver_frame(solver): solver.add(*formulae) result = solver.check() if result == z3.sat: return (z3.sat, solver.model()) else: return (result, None) is_https = z3.Bool('is_https') is_http = z3.Bool('is_http') proto = z3.String('proto') proto_delimiter = z3.String('proto_delimiter') domain = z3.String('domain') fqdn = z3.String('fqdn') root_domain = z3.String('root_domain') base_url = proto + '://' + fqdn unknown_string = z3.String('solution') z3_byte_to_ord = {z3.StringVal(bytes([ii])): ii for ii in range(256)} def z3_str_to_bytes(zs: z3.StringVal): ll = z3.simplify(z3.Length(zs)).as_long() return bytes([z3_byte_to_ord[z3.simplify(zs[ii])] for ii in range(ll)]) def z3_str_to_str(zs: z3.StringVal):
def generate_constraints(data): I = len(data[0]) # number of inflections count = 0 cost_constraint = 0 column_cost = [0]*I length_c = 0 constraints = [] for example in data: suffixes = [z3.String('suf' + chr(ord('A') + i)) for i in range(I) ] prefixes = [z3.String('pre' + chr(ord('A') + i)) for i in range(I) ] # preA = z3.String('preA') # preB = z3.String('preB') # sufA = z3.String('sufA') # sufB = z3.String('sufB') stem = z3.String('stem' + str(count)) # 1 is associated with the prefix unch1 = [z3.String('unch1' + str(count) + chr(ord('A') + i)) for i in range(I) ] # 2 is associated with the suffix unch2 = [z3.String('unch2' + str(count) + chr(ord('A') + i)) for i in range(I) ] # unchA1 = z3.String('unch' + str(count) + 'A') # unchA2 = z3.String('unch' + str(count) + 'B') # unchB1 = z3.String('unch' + str(count) + 'C') # unchB2 = z3.String('unch' + str(count) + 'D') ch = [z3.String('ch' + str(count) + chr(ord('A') + i)) for i in range(I) ] var = [z3.String('var' + str(count) + chr(ord('A') + i)) for i in range(I) ] # varA = z3.String('var' + str(count) + 'A') # varB = z3.String('var' + str(count) + 'B') # scA = z3.Int('sc'+str(count)+'A') # scB = z3.Int('sc'+str(count)+'B') sc = [z3.Int('sc' + str(count) + chr(ord('A') + i)) for i in range(I) ] lc = z3.Int('l'+str(count)) for v in var: constraints.append(z3.Length(v) <= 1) # constraints.append(z3.Length(varA) <= 1) # constraints.append(z3.Length(varB) <= 1) for i in range(I): constraints.append(z3.Concat(prefixes[i],stem,suffixes[i]) == z3.Concat(unch1[i],ch[i],unch2[i])) # constraints.append(z3.Concat(preA,stem,sufA) == z3.Concat(unchA1,chA,unchA2)) # constraints.append(z3.Concat(preB,stem,sufB) == z3.Concat(unchB1,chB,unchB2)) for i in range(I): if len(example[i]) == 0: continue constraints.append(z3.StringVal(convert_ipa(example[i],m)) == z3.Concat(unch1[i],var[i],unch2[i])) # constraints.append(z3.StringVal(convert_ipa(example[0],m)) == z3.Concat(unchA1,varA,unchA2)) # constraints.append(z3.StringVal(convert_ipa(example[1],m)) == z3.Concat(unchB1,varB,unchB2)) constraints.append(z3.Length(stem) == lc) for i in range(I): constraints.append(z3.If(ch[i] == var[i],0,1) == sc[i]) #constraints.append(z3.If(chB == varB,0,1) == scB) length_c = length_c + lc for i in range(I): constraints.append(sc[i] <= 1) cost_constraint = cost_constraint + sum(sc) for i in range(I): column_cost[i] = column_cost[i] + sc[i] count += 1 return constraints, cost_constraint, column_cost