Ignore:
Timestamp:
12/12/14 12:05:51 (6 years ago)
Author:
rlacroix
Message:

Fix a possible infinite loop in the duration parser and make parsing stricter.

  • Some malformed duration strings could cause an infinite loop in the parser.
  • Invalid duration strings will now cause an error message to be displayed.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • XIOS/trunk/src/duration.cpp

    r501 r539  
    4242      } 
    4343 
    44       StdIStream & operator>>(StdIStream & in , CDuration & duration) 
     44      StdIStream& operator>>(StdIStream& in , CDuration& duration) 
    4545      { 
    46          duration.year = duration.month  = duration.day    = 
    47          duration.hour = duration.minute = duration.second = duration.timestep=0.0; 
    48          double v = 1.0; 
    49          char   c = '/'; 
    50          while (!in.eof()) 
    51          { 
    52                if (!(in >> v >> c))  
    53                { 
    54                  //DEBUG("----> Pb StdIStream & operator>>(StdIStream & in , CDuration & duration)") ; 
    55                  //if (in.eof())  DEBUG("----> Fin de fichier StdIStream & operator>>(StdIStream & in , CDuration & duration)") ; 
    56                } 
    57                if (in.eof())   
    58                { 
    59                  //DEBUG("----> Fin de fichier StdIStream & operator>>(StdIStream & in , CDuration & duration)") ; 
    60                  break ; 
    61                } 
    62                switch (c) 
    63                { 
    64                   case 'y': duration.year   = v; break; 
    65                   case 'd': duration.day    = v; break; 
    66                   case 'h': duration.hour   = v; break; 
    67                   case 's': duration.second = v; break; 
    68                   case 'm': 
    69                   { 
    70                      in >> c; 
    71                      if     (c == 'i') duration.minute = v; 
    72                      else if(c == 'o') duration.month  = v; 
    73                      else 
    74                      { 
    75                         StdString valc("m"); valc.append(1, c); 
    76                         //DEBUG("La chaine \"" << valc << "\" ne permet pas de définir une unité de durée."); 
    77                         break; 
    78                      } 
    79                      break; 
    80                   } 
    81                   case 't' : 
    82                   { 
    83                     in >> c; 
    84                     if (c=='s') duration.timestep = v;  
    85                     break; 
    86                   } 
    87                    
    88                   default: 
    89                      StdString valc; valc.append(1, c); 
    90                      //DEBUG("La chaine \"" << valc << "\" ne permet pas de définir une unité de durée."); 
    91                      break; 
    92                } 
     46        duration = NoneDu; 
     47        double v = 1.0; 
     48        char   c = '/'; 
     49        bool   invalidUnit = false; 
     50 
     51        do 
     52        { 
     53          in >> v >> c; 
     54          if (in.fail()) 
     55            ERROR("StdIStream& operator>>(StdIStream& in , CDuration& duration)", 
     56                  << "Bad duration format: impossible to read a pair (value, unit)."); 
     57 
     58          switch (c) 
     59          { 
     60            case 'y': duration.year   = v; break; 
     61            case 'd': duration.day    = v; break; 
     62            case 'h': duration.hour   = v; break; 
     63            case 's': duration.second = v; break; 
     64            case 'm': 
     65            { 
     66              in >> c; 
     67              if      (c == 'i') duration.minute = v; 
     68              else if (c == 'o') duration.month  = v; 
     69              else invalidUnit = true; 
     70              break; 
    9371            } 
    94             return (in); 
     72            case 't': 
     73            { 
     74              in >> c; 
     75              if (c == 's') duration.timestep = v; 
     76              else invalidUnit = true; 
     77              break; 
     78            } 
     79            default: 
     80              invalidUnit = true;  
     81              break; 
     82          } 
     83 
     84          if (invalidUnit) 
     85            ERROR("StdIStream& operator>>(StdIStream& in , CDuration& duration)", 
     86                  << "Bad duration format: invalid unit, unexpected '" << c << "' character."); 
     87        } while (in.peek() != EOF); // check whether there is a next character to read  
     88 
     89        return in; 
    9590      } 
    9691 
Note: See TracChangeset for help on using the changeset viewer.