Skip to content

Commit bffb1ca

Browse files
author
Daniel Kroening
committed
smt2_parser: avoid access to vector without prior size check
1 parent e6d76e5 commit bffb1ca

File tree

2 files changed

+39
-55
lines changed

2 files changed

+39
-55
lines changed

src/solvers/smt2/smt2_parser.cpp

+30-50
Original file line numberDiff line numberDiff line change
@@ -313,24 +313,26 @@ exprt smt2_parsert::function_application(
313313
return nil_exprt();
314314
}
315315

316-
exprt smt2_parsert::cast_bv_to_signed(const exprt &expr)
316+
exprt::operandst smt2_parsert::cast_bv_to_signed(const exprt::operandst &op)
317317
{
318-
if(expr.type().id()==ID_signedbv) // no need to cast
319-
return expr;
318+
exprt::operandst result = op;
320319

321-
if(expr.type().id()!=ID_unsignedbv)
320+
for(auto &expr : result)
322321
{
323-
error() << "expected unsigned bitvector" << eom;
324-
return expr;
322+
if(expr.type().id() == ID_signedbv) // no need to cast
323+
{
324+
}
325+
else if(expr.type().id() != ID_unsignedbv)
326+
{
327+
error() << "expected unsigned bitvector" << eom;
328+
}
329+
else
330+
{
331+
const auto width = to_unsignedbv_type(expr.type()).get_width();
332+
expr = typecast_exprt(expr, signedbv_typet(width));
333+
}
325334
}
326335

327-
auto width=to_unsignedbv_type(expr.type()).get_width();
328-
signedbv_typet signed_type(width);
329-
330-
typecast_exprt result(expr, signed_type);
331-
result.op0()=expr;
332-
result.type()=signed_type;
333-
334336
return result;
335337
}
336338

@@ -345,17 +347,11 @@ exprt smt2_parsert::cast_bv_to_unsigned(const exprt &expr)
345347
return expr;
346348
}
347349

348-
auto width=to_signedbv_type(expr.type()).get_width();
349-
unsignedbv_typet unsigned_type(width);
350-
351-
typecast_exprt result(expr, unsigned_type);
352-
result.op0()=expr;
353-
result.type()=unsigned_type;
354-
355-
return result;
350+
const auto width=to_signedbv_type(expr.type()).get_width();
351+
return typecast_exprt(expr, unsignedbv_typet(width));
356352
}
357353

358-
exprt smt2_parsert::multi_ary(irep_idt id, exprt::operandst &op)
354+
exprt smt2_parsert::multi_ary(irep_idt id, const exprt::operandst &op)
359355
{
360356
if(op.empty())
361357
{
@@ -377,12 +373,12 @@ exprt smt2_parsert::multi_ary(irep_idt id, exprt::operandst &op)
377373
}
378374

379375
exprt result(id, op[0].type());
380-
result.operands().swap(op);
376+
result.operands() = op;
381377
return result;
382378
}
383379
}
384380

385-
exprt smt2_parsert::binary_predicate(irep_idt id, exprt::operandst &op)
381+
exprt smt2_parsert::binary_predicate(irep_idt id, const exprt::operandst &op)
386382
{
387383
if(op.size()!=2)
388384
{
@@ -404,7 +400,7 @@ exprt smt2_parsert::binary_predicate(irep_idt id, exprt::operandst &op)
404400
}
405401
}
406402

407-
exprt smt2_parsert::unary(irep_idt id, exprt::operandst &op)
403+
exprt smt2_parsert::unary(irep_idt id, const exprt::operandst &op)
408404
{
409405
if(op.size()!=1)
410406
{
@@ -415,7 +411,7 @@ exprt smt2_parsert::unary(irep_idt id, exprt::operandst &op)
415411
return unary_exprt(id, op[0], op[0].type());
416412
}
417413

418-
exprt smt2_parsert::binary(irep_idt id, exprt::operandst &op)
414+
exprt smt2_parsert::binary(irep_idt id, const exprt::operandst &op)
419415
{
420416
if(op.size()!=2)
421417
{
@@ -510,45 +506,35 @@ exprt smt2_parsert::function_application()
510506
}
511507
else if(id=="bvsle")
512508
{
513-
op[0]=cast_bv_to_signed(op[0]);
514-
op[1]=cast_bv_to_signed(op[1]);
515-
return binary_predicate(ID_le, op);
509+
return binary_predicate(ID_le, cast_bv_to_signed(op));
516510
}
517511
else if(id=="bvuge")
518512
{
519513
return binary_predicate(ID_ge, op);
520514
}
521515
else if(id=="bvsge")
522516
{
523-
op[0]=cast_bv_to_signed(op[0]);
524-
op[1]=cast_bv_to_signed(op[1]);
525-
return binary_predicate(ID_ge, op);
517+
return binary_predicate(ID_ge, cast_bv_to_signed(op));
526518
}
527519
else if(id=="bvult")
528520
{
529521
return binary_predicate(ID_lt, op);
530522
}
531523
else if(id=="bvslt")
532524
{
533-
op[0]=cast_bv_to_signed(op[0]);
534-
op[1]=cast_bv_to_signed(op[1]);
535-
return binary_predicate(ID_lt, op);
525+
return binary_predicate(ID_lt, cast_bv_to_signed(op));
536526
}
537527
else if(id=="bvugt")
538528
{
539529
return binary_predicate(ID_gt, op);
540530
}
541531
else if(id=="bvsgt")
542532
{
543-
op[0]=cast_bv_to_signed(op[0]);
544-
op[1]=cast_bv_to_signed(op[1]);
545-
return binary_predicate(ID_gt, op);
533+
return binary_predicate(ID_gt, cast_bv_to_signed(op));
546534
}
547535
else if(id=="bvashr")
548536
{
549-
op[0]=cast_bv_to_signed(op[0]);
550-
op[1]=cast_bv_to_signed(op[1]);
551-
return cast_bv_to_unsigned(binary(ID_ashr, op));
537+
return cast_bv_to_unsigned(binary(ID_ashr, cast_bv_to_signed(op)));
552538
}
553539
else if(id=="bvlshr" || id=="bvshr")
554540
{
@@ -608,9 +594,7 @@ exprt smt2_parsert::function_application()
608594
}
609595
else if(id=="bvsdiv")
610596
{
611-
op[0]=cast_bv_to_signed(op[0]);
612-
op[1]=cast_bv_to_signed(op[1]);
613-
return cast_bv_to_unsigned(binary(ID_div, op));
597+
return cast_bv_to_unsigned(binary(ID_div, cast_bv_to_signed(op)));
614598
}
615599
else if(id=="bvudiv")
616600
{
@@ -624,17 +608,13 @@ exprt smt2_parsert::function_application()
624608
{
625609
// 2's complement signed remainder (sign follows dividend)
626610
// This matches our ID_mod, and what C does since C99.
627-
op[0]=cast_bv_to_signed(op[0]);
628-
op[1]=cast_bv_to_signed(op[1]);
629-
return cast_bv_to_unsigned(binary(ID_mod, op));
611+
return cast_bv_to_unsigned(binary(ID_mod, cast_bv_to_signed(op)));
630612
}
631613
else if(id=="bvsmod")
632614
{
633615
// 2's complement signed remainder (sign follows divisor)
634616
// We don't have that.
635-
op[0]=cast_bv_to_signed(op[0]);
636-
op[1]=cast_bv_to_signed(op[1]);
637-
return cast_bv_to_unsigned(binary(ID_mod, op));
617+
return cast_bv_to_unsigned(binary(ID_mod, cast_bv_to_signed(op)));
638618
}
639619
else if(id=="bvurem" || id=="%")
640620
{

src/solvers/smt2/smt2_parser.h

+9-5
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,21 @@ class smt2_parsert:public smt2_tokenizert
6464
exprt::operandst operands();
6565
typet function_signature_declaration();
6666
typet function_signature_definition();
67-
exprt multi_ary(irep_idt, exprt::operandst &);
68-
exprt binary_predicate(irep_idt, exprt::operandst &);
69-
exprt binary(irep_idt, exprt::operandst &);
70-
exprt unary(irep_idt, exprt::operandst &);
67+
exprt multi_ary(irep_idt, const exprt::operandst &);
68+
exprt binary_predicate(irep_idt, const exprt::operandst &);
69+
exprt binary(irep_idt, const exprt::operandst &);
70+
exprt unary(irep_idt, const exprt::operandst &);
7171

7272
exprt let_expression();
7373
exprt quantifier_expression(irep_idt);
7474
exprt function_application(
7575
const irep_idt &identifier,
7676
const exprt::operandst &op);
77-
exprt cast_bv_to_signed(const exprt &);
77+
78+
/// Apply typecast to signedbv to expressions in vector
79+
exprt::operandst cast_bv_to_signed(const exprt::operandst &);
80+
81+
/// Apply typecast to unsignedbv to given expression
7882
exprt cast_bv_to_unsigned(const exprt &);
7983
};
8084

0 commit comments

Comments
 (0)