about summary refs log tree commit diff stats
path: root/016dilated_reagent.cc
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2016-10-21 01:08:09 -0700
committerKartik K. Agaram <vc@akkartik.com>2016-10-21 01:13:27 -0700
commit66abe7c1bd54ca227b9e035d52a1c2f1ea387b5e (patch)
tree9fc885faa5b4878247d4411bd0d72c1c59cc5f92 /016dilated_reagent.cc
parent22d93b76718a9e260c1969adf53fc0559cf24355 (diff)
downloadmu-66abe7c1bd54ca227b9e035d52a1c2f1ea387b5e.tar.gz
3539
Always check if next_word() returned an empty string (if it hit eof).

Thanks Rebecca Allard for running into a crash when a .mu file ends with
'{' (without a following newline).

Open question: how to express the constraint that next_word() should
always check if its result is empty? Can *any* type system do that?!
Even the usual constraint that we must use a result isn't iron-clad: you
could save the result in a variable but then ignore it. Unless you go to
Go's extraordinary lengths of considering any dead code an error.
Diffstat (limited to '016dilated_reagent.cc')
-rw-r--r--016dilated_reagent.cc21
1 files changed, 19 insertions, 2 deletions
diff --git a/016dilated_reagent.cc b/016dilated_reagent.cc
index b7c8ecc4..1d89ba8d 100644
--- a/016dilated_reagent.cc
+++ b/016dilated_reagent.cc
@@ -107,7 +107,13 @@ if (starts_with(s, "{")) {
     return;
   }
   {
-    string_tree* type_names = new string_tree(next_word(in));
+    string s = next_word(in);
+    if (s.empty()) {
+      assert(!has_data(in));
+      raise << "incomplete dilated reagent at end of file (0)\n" << end();
+      return;
+    }
+    string_tree* type_names = new string_tree(s);
     // End Parsing Dilated Reagent Type Property(type_names)
     type = new_type_tree(type_names);
     delete type_names;
@@ -116,7 +122,13 @@ if (starts_with(s, "{")) {
     string key = slurp_key(in);
     if (key.empty()) continue;
     if (key == "}") continue;
-    string_tree* value = new string_tree(next_word(in));
+    string s = next_word(in);
+    if (s.empty()) {
+      assert(!has_data(in));
+      raise << "incomplete dilated reagent at end of file (1)\n" << end();
+      return;
+    }
+    string_tree* value = new string_tree(s);
     // End Parsing Dilated Reagent Property(value)
     properties.push_back(pair<string, string_tree*>(key, value));
   }
@@ -126,6 +138,11 @@ if (starts_with(s, "{")) {
 :(code)
 string slurp_key(istream& in) {
   string result = next_word(in);
+  if (result.empty()) {
+    assert(!has_data(in));
+    raise << "incomplete dilated reagent at end of file (2)\n" << end();
+    return result;
+  }
   while (!result.empty() && *result.rbegin() == ':')
     strip_last(result);
   while (isspace(in.peek()) || in.peek() == ':')