@@ -482,26 +482,45 @@ bvt bv_utilst::shift(const bvt &src, const shiftt s, std::size_t dist)
482
482
bvt result;
483
483
result.resize (src.size ());
484
484
485
+ // 'dist' is user-controlled, and thus arbitary.
486
+ // We thus must guard against the case in which i+dist overflows.
487
+ // We do so by considering the case dist>=src.size().
488
+
485
489
for (std::size_t i=0 ; i<src.size (); i++)
486
490
{
487
491
literalt l;
488
492
489
493
switch (s)
490
494
{
491
- case shiftt::LEFT:
495
+ case shiftt::SHIFT_LEFT:
496
+ // no underflow on i-dist because of condition dist<=i
492
497
l=(dist<=i?src[i-dist]:const_literal (false ));
493
498
break ;
494
499
495
- case shiftt::ARIGHT:
496
- l=(i+dist<src.size ()?src[i+dist]:src[src.size ()-1 ]); // sign bit
500
+ case shiftt::SHIFT_ARIGHT:
501
+ // src.size()-i won't underflow as i<src.size()
502
+ // Then, if dist<src.size()-i, then i+dist<src.size()
503
+ l=(dist<src.size ()-i?src[i+dist]:src[src.size ()-1 ]); // sign bit
504
+ break ;
505
+
506
+ case shiftt::SHIFT_LRIGHT:
507
+ // src.size()-i won't underflow as i<src.size()
508
+ // Then, if dist<src.size()-i, then i+dist<src.size()
509
+ l=(dist<src.size ()-i?src[i+dist]:const_literal (false ));
497
510
break ;
498
511
499
- case shiftt::LRIGHT:
500
- l=(i+dist<src.size ()?src[i+dist]:const_literal (false ));
512
+ case shiftt::ROTATE_LEFT:
513
+ // prevent overflows by using dist%src.size()
514
+ l=src[(src.size ()+i-(dist%src.size ()))%src.size ()];
515
+ break ;
516
+
517
+ case shiftt::ROTATE_RIGHT:
518
+ // prevent overflows by using dist%src.size()
519
+ l=src[(i+(dist%src.size ()))%src.size ()];
501
520
break ;
502
521
503
522
default :
504
- assert ( false ) ;
523
+ UNREACHABLE ;
505
524
}
506
525
507
526
result[i]=l;
0 commit comments