Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

read() and write() may fail, we do not check for this #1682

Open
daniel-j-h opened this issue Sep 13, 2015 · 2 comments
Open

read() and write() may fail, we do not check for this #1682

daniel-j-h opened this issue Sep 13, 2015 · 2 comments

Comments

@daniel-j-h
Copy link
Member

All our reads via stream.read(...) are unchecked. That is, in case of extraction failures or premature eof, we silently go on with uninitialized data structures (hint: undefined behavior anyone?).

Note: ticket explains for read, same applies to write.

Two solutions are possible:

  • check the read function's return value (stream&) via its operator bool conversion
  • let streams throw on error (not on per default, to mock with developers)
int main() try {
  std::ifstream in{"bin"};
  assert(in);
  // in.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ifstream::eofbit);
  // --^

  std::vector<char> v(10);
  auto& rc = in.read(v.data(), 10);

  if(!rc) {
  // --^
    if(rc.eof()) 
      return 10;
    if(rc.bad()) 
      return 11;
    if(rc.fail()) 
      return 12;
  }

} catch(const std::exception& e) {
  std::cerr << e.what() << std::endl;
}

Discussion: I think we can automate this to a certain degree with a clever substitution to turn

x.read(y,z);

into

ensure(x.read(y,z));

relying on the returned stream's conversion to bool in a boolean context, with ensure being a assert-like function that also triggers in release builds and potentially throws.

References:

@daniel-j-h daniel-j-h changed the title std::basic_istream::read may fail, we do not check for this read() and write() may fail, we do not check for this Feb 26, 2016
@daniel-j-h
Copy link
Member Author

daniel-j-h commented Feb 26, 2016

Updated ticket, same applies for writing. As of now, this is the state we're in:

$ rg '\.read\((.*),(.*)\);' |wc -l
62
$ rg '\.write\((.*),(.*)\);' |wc -l
50

@danpat
Copy link
Member

danpat commented Dec 8, 2016

We're partway there with #3383 and #3321

$ ag '\.read\((.*),(.*)\);' |wc -l
       5
$ ag '\.write\((.*),(.*)\);' | wc -l
      51

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants