3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

fix a couple hundred deref-after-free bugs due to .c_str() on a temporary string

This commit is contained in:
Nuno Lopes 2020-07-11 20:24:45 +01:00
parent 48a9defb0d
commit 23e6adcad3
64 changed files with 248 additions and 229 deletions

View file

@ -126,6 +126,7 @@ public:
explicit parameter(rational && r) : m_kind(PARAM_RATIONAL), m_rational(alloc(rational, std::move(r))) {}
explicit parameter(double d):m_kind(PARAM_DOUBLE), m_dval(d) {}
explicit parameter(const char *s):m_kind(PARAM_SYMBOL), m_symbol(symbol(s)) {}
explicit parameter(const std::string &s):m_kind(PARAM_SYMBOL), m_symbol(symbol(s)) {}
explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {}
parameter(parameter const&);
@ -984,6 +985,7 @@ struct builtin_name {
decl_kind m_kind;
symbol m_name;
builtin_name(char const * name, decl_kind k) : m_kind(k), m_name(name) {}
builtin_name(const std::string &name, decl_kind k) : m_kind(k), m_name(name) {}
};
/**

View file

@ -36,12 +36,12 @@ format * smt2_pp_environment::pp_fdecl_name(symbol const & s, unsigned & len, bo
if (is_smt2_quoted_symbol(s)) {
std::string str = mk_smt2_quoted_symbol(s);
len = static_cast<unsigned>(str.length());
return mk_string(m, str.c_str());
return mk_string(m, str);
}
else if (s.is_numerical()) {
std::string str = s.str();
len = static_cast<unsigned>(str.length());
return mk_string(m, str.c_str());
return mk_string(m, str);
}
else if (!s.bare_str()) {
len = 4;
@ -114,7 +114,7 @@ format * smt2_pp_environment::pp_fdecl_params(format * fname, func_decl * f) {
fs.push_back(mk_int(get_manager(), f->get_parameter(i).get_int()));
else if (f->get_parameter(i).is_rational()) {
std::string str = f->get_parameter(i).get_rational().to_string();
fs.push_back(mk_string(get_manager(), str.c_str()));
fs.push_back(mk_string(get_manager(), str));
}
else
fs.push_back(pp_fdecl_ref(to_func_decl(f->get_parameter(i).get_ast())));
@ -177,7 +177,7 @@ format * smt2_pp_environment::pp_bv_literal(app * t, bool use_bv_lits, bool bv_n
format * vf;
if (!use_bv_lits) {
string_buffer<> buf;
buf << "(_ bv" << val.to_string().c_str() << " " << bv_size << ")";
buf << "(_ bv" << val.to_string() << ' ' << bv_size << ')';
vf = mk_string(get_manager(), buf.c_str());
}
else {
@ -238,30 +238,30 @@ format * smt2_pp_environment::pp_float_literal(app * t, bool use_bv_lits, bool u
string_buffer<> buf;
VERIFY(get_futil().is_numeral(t, v));
if (fm.is_nan(v)) {
buf << "(_ NaN " << v.get().get_ebits() << " " << v.get().get_sbits() << ")";
buf << "(_ NaN " << v.get().get_ebits() << ' ' << v.get().get_sbits() << ')';
return mk_string(m, buf.c_str());
}
else if (fm.is_pinf(v)) {
buf << "(_ +oo " << v.get().get_ebits() << " " << v.get().get_sbits() << ")";
buf << "(_ +oo " << v.get().get_ebits() << ' ' << v.get().get_sbits() << ')';
return mk_string(m, buf.c_str());
}
else if (fm.is_ninf(v)) {
buf << "(_ -oo " << v.get().get_ebits() << " " << v.get().get_sbits() << ")";
buf << "(_ -oo " << v.get().get_ebits() << ' ' << v.get().get_sbits() << ')';
return mk_string(m, buf.c_str());
}
else if (fm.is_pzero(v)) {
buf << "(_ +zero " << v.get().get_ebits() << " " << v.get().get_sbits() << ")";
buf << "(_ +zero " << v.get().get_ebits() << ' ' << v.get().get_sbits() << ')';
return mk_string(m, buf.c_str());
}
else if (fm.is_nzero(v)) {
buf << "(_ -zero " << v.get().get_ebits() << " " << v.get().get_sbits() << ")";
buf << "(_ -zero " << v.get().get_ebits() << ' ' << v.get().get_sbits() << ')';
return mk_string(m, buf.c_str());
}
else if (use_float_real_lits)
{
buf << "((_ to_fp " << v.get().get_ebits() << " " <<
buf << "((_ to_fp " << v.get().get_ebits() << ' ' <<
v.get().get_sbits() << ") RTZ " <<
fm.to_string(v).c_str() << ")";
fm.to_string(v) << ')';
return mk_string(m, buf.c_str());
}
else {
@ -301,9 +301,8 @@ format * smt2_pp_environment::mk_neg(format * f) const {
format * smt2_pp_environment::mk_float(rational const & val) const {
SASSERT(val.is_nonneg());
SASSERT(val.is_int());
std::string s = val.to_string();
s += ".0";
return mk_string(get_manager(), s.c_str());
std::string s = val.to_string() + ".0";
return mk_string(get_manager(), s);
}
format * smt2_pp_environment::pp_arith_literal(app * t, bool decimal, unsigned decimal_prec) {
@ -314,11 +313,11 @@ format * smt2_pp_environment::pp_arith_literal(app * t, bool decimal, unsigned d
if (u.is_numeral(t, val, is_int)) {
if (is_int) {
if (val.is_nonneg()) {
return mk_string(get_manager(), val.to_string().c_str());
return mk_string(get_manager(), val.to_string());
}
else {
val.neg();
return mk_neg(mk_string(get_manager(), val.to_string().c_str()));
return mk_neg(mk_string(get_manager(), val.to_string()));
}
}
else {
@ -332,7 +331,7 @@ format * smt2_pp_environment::pp_arith_literal(app * t, bool decimal, unsigned d
else if (decimal) {
std::ostringstream buffer;
val.display_decimal(buffer, decimal_prec);
vf = mk_string(get_manager(), buffer.str().c_str());
vf = mk_string(get_manager(), buffer.str());
}
else {
format * buffer[2] = { mk_float(numerator(val)), mk_float(denominator(val)) };
@ -360,7 +359,7 @@ format * smt2_pp_environment::pp_arith_literal(app * t, bool decimal, unsigned d
else {
am.display_root_smt2(buffer, val2);
}
vf = mk_string(get_manager(), buffer.str().c_str());
vf = mk_string(get_manager(), buffer.str());
return is_neg ? mk_neg(vf) : vf;
}
}
@ -380,16 +379,14 @@ format * smt2_pp_environment::pp_string_literal(app * t) {
buffer << encs[i];
}
}
buffer << "\"";
return mk_string(get_manager(), buffer.str().c_str());
buffer << '"';
return mk_string(get_manager(), buffer.str());
}
format * smt2_pp_environment::pp_datalog_literal(app * t) {
uint64_t v;
VERIFY (get_dlutil().is_numeral(t, v));
std::ostringstream buffer;
buffer << v;
return mk_string(get_manager(), buffer.str().c_str());
return mk_string(get_manager(), std::to_string(v));
}
format_ns::format * smt2_pp_environment::pp_sort(sort * s) {
@ -440,10 +437,10 @@ format_ns::format * smt2_pp_environment::pp_sort(sort * s) {
for (unsigned i = 0; i < sz; i++) {
fs.push_back(pp_sort(get_dtutil().get_datatype_parameter_sort(s, i)));
}
return mk_seq1(m, fs.begin(), fs.end(), f2f(), s->get_name().str().c_str());
return mk_seq1(m, fs.begin(), fs.end(), f2f(), s->get_name().str());
}
}
return format_ns::mk_string(get_manager(), s->get_name().str().c_str());
return format_ns::mk_string(get_manager(), s->get_name().str());
}
typedef app_ref_vector format_ref_vector;
@ -557,9 +554,7 @@ class smt2_printer {
symbol ensure_quote_sym(symbol const& s) {
if (is_smt2_quoted_symbol(s)) {
std::string str;
str = mk_smt2_quoted_symbol(s);
return symbol(str.c_str());
return symbol(mk_smt2_quoted_symbol(s));
}
else
return s;
@ -576,7 +571,7 @@ class smt2_printer {
else {
vname = s.str();
}
f = mk_string(m(), vname.c_str ());
f = mk_string(m(), vname);
}
else {
// fallback... it is not supposed to happen when the printer is correctly used.
@ -584,7 +579,7 @@ class smt2_printer {
buf.append("(:var ");
buf.append(v->get_idx());
//buf.append(" ");
//buf.append(v->get_sort()->get_name().str().c_str());
//buf.append(v->get_sort()->get_name().str());
buf.append(")");
f = mk_string(m(), buf.c_str());
}
@ -604,7 +599,7 @@ class smt2_printer {
format * pp_simple_attribute(char const * attr, symbol const & s) {
std::string str = ensure_quote(s);
return mk_compose(m(), mk_string(m(), attr), mk_string(m(), str.c_str()));
return mk_compose(m(), mk_string(m(), attr), mk_string(m(), str));
}
format * pp_labels(bool is_pos, buffer<symbol> const & names, format * f) {
@ -654,7 +649,7 @@ class smt2_printer {
if (m_expr2alias->find(t, idx)) {
unsigned lvl = m_aliased_lvls_names[idx].first;
symbol const & s = m_aliased_lvls_names[idx].second;
m_format_stack.push_back(mk_string(m(), s.str().c_str()));
m_format_stack.push_back(mk_string(m(), s.str()));
m_info_stack.push_back(info(lvl+1, 1, 1));
return true;
}
@ -707,7 +702,7 @@ class smt2_printer {
<< ", lvl: " << f_info.m_lvl << " t: #" << t->get_id() << "\n" << mk_ll_pp(t, m())
<< ", is-shared: " << m_soccs.is_shared(t) << "\n";);
register_alias(t, f, f_info.m_lvl, a);
m_format_stack.push_back(mk_string(m(), a.str().c_str()));
m_format_stack.push_back(mk_string(m(), a.str()));
m_info_stack.push_back(info(f_info.m_lvl + 1, 1, 1));
}
else {
@ -811,7 +806,7 @@ class smt2_printer {
format * f_def[1] = { m_aliased_pps.get(i) };
decls.reserve(lvl+1);
ptr_vector<format> & lvl_decls = decls[lvl];
lvl_decls.push_back(mk_seq1<format**, f2f>(m(), f_def, f_def+1, f2f(), f_name.str().c_str()));
lvl_decls.push_back(mk_seq1<format**, f2f>(m(), f_def, f_def+1, f2f(), f_name.str()));
}
TRACE("pp_let", tout << "decls.size(): " << decls.size() << "\n";);
ptr_buffer<format> buf;
@ -919,9 +914,9 @@ class smt2_printer {
var_name = mk_smt2_quoted_symbol (*it);
}
else {
var_name = it->str ();
var_name = it->str();
}
buf.push_back(mk_seq1<format**,f2f>(m(), fs, fs+1, f2f(), var_name.c_str ()));
buf.push_back(mk_seq1<format**,f2f>(m(), fs, fs+1, f2f(), var_name));
}
return mk_seq5(m(), buf.begin(), buf.end(), f2f());
}

View file

@ -62,7 +62,7 @@ symbol smt_renaming::fix_symbol(symbol s, int k) {
if (s.is_numerical()) {
buffer << s << k;
return symbol(buffer.str().c_str());
return symbol(buffer.str());
}
if (!s.bare_str()) {
@ -78,7 +78,7 @@ symbol smt_renaming::fix_symbol(symbol s, int k) {
buffer << "!" << k;
}
return symbol(buffer.str().c_str());
return symbol(buffer.str());
}
bool smt_renaming::is_legal(char c) {

View file

@ -17,6 +17,7 @@ Revision History:
--*/
#pragma once
#include <string>
#include "ast/ast.h"
@ -53,6 +54,7 @@ namespace format_ns {
family_id get_format_family_id(ast_manager & m);
format * mk_string(ast_manager & m, char const * str);
static inline format * mk_string(ast_manager & m, const std::string & str) { return mk_string(m, str.c_str()); }
format * mk_int(ast_manager & m, int i);
format * mk_unsigned(ast_manager & m, unsigned u);
format * mk_indent(ast_manager & m, unsigned i, format * f);
@ -104,6 +106,12 @@ namespace format_ns {
mk_string(m, rp)))));
}
template<typename It, typename ToDoc>
static inline format * mk_seq1(ast_manager & m, It const & begin, It const & end, ToDoc proc, const std::string &header,
char const * lp = "(", char const * rp = ")") {
return mk_seq1(m, begin, end, proc, header.c_str(), lp, rp);
}
#define FORMAT_DEFAULT_INDENT 2
/**

View file

@ -206,8 +206,8 @@ bool quasi_macros::quasi_macro_to_macro(quantifier * q, app * a, expr * t, quant
if (!is_var(arg) || v_seen.get(to_var(arg)->get_idx())) {
unsigned inx = m_new_var_names.size();
m_new_name.str("");
m_new_name << "X" << inx;
m_new_var_names.push_back(symbol(m_new_name.str().c_str()));
m_new_name << 'X' << inx;
m_new_var_names.push_back(symbol(m_new_name.str()));
m_new_qsorts.push_back(f->get_domain()[i]);
m_new_vars.push_back(m.mk_var(inx + q->get_num_decls(), f->get_domain()[i]));

View file

@ -631,7 +631,8 @@ bool pattern_inference_cfg::reduce_quantifier(
if (new_patterns.empty()) {
mk_patterns(q->get_num_decls(), new_body, 0, nullptr, new_patterns);
if (m_params.m_pi_warnings && !new_patterns.empty()) {
warning_msg("ignoring nopats annotation because Z3 couldn't find any other pattern (quantifier id: %s)", q->get_qid().str().c_str());
auto str = q->get_qid().str();
warning_msg("ignoring nopats annotation because Z3 couldn't find any other pattern (quantifier id: %s)", str.c_str());
}
}
}
@ -644,8 +645,9 @@ bool pattern_inference_cfg::reduce_quantifier(
if (!new_patterns.empty()) {
weight = std::max(weight, static_cast<int>(m_params.m_pi_arith_weight));
if (m_params.m_pi_warnings) {
auto str = q->get_qid().str();
warning_msg("using arith. in pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_ARITH_WEIGHT=<val>).",
q->get_qid().str().c_str(), weight);
str.c_str(), weight);
}
}
}
@ -659,8 +661,9 @@ bool pattern_inference_cfg::reduce_quantifier(
if (!new_patterns.empty()) {
weight = std::max(weight, static_cast<int>(m_params.m_pi_non_nested_arith_weight));
if (m_params.m_pi_warnings) {
auto str = q->get_qid().str();
warning_msg("using non nested arith. pattern (quantifier id: %s), the weight was increased to %d (this value can be modified using PI_NON_NESTED_ARITH_WEIGHT=<val>).",
q->get_qid().str().c_str(), weight);
str.c_str(), weight);
}
// verbose_stream() << mk_pp(q, m) << "\n";
}
@ -686,7 +689,8 @@ bool pattern_inference_cfg::reduce_quantifier(
mk_patterns(result2->get_num_decls(), result2->get_expr(), 0, nullptr, new_patterns);
if (!new_patterns.empty()) {
if (m_params.m_pi_warnings) {
warning_msg("pulled nested quantifier to be able to find an usable pattern (quantifier id: %s)", q->get_qid().str().c_str());
auto str = q->get_qid().str();
warning_msg("pulled nested quantifier to be able to find an usable pattern (quantifier id: %s)", str.c_str());
}
new_q = m.update_quantifier(result2, new_patterns.size(), (expr**) new_patterns.c_ptr(), result2->get_expr());
if (m.proofs_enabled()) {
@ -699,7 +703,8 @@ bool pattern_inference_cfg::reduce_quantifier(
if (new_patterns.empty()) {
if (m_params.m_pi_warnings) {
warning_msg("failed to find a pattern for quantifier (quantifier id: %s)", q->get_qid().str().c_str());
auto str = q->get_qid().str();
warning_msg("failed to find a pattern for quantifier (quantifier id: %s)", str.c_str());
}
TRACE("pi_failed", tout << mk_pp(q, m) << "\n";);
}

View file

@ -51,12 +51,12 @@ bool bv_elim_cfg::reduce_quantifier(quantifier * q,
for (unsigned j = 0; j < num_bits; ++j) {
std::ostringstream new_name;
new_name << nm.str();
new_name << "_";
new_name << '_';
new_name << j;
var* v = m.mk_var(var_idx++, m.mk_bool_sort());
var* v = m.mk_var(var_idx++, m.mk_bool_sort());
args.push_back(v);
_sorts.push_back(m.mk_bool_sort());
_names.push_back(symbol(new_name.str().c_str()));
_names.push_back(symbol(new_name.str()));
}
bv = m.mk_app(bfid, OP_MKBV, 0, nullptr, args.size(), args.c_ptr());
_subst_map.push_back(bv.get());

View file

@ -158,8 +158,8 @@ expr_ref pb_rewriter::mk_validate_rewrite(app_ref& e1, app_ref& e2) {
}
std::ostringstream strm;
strm << "x" << i;
name = symbol(strm.str().c_str());
strm << 'x' << i;
name = symbol(strm.str());
trail.push_back(m.mk_const(name, a.mk_int()));
expr* x = trail.back();
m.is_not(e,e);
@ -190,7 +190,7 @@ void pb_rewriter::validate_rewrite(func_decl* f, unsigned sz, expr*const* args,
void pb_rewriter::dump_pb_rewrite(expr* fml) {
std::ostringstream strm;
strm << "pb_rewrite_" << (s_lemma++) << ".smt2";
std::ofstream out(strm.str().c_str());
std::ofstream out(strm.str());
ast_smt_pp pp(m());
pp.display_smt2(out, fml);
out.close();

View file

@ -1916,7 +1916,7 @@ br_status seq_rewriter::mk_str_itos(expr* a, expr_ref& result) {
rational r;
if (m_autil.is_numeral(a, r)) {
if (r.is_int() && !r.is_neg()) {
result = str().mk_string(symbol(r.to_string().c_str()));
result = str().mk_string(symbol(r.to_string()));
}
else {
result = str().mk_string(symbol(""));

View file

@ -199,12 +199,6 @@ zstring::zstring(unsigned ch) {
m_buffer.push_back(ch);
}
zstring& zstring::operator=(zstring const& other) {
m_buffer.reset();
m_buffer.append(other.m_buffer);
return *this;
}
zstring zstring::reverse() const {
zstring result;
for (unsigned i = length(); i-- > 0; ) {
@ -876,7 +870,7 @@ func_decl * seq_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters,
if (!(num_parameters == 1 && parameters[0].is_int()))
m.raise_exception("character literal expects integer parameter");
zstring zs(parameters[0].get_int());
parameter p(zs.encode().c_str());
parameter p(zs.encode());
return m.mk_const_decl(m_stringc_sym, m_string,func_decl_info(m_family_id, OP_STRING_CONST, 1, &p));
}
@ -991,7 +985,7 @@ void seq_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol cons
init();
for (unsigned i = 0; i < m_sigs.size(); ++i) {
if (m_sigs[i]) {
op_names.push_back(builtin_name(m_sigs[i]->m_name.str().c_str(), i));
op_names.push_back(builtin_name(m_sigs[i]->m_name.str(), i));
}
}
op_names.push_back(builtin_name("str.in.re", _OP_STRING_IN_REGEXP));
@ -1024,7 +1018,7 @@ void seq_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol
app* seq_decl_plugin::mk_string(symbol const& s) {
zstring canonStr(s.bare_str());
symbol canonSym(canonStr.encode().c_str());
symbol canonSym(canonStr.encode());
parameter param(canonSym);
func_decl* f = m_manager->mk_const_decl(m_stringc_sym, m_string,
func_decl_info(m_family_id, OP_STRING_CONST, 1, &param));
@ -1032,7 +1026,7 @@ app* seq_decl_plugin::mk_string(symbol const& s) {
}
app* seq_decl_plugin::mk_string(zstring const& s) {
symbol sym(s.encode().c_str());
symbol sym(s.encode());
parameter param(sym);
func_decl* f = m_manager->mk_const_decl(m_stringc_sym, m_string,
func_decl_info(m_family_id, OP_STRING_CONST, 1, &param));

View file

@ -24,6 +24,7 @@ Revision History:
#include "ast/ast.h"
#include "ast/bv_decl_plugin.h"
#include <string>
#define Z3_USE_UNICODE 0
@ -121,11 +122,10 @@ public:
static unsigned max_char() { return 196607; }
zstring() {}
zstring(char const* s);
zstring(const std::string &str) : zstring(str.c_str()) {}
zstring(unsigned sz, unsigned const* s) { m_buffer.append(sz, s); SASSERT(well_formed()); }
zstring(zstring const& other): m_buffer(other.m_buffer) {}
zstring(unsigned num_bits, bool const* ch);
zstring(unsigned ch);
zstring& operator=(zstring const& other);
zstring replace(zstring const& src, zstring const& dst) const;
zstring reverse() const;
std::string encode() const;

View file

@ -67,10 +67,11 @@ struct well_sorted_proc {
);
std::ostringstream strm;
strm << "Sort mismatch for argument " << i+1 << " of " << mk_ll_pp(n, m_manager, false) << "\n";
strm << "Expected sort: " << mk_pp(expected_sort, m_manager) << "\n";
strm << "Actual sort: " << mk_pp(actual_sort, m_manager) << "\n";
strm << "Function sort: " << mk_pp(decl, m_manager) << ".";
warning_msg("%s", strm.str().c_str());
strm << "Expected sort: " << mk_pp(expected_sort, m_manager) << '\n';
strm << "Actual sort: " << mk_pp(actual_sort, m_manager) << '\n';
strm << "Function sort: " << mk_pp(decl, m_manager) << '.';
auto str = strm.str();
warning_msg("%s", str.c_str());
m_error = true;
return;
}