@@ -283,7 +283,7 @@ int exec_divmod(VmState* st, unsigned args, int quiet) {
283283 auto x = stack.pop_int ();
284284 if (add) {
285285 CHECK (d == 3 );
286- typename td::BigInt256::DoubleInt tmp{*x}, quot;
286+ td::BigInt256::DoubleInt tmp{*x}, quot;
287287 tmp += *w;
288288 tmp.mod_div (*y, quot, round_mode);
289289 auto q = td::make_refint (quot), r = td::make_refint (tmp);
@@ -365,9 +365,9 @@ int exec_shrmod(VmState* st, unsigned args, int mode) {
365365 auto x = stack.pop_int ();
366366 if (add) {
367367 CHECK (d == 3 );
368- typename td::BigInt256::DoubleInt tmp{*x}, quot ;
368+ td::BigInt256::DoubleInt tmp{*x};
369369 tmp += *w;
370- typename td::BigInt256::DoubleInt tmp2{tmp};
370+ td::BigInt256::DoubleInt tmp2{tmp};
371371 tmp2.rshift (y, round_mode).normalize ();
372372 stack.push_int_quiet (td::make_refint (tmp2), mode & 1 );
373373 tmp.normalize ().mod_pow2 (y, round_mode).normalize ();
@@ -450,7 +450,7 @@ int exec_muldivmod(VmState* st, unsigned args, int quiet) {
450450 auto w = add ? stack.pop_int () : td::RefInt256{};
451451 auto y = stack.pop_int ();
452452 auto x = stack.pop_int ();
453- typename td::BigInt256::DoubleInt tmp{0 }, quot;
453+ td::BigInt256::DoubleInt tmp{0 }, quot;
454454 if (add) {
455455 tmp = *w;
456456 }
@@ -496,8 +496,9 @@ std::string dump_muldivmod(CellSlice&, unsigned args, bool quiet) {
496496}
497497
498498int exec_mulshrmod (VmState* st, unsigned args, int mode) {
499- int z = -1 ;
500- if (mode & 2 ) {
499+ bool quiet = mode & 1 , z_in_args = mode & 2 ;
500+ long long z = -1 ;
501+ if (z_in_args) {
501502 z = (args & 0xff ) + 1 ;
502503 args >>= 8 ;
503504 }
@@ -513,9 +514,12 @@ int exec_mulshrmod(VmState* st, unsigned args, int mode) {
513514 }
514515 Stack& stack = st->get_stack ();
515516 VM_LOG (st) << " execute MULSHR/MOD " << (args & 15 ) << ' ,' << z;
516- if (!(mode & 2 ) ) {
517+ if (!z_in_args ) {
517518 stack.check_underflow (add ? 4 : 3 );
518- z = stack.pop_smallint_range (256 );
519+ z = stack.pop_long ();
520+ if ((st->get_global_version () < 13 || !quiet) && (z < 0 || z > 256 )) {
521+ throw VmError{Excno::range_chk};
522+ }
519523 } else {
520524 stack.check_underflow (add ? 3 : 2 );
521525 }
@@ -525,26 +529,37 @@ int exec_mulshrmod(VmState* st, unsigned args, int mode) {
525529 auto w = add ? stack.pop_int () : td::RefInt256{};
526530 auto y = stack.pop_int ();
527531 auto x = stack.pop_int ();
528- typename td::BigInt256::DoubleInt tmp{0 };
532+ if (st->get_global_version () >= 13 ) {
533+ if (!x->is_valid () || !y->is_valid () || (w.not_null () && !w->is_valid ()) || z < 0 || z > 256 ) {
534+ stack.push_int_quiet (td::nan_refint (), quiet);
535+ if (d == 3 ) {
536+ stack.push_int_quiet (td::nan_refint (), quiet);
537+ }
538+ return 0 ;
539+ }
540+ }
541+ td::BigInt256::DoubleInt tmp{0 };
529542 if (add) {
530543 tmp = *w;
531544 }
532545 tmp.add_mul (*x, *y).normalize ();
533546 switch (d) {
534547 case 1 :
535- tmp.rshift (z, round_mode).normalize ();
536- stack.push_int_quiet (td::make_refint (tmp), mode & 1 );
548+ tmp.rshift (( int ) z, round_mode).normalize ();
549+ stack.push_int_quiet (td::make_refint (tmp), quiet );
537550 break ;
538551 case 3 : {
539- typename td::BigInt256::DoubleInt tmp2{tmp};
540- tmp2.rshift (z, round_mode).normalize ();
541- stack.push_int_quiet (td::make_refint (tmp2), mode & 1 );
552+ td::BigInt256::DoubleInt tmp2{tmp};
553+ tmp2.rshift (( int ) z, round_mode).normalize ();
554+ stack.push_int_quiet (td::make_refint (tmp2), quiet );
542555 }
543556 // fallthrough
544557 case 2 :
545- tmp.normalize ().mod_pow2 (z, round_mode).normalize ();
546- stack.push_int_quiet (td::make_refint (tmp), mode & 1 );
558+ tmp.normalize ().mod_pow2 (( int ) z, round_mode).normalize ();
559+ stack.push_int_quiet (td::make_refint (tmp), quiet );
547560 break ;
561+ default :
562+ UNREACHABLE ();
548563 }
549564 return 0 ;
550565}
@@ -594,8 +609,9 @@ std::string dump_mulshrmod(CellSlice&, unsigned args, int mode) {
594609}
595610
596611int exec_shldivmod (VmState* st, unsigned args, int mode) {
597- int y = -1 ;
598- if (mode & 2 ) {
612+ bool quiet = mode & 1 , y_in_args = mode & 2 ;
613+ long y = -1 ;
614+ if (y_in_args) {
599615 y = (args & 0xff ) + 1 ;
600616 args >>= 8 ;
601617 }
@@ -611,38 +627,52 @@ int exec_shldivmod(VmState* st, unsigned args, int mode) {
611627 }
612628 Stack& stack = st->get_stack ();
613629 VM_LOG (st) << " execute SHLDIV/MOD " << (args & 15 ) << ' ,' << y;
614- if (!(mode & 2 ) ) {
630+ if (!y_in_args ) {
615631 stack.check_underflow (add ? 4 : 3 );
616- y = stack.pop_smallint_range (256 );
632+ y = stack.pop_long ();
633+ if ((st->get_global_version () < 13 || !quiet) && (y < 0 || y > 256 )) {
634+ throw VmError{Excno::range_chk};
635+ }
617636 } else {
618637 stack.check_underflow (add ? 3 : 2 );
619638 }
620639 auto z = stack.pop_int ();
621640 auto w = add ? stack.pop_int () : td::RefInt256{};
622641 auto x = stack.pop_int ();
623- typename td::BigInt256::DoubleInt tmp{*x}, quot;
624- tmp <<= y;
642+ if (st->get_global_version () >= 13 ) {
643+ if (!z->is_valid () || !x->is_valid () || (w.not_null () && !w->is_valid ()) || y < 0 || y > 256 ) {
644+ stack.push_int_quiet (td::nan_refint (), quiet);
645+ if (d == 3 ) {
646+ stack.push_int_quiet (td::nan_refint (), quiet);
647+ }
648+ return 0 ;
649+ }
650+ }
651+ td::BigInt256::DoubleInt tmp{*x}, quot;
652+ tmp <<= (int )y;
625653 if (add) {
626654 tmp += *w;
627655 }
628656 switch (d) {
629657 case 1 : {
630658 tmp.mod_div (*z, quot, round_mode);
631- stack.push_int_quiet (td::make_refint (quot.normalize ()), mode & 1 );
659+ stack.push_int_quiet (td::make_refint (quot.normalize ()), quiet );
632660 break ;
633661 }
634662 case 3 : {
635663 tmp.mod_div (*z, quot, round_mode);
636- stack.push_int_quiet (td::make_refint (quot.normalize ()), mode & 1 );
637- stack.push_int_quiet (td::make_refint (tmp), mode & 1 );
664+ stack.push_int_quiet (td::make_refint (quot.normalize ()), quiet );
665+ stack.push_int_quiet (td::make_refint (tmp), quiet );
638666 break ;
639667 }
640668 case 2 : {
641- typename td::BigInt256::DoubleInt tmp2;
669+ td::BigInt256::DoubleInt tmp2;
642670 tmp.mod_div (*z, tmp2, round_mode);
643- stack.push_int_quiet (td::make_refint (tmp), mode & 1 );
671+ stack.push_int_quiet (td::make_refint (tmp), quiet );
644672 break ;
645673 }
674+ default :
675+ UNREACHABLE ();
646676 }
647677 return 0 ;
648678}
@@ -742,17 +772,37 @@ int exec_lshift(VmState* st, bool quiet) {
742772 Stack& stack = st->get_stack ();
743773 VM_LOG (st) << " execute LSHIFT" ;
744774 stack.check_underflow (2 );
745- int x = stack.pop_smallint_range (1023 );
746- stack.push_int_quiet (stack.pop_int () << x, quiet);
775+ long long shift = stack.pop_long ();
776+ if ((st->get_global_version () < 13 || !quiet) && (shift < 0 || shift > 1023 )) {
777+ throw VmError{Excno::range_chk};
778+ }
779+ auto a = stack.pop_int ();
780+ td::RefInt256 result;
781+ if (st->get_global_version () >= 13 && (shift < 0 || shift > 1023 || !a->is_valid ())) {
782+ result = td::nan_refint ();
783+ } else {
784+ result = std::move (a) << (int )shift;
785+ }
786+ stack.push_int_quiet (std::move (result), quiet);
747787 return 0 ;
748788}
749789
750790int exec_rshift (VmState* st, bool quiet) {
751791 Stack& stack = st->get_stack ();
752792 VM_LOG (st) << " execute RSHIFT" ;
753793 stack.check_underflow (2 );
754- int x = stack.pop_smallint_range (1023 );
755- stack.push_int_quiet (stack.pop_int () >> x, quiet);
794+ long long shift = stack.pop_long ();
795+ if ((st->get_global_version () < 13 || !quiet) && (shift < 0 || shift > 1023 )) {
796+ throw VmError{Excno::range_chk};
797+ }
798+ auto a = stack.pop_int ();
799+ td::RefInt256 result;
800+ if (st->get_global_version () >= 13 && (shift < 0 || shift > 1023 || !a->is_valid ())) {
801+ result = td::nan_refint ();
802+ } else {
803+ result = std::move (a) >> (int )shift;
804+ }
805+ stack.push_int_quiet (std::move (result), quiet);
756806 return 0 ;
757807}
758808
@@ -772,7 +822,14 @@ int exec_and(VmState* st, bool quiet) {
772822 VM_LOG (st) << " execute AND" ;
773823 stack.check_underflow (2 );
774824 auto y = stack.pop_int ();
775- stack.push_int_quiet (stack.pop_int () & std::move (y), quiet);
825+ auto x = stack.pop_int ();
826+ td::RefInt256 result;
827+ if (st->get_global_version () >= 13 && (!x->is_valid () || !y->is_valid ())) {
828+ result = td::nan_refint ();
829+ } else {
830+ result = std::move (x) & std::move (y);
831+ }
832+ stack.push_int_quiet (std::move (result), quiet);
776833 return 0 ;
777834}
778835
@@ -781,7 +838,14 @@ int exec_or(VmState* st, bool quiet) {
781838 VM_LOG (st) << " execute OR" ;
782839 stack.check_underflow (2 );
783840 auto y = stack.pop_int ();
784- stack.push_int_quiet (stack.pop_int () | std::move (y), quiet);
841+ auto x = stack.pop_int ();
842+ td::RefInt256 result;
843+ if (st->get_global_version () >= 13 && (!x->is_valid () || !y->is_valid ())) {
844+ result = td::nan_refint ();
845+ } else {
846+ result = std::move (x) | std::move (y);
847+ }
848+ stack.push_int_quiet (std::move (result), quiet);
785849 return 0 ;
786850}
787851
0 commit comments