2727#include < ios>
2828#include < iosfwd>
2929#include < istream>
30+ #include < limits>
3031#include < memory>
3132#include < optional>
3233#include < ostream>
@@ -483,6 +484,8 @@ VectorFstImpl<S>* VectorFstImpl<S>::Read(std::istream& strm,
483484 impl->BaseImpl ::SetStart (hdr.Start ());
484485 if (hdr.NumStates () != kNoStateId ) impl->ReserveStates (hdr.NumStates ());
485486 StateId state = 0 ;
487+ StateId max_next_state = std::numeric_limits<StateId>::lowest ();
488+ StateId min_next_state = std::numeric_limits<StateId>::max ();
486489 for (; hdr.NumStates () == kNoStateId || state < hdr.NumStates (); ++state) {
487490 Weight weight;
488491 if (!weight.Read (strm)) break ;
@@ -506,13 +509,30 @@ VectorFstImpl<S>* VectorFstImpl<S>::Read(std::istream& strm,
506509 LOG (ERROR) << " VectorFst::Read: Read failed: " << opts.source ;
507510 return nullptr ;
508511 }
512+ if (arc.nextstate > max_next_state) max_next_state = arc.nextstate ;
513+ if (arc.nextstate < min_next_state) min_next_state = arc.nextstate ;
509514 impl->BaseImpl ::AddArc (state, std::move (arc));
510515 }
511516 }
512517 if (hdr.NumStates () != kNoStateId && state != hdr.NumStates ()) {
513518 LOG (ERROR) << " VectorFst::Read: Unexpected end of file: " << opts.source ;
514519 return nullptr ;
515520 }
521+ // Sanity check for the start state.
522+ if (impl->Start () != kNoStateId && impl->Start () >= state) {
523+ LOG (ERROR) << " VectorFst::Read: initial state " << impl->Start ()
524+ << " out of range [0, " << state << " )" ;
525+ return nullptr ;
526+ }
527+ // Sanity check on next states.
528+ if (min_next_state < 0 ) {
529+ LOG (ERROR) << " VectorFst::Read: Invalid arc.nextstate=" << min_next_state;
530+ return nullptr ;
531+ }
532+ if (max_next_state >= state) {
533+ LOG (ERROR) << " VectorFst::Read: Invalid arc.nextstate=" << max_next_state;
534+ return nullptr ;
535+ }
516536 return impl.release ();
517537}
518538
0 commit comments