mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-03 21:09:11 +00:00 
			
		
		
		
	harden a few API methods against longjumps in set_error. Memory leak exposed in #1297
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
		
							parent
							
								
									09ea370ea3
								
							
						
					
					
						commit
						c093e6d4b9
					
				
					 4 changed files with 26 additions and 22 deletions
				
			
		| 
						 | 
				
			
			@ -283,15 +283,16 @@ extern "C" {
 | 
			
		|||
        Z3_optimize opt,
 | 
			
		||||
        std::istream& s) {
 | 
			
		||||
        ast_manager& m = mk_c(c)->m();
 | 
			
		||||
        cmd_context ctx(false, &m);
 | 
			
		||||
        install_opt_cmds(ctx, to_optimize_ptr(opt));
 | 
			
		||||
        ctx.set_ignore_check(true);
 | 
			
		||||
        if (!parse_smt2_commands(ctx, s)) {
 | 
			
		||||
        scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &m);
 | 
			
		||||
        install_opt_cmds(*ctx.get(), to_optimize_ptr(opt));
 | 
			
		||||
        ctx->set_ignore_check(true);
 | 
			
		||||
        if (!parse_smt2_commands(*ctx.get(), s)) {
 | 
			
		||||
            ctx = nullptr;
 | 
			
		||||
            SET_ERROR_CODE(Z3_PARSER_ERROR);
 | 
			
		||||
            return;
 | 
			
		||||
        }        
 | 
			
		||||
        ptr_vector<expr>::const_iterator it  = ctx.begin_assertions();
 | 
			
		||||
        ptr_vector<expr>::const_iterator end = ctx.end_assertions();
 | 
			
		||||
        ptr_vector<expr>::const_iterator it  = ctx->begin_assertions();
 | 
			
		||||
        ptr_vector<expr>::const_iterator end = ctx->end_assertions();
 | 
			
		||||
        for (; it != end; ++it) {
 | 
			
		||||
            to_optimize_ptr(opt)->add_hard_constraint(*it);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -320,9 +321,6 @@ extern "C" {
 | 
			
		|||
            std::ostringstream strm;
 | 
			
		||||
            strm << "Could not open file " << s;
 | 
			
		||||
            throw default_exception(strm.str());
 | 
			
		||||
 | 
			
		||||
            SET_ERROR_CODE(Z3_PARSER_ERROR);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Z3_optimize_from_stream(c, d, is);
 | 
			
		||||
        Z3_CATCH;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,7 +56,7 @@ extern "C" {
 | 
			
		|||
                                       Z3_func_decl const decls[]) {
 | 
			
		||||
        Z3_TRY;
 | 
			
		||||
        LOG_Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
 | 
			
		||||
        std::ostringstream* outs = alloc(std::ostringstream);
 | 
			
		||||
        scoped_ptr<std::ostringstream> outs = alloc(std::ostringstream);
 | 
			
		||||
        bool ok = false;
 | 
			
		||||
 | 
			
		||||
        RESET_ERROR_CODE();
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +69,7 @@ extern "C" {
 | 
			
		|||
            ok = false;
 | 
			
		||||
        }
 | 
			
		||||
        mk_c(c)->m_smtlib_error_buffer = outs->str();
 | 
			
		||||
        dealloc(outs);
 | 
			
		||||
        outs = nullptr;
 | 
			
		||||
        if (!ok) {
 | 
			
		||||
            mk_c(c)->reset_parser();
 | 
			
		||||
            SET_ERROR_CODE(Z3_PARSER_ERROR);
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +89,7 @@ extern "C" {
 | 
			
		|||
        LOG_Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, types, num_decls, decl_names, decls);
 | 
			
		||||
        bool ok = false;
 | 
			
		||||
        RESET_ERROR_CODE();
 | 
			
		||||
        std::ostringstream* outs = alloc(std::ostringstream);
 | 
			
		||||
        scoped_ptr<std::ostringstream> outs = alloc(std::ostringstream);
 | 
			
		||||
        init_smtlib_parser(c, num_sorts, sort_names, types, num_decls, decl_names, decls);
 | 
			
		||||
        mk_c(c)->m_smtlib_parser->set_error_stream(*outs);
 | 
			
		||||
        try {
 | 
			
		||||
| 
						 | 
				
			
			@ -99,7 +99,7 @@ extern "C" {
 | 
			
		|||
            ok = false;
 | 
			
		||||
        }
 | 
			
		||||
        mk_c(c)->m_smtlib_error_buffer = outs->str();
 | 
			
		||||
        dealloc(outs);
 | 
			
		||||
        outs = nullptr;
 | 
			
		||||
        if (!ok) {
 | 
			
		||||
            mk_c(c)->reset_parser();
 | 
			
		||||
            SET_ERROR_CODE(Z3_PARSER_ERROR);
 | 
			
		||||
| 
						 | 
				
			
			@ -262,21 +262,22 @@ extern "C" {
 | 
			
		|||
                                Z3_symbol const decl_names[],
 | 
			
		||||
                                Z3_func_decl const decls[]) {
 | 
			
		||||
        Z3_TRY;
 | 
			
		||||
        cmd_context ctx(false, &(mk_c(c)->m()));
 | 
			
		||||
        ctx.set_ignore_check(true);
 | 
			
		||||
        scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &(mk_c(c)->m()));
 | 
			
		||||
        ctx->set_ignore_check(true);
 | 
			
		||||
        for (unsigned i = 0; i < num_decls; ++i) {
 | 
			
		||||
           ctx.insert(to_symbol(decl_names[i]), to_func_decl(decls[i]));
 | 
			
		||||
            ctx->insert(to_symbol(decl_names[i]), to_func_decl(decls[i]));
 | 
			
		||||
        }
 | 
			
		||||
        for (unsigned i = 0; i < num_sorts; ++i) {
 | 
			
		||||
            psort* ps = ctx.pm().mk_psort_cnst(to_sort(sorts[i]));
 | 
			
		||||
            ctx.insert(ctx.pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps));
 | 
			
		||||
            psort* ps = ctx->pm().mk_psort_cnst(to_sort(sorts[i]));
 | 
			
		||||
            ctx->insert(ctx->pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps));
 | 
			
		||||
        }
 | 
			
		||||
        if (!parse_smt2_commands(ctx, is)) {
 | 
			
		||||
        if (!parse_smt2_commands(*ctx.get(), is)) {
 | 
			
		||||
            ctx = nullptr;
 | 
			
		||||
            SET_ERROR_CODE(Z3_PARSER_ERROR);
 | 
			
		||||
            return of_ast(mk_c(c)->m().mk_true());
 | 
			
		||||
        }
 | 
			
		||||
        ptr_vector<expr>::const_iterator it  = ctx.begin_assertions();
 | 
			
		||||
        ptr_vector<expr>::const_iterator end = ctx.end_assertions();
 | 
			
		||||
        ptr_vector<expr>::const_iterator it  = ctx->begin_assertions();
 | 
			
		||||
        ptr_vector<expr>::const_iterator end = ctx->end_assertions();
 | 
			
		||||
        unsigned size = static_cast<unsigned>(end - it);
 | 
			
		||||
        return of_ast(mk_c(c)->mk_and(size, it));
 | 
			
		||||
        Z3_CATCH_RETURN(0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,9 +63,11 @@ extern "C" {
 | 
			
		|||
        RESET_ERROR_CODE();
 | 
			
		||||
        if (!mk_c(c)->m().is_bool(to_expr(body))) {
 | 
			
		||||
            SET_ERROR_CODE(Z3_SORT_ERROR);
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        if (num_patterns > 0 && num_no_patterns > 0) {
 | 
			
		||||
            SET_ERROR_CODE(Z3_INVALID_USAGE);
 | 
			
		||||
            return nullptr;
 | 
			
		||||
        }
 | 
			
		||||
        expr * const* ps = reinterpret_cast<expr * const*>(patterns);
 | 
			
		||||
        expr * const* no_ps = reinterpret_cast<expr * const*>(no_patterns);
 | 
			
		||||
| 
						 | 
				
			
			@ -76,7 +78,7 @@ extern "C" {
 | 
			
		|||
            for (unsigned i = 0; i < num_patterns; i++) {
 | 
			
		||||
                if (!v(num_decls, ps[i], 0, 0)) {
 | 
			
		||||
                    SET_ERROR_CODE(Z3_INVALID_PATTERN);
 | 
			
		||||
                    return 0;
 | 
			
		||||
                    return nullptr;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -442,6 +442,7 @@ extern "C" {
 | 
			
		|||
        unsigned sz = __assumptions.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; ++i) {
 | 
			
		||||
            if (!is_expr(__assumptions[i])) {
 | 
			
		||||
                _assumptions.finalize(); _consequences.finalize(); _variables.finalize();
 | 
			
		||||
                SET_ERROR_CODE(Z3_INVALID_USAGE);
 | 
			
		||||
                return Z3_L_UNDEF;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -451,6 +452,7 @@ extern "C" {
 | 
			
		|||
        sz = __variables.size();
 | 
			
		||||
        for (unsigned i = 0; i < sz; ++i) {
 | 
			
		||||
            if (!is_expr(__variables[i])) {
 | 
			
		||||
                _assumptions.finalize(); _consequences.finalize(); _variables.finalize();
 | 
			
		||||
                SET_ERROR_CODE(Z3_INVALID_USAGE);
 | 
			
		||||
                return Z3_L_UNDEF;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			@ -471,6 +473,7 @@ extern "C" {
 | 
			
		|||
            }
 | 
			
		||||
            catch (z3_exception & ex) {
 | 
			
		||||
                to_solver_ref(s)->set_reason_unknown(eh);
 | 
			
		||||
                _assumptions.finalize(); _consequences.finalize(); _variables.finalize();
 | 
			
		||||
                mk_c(c)->handle_exception(ex);
 | 
			
		||||
                return Z3_L_UNDEF;
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue