diff options
Diffstat (limited to 'ninja/src/deps_log.cc')
-rw-r--r-- | ninja/src/deps_log.cc | 57 |
1 files changed, 42 insertions, 15 deletions
diff --git a/ninja/src/deps_log.cc b/ninja/src/deps_log.cc index ce9bf06b3f3..2c4e3c29a1f 100644 --- a/ninja/src/deps_log.cc +++ b/ninja/src/deps_log.cc @@ -37,13 +37,15 @@ const int kCurrentVersion = 1; // buffer after every record to make sure records aren't written partially. const int kMaxBufferSize = 1 << 15; +// Record size is currently limited to 15 bit +const size_t kMaxRecordSize = (1 << 15) - 1; + DepsLog::~DepsLog() { Close(); } bool DepsLog::OpenForWrite(const string& path, string* err) { if (needs_recompaction_) { - Close(); if (!Recompact(path, err)) return false; } @@ -70,8 +72,10 @@ bool DepsLog::OpenForWrite(const string& path, string* err) { return false; } } - fflush(file_); - + if (fflush(file_) != 0) { + *err = strerror(errno); + return false; + } return true; } @@ -88,12 +92,14 @@ bool DepsLog::RecordDeps(Node* node, TimeStamp mtime, // Assign ids to all nodes that are missing one. if (node->id() < 0) { - RecordId(node); + if (!RecordId(node)) + return false; made_change = true; } for (int i = 0; i < node_count; ++i) { if (nodes[i]->id() < 0) { - RecordId(nodes[i]); + if (!RecordId(nodes[i])) + return false; made_change = true; } } @@ -120,18 +126,28 @@ bool DepsLog::RecordDeps(Node* node, TimeStamp mtime, return true; // Update on-disk representation. - uint16_t size = 4 * (1 + 1 + (uint16_t)node_count); + size_t size = 4 * (1 + 1 + (uint16_t)node_count); + if (size > kMaxRecordSize) { + errno = ERANGE; + return false; + } size |= 0x8000; // Deps record: set high bit. - fwrite(&size, 2, 1, file_); + uint16_t size16 = (uint16_t)size; + if (fwrite(&size16, 2, 1, file_) < 1) + return false; int id = node->id(); - fwrite(&id, 4, 1, file_); + if (fwrite(&id, 4, 1, file_) < 1) + return false; int timestamp = mtime; - fwrite(×tamp, 4, 1, file_); + if (fwrite(×tamp, 4, 1, file_) < 1) + return false; for (int i = 0; i < node_count; ++i) { id = nodes[i]->id(); - fwrite(&id, 4, 1, file_); + if (fwrite(&id, 4, 1, file_) < 1) + return false; } - fflush(file_); + if (fflush(file_) != 0) + return false; // Update in-memory representation. Deps* deps = new Deps(mtime, node_count); @@ -265,6 +281,7 @@ bool DepsLog::Recompact(const string& path, string* err) { METRIC_RECORD(".ninja_deps recompact"); printf("Recompacting deps...\n"); + Close(); string temp_path = path + ".recompact"; // OpenForWrite() opens for append. Make sure it's not appending to a @@ -323,10 +340,20 @@ bool DepsLog::UpdateDeps(int out_id, Deps* deps) { } bool DepsLog::RecordId(Node* node) { - uint16_t size = (uint16_t)node->path().size(); - fwrite(&size, 2, 1, file_); - fwrite(node->path().data(), node->path().size(), 1, file_); - fflush(file_); + size_t size = node->path().size(); + if (size > kMaxRecordSize) { + errno = ERANGE; + return false; + } + uint16_t size16 = (uint16_t)size; + if (fwrite(&size16, 2, 1, file_) < 1) + return false; + if (fwrite(node->path().data(), node->path().size(), 1, file_) < 1) { + assert(node->path().size() > 0); + return false; + } + if (fflush(file_) != 0) + return false; node->set_id(nodes_.size()); nodes_.push_back(node); |