Branch: Tag:

2014-09-05

2014-09-05 15:13:57 by Henrik Grubbström (Grubba) <grubba@grubba.org>

IOBuffer: Improved error recovery for read_h{string,buffer}().

Don't advance the buffer pointers if there's not enough data.

NB: Not a 100% robust. It will fail if io_avail() throws errors,
or if the holerith length is negative or too large.

1093:    struct pike_string *s;       len = io_read_number( THIS, bytes ); +  +  if (len < 0) { +  /* io_avail() in io_read_number() failed. */ +  push_int(0); +  return; +  } +  +  /* NB: We assume that io_avail() in io_read_string() doesn't throw. */    s = io_read_string( THIS, len ); -  if( s ) +  +  if( s ) {    push_string(s); -  else +  } else { +  io_rewind( THIS, bytes );    push_int(0);    } -  +  }       /*! @decl IOBuffer read_hbuffer( int n )    *! @decl IOBuffer read_hbuffer( int n, bool copy )
1121:    */    PIKEFUN IOBuffer read_hbuffer( int bytes, int|void copy )    { -  LONGEST len = io_read_number( THIS, bytes ); +  LONGEST len;    int do_copy = 0;    struct object *o; -  +     if( copy ) do_copy = copy->u.integer;    pop_n_elems(args);    -  if( (o = io_read_buffer( THIS, len, do_copy )) ) +  if (!io_avail( THIS, bytes )) { +  push_int(0); +  return; +  } +  +  len = io_read_number( THIS, bytes ); +  +  /* NB: We assume that io_avail() in io_read_buffer() doesn't throw. */ +  o = io_read_buffer( THIS, len, do_copy ); +  +  if( o ) {    push_object(o); -  else +  } else { +  io_rewind( THIS, bytes );    push_int(0);    } -  +  }       /*! @decl IOBuffer read_buffer( int n )    *! @decl IOBuffer read_buffer( int n, bool copy )