diff options
-rw-r--r-- | src/build_log.cc | 10 | ||||
-rw-r--r-- | src/build_log_test.cc | 28 |
2 files changed, 35 insertions, 3 deletions
diff --git a/src/build_log.cc b/src/build_log.cc index cd74bd1..c630fbe 100644 --- a/src/build_log.cc +++ b/src/build_log.cc @@ -144,8 +144,15 @@ bool BuildLog::Load(const string& path, string* err) { } end = strchr(start, ' '); + if (!end) + continue; string output = string(start, end - start); + start = end + 1; + end = strchr(start, '\n'); + if (!end) + continue; + LogEntry* entry; Log::iterator i = log_.find(output); if (i != log_.end()) { @@ -160,9 +167,6 @@ bool BuildLog::Load(const string& path, string* err) { entry->output = output; entry->start_time = start_time; entry->end_time = end_time; - - start = end + 1; - end = strchr(start, '\n'); entry->command = string(start, end - start); } diff --git a/src/build_log_test.cc b/src/build_log_test.cc index caf1540..8bb2bfa 100644 --- a/src/build_log_test.cc +++ b/src/build_log_test.cc @@ -69,3 +69,31 @@ TEST_F(BuildLogTest, DoubleEntry) { ASSERT_TRUE(e); ASSERT_EQ("command def", e->command); } + +TEST_F(BuildLogTest, Truncate) { + AssertParse(&state_, +"build out: cat mid\n" +"build mid: cat in\n"); + + BuildLog log1; + string err; + EXPECT_TRUE(log1.OpenForWrite(kTestFilename, &err)); + ASSERT_EQ("", err); + log1.RecordCommand(state_.edges_[0], 15, 18); + log1.RecordCommand(state_.edges_[1], 20, 25); + log1.Close(); + + struct stat statbuf; + ASSERT_EQ(0, stat(kTestFilename, &statbuf)); + ASSERT_GT(statbuf.st_size, 0); + + // For all possible truncations of the input file, assert that we don't + // crash or report an error when parsing. + for (off_t size = statbuf.st_size; size > 0; --size) { + ASSERT_EQ(0, truncate(kTestFilename, size)); + + BuildLog log2; + EXPECT_TRUE(log2.Load(kTestFilename, &err)); + ASSERT_EQ("", err); + } +} |