summaryrefslogtreecommitdiff
path: root/ninja/src/deps_log.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ninja/src/deps_log.cc')
-rw-r--r--ninja/src/deps_log.cc57
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(&timestamp, 4, 1, file_);
+ if (fwrite(&timestamp, 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);