Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(617)

Side by Side Diff: util/file/string_file_writer.cc

Issue 432003005: Introduce MinidumpWritable, its dependencies, and their tests (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "util/file/string_file_writer.h"
16
17 #include <string.h>
18
19 #include "base/logging.h"
20 #include "base/numerics/safe_math.h"
21
22 namespace crashpad {
23
24 StringFileWriter::StringFileWriter() : string_(), offset_(0) {
25 }
26
27 StringFileWriter::~StringFileWriter() {
28 }
29
30 void StringFileWriter::Reset() {
31 string_.clear();
32 offset_ = 0;
33 }
34
35 bool StringFileWriter::Write(const void* data, size_t size) {
36 DCHECK(offset_.IsValid());
37
38 size_t offset = offset_.ValueOrDie();
Robert Sesek 2014/08/01 14:38:04 Mark this const so it isn't accidentally used as a
Mark Mentovai 2014/08/01 16:09:35 rsesek wrote:
39 if (offset > string_.size()) {
40 string_.resize(offset);
41 }
42
43 base::CheckedNumeric<ssize_t> new_offset = offset_;
44 new_offset += size;
45 if (!new_offset.IsValid()) {
46 LOG(ERROR) << "Write(): file too large";
47 return false;
48 }
49
50 string_.replace(offset, size, reinterpret_cast<const char*>(data), size);
51 offset_ = new_offset;
52
53 return true;
54 }
55
56 bool StringFileWriter::WriteIoVec(std::vector<WritableIoVec>* iovecs) {
57 DCHECK(offset_.IsValid());
58
59 if (iovecs->empty()) {
60 LOG(ERROR) << "WriteIoVec(): no iovecs";
61 return false;
62 }
63
64 // Avoid writing anything at all if it would cause an overflow.
65 base::CheckedNumeric<ssize_t> new_offset = offset_;
66 for (const WritableIoVec& iov : *iovecs) {
67 new_offset += iov.iov_len;
68 if (!new_offset.IsValid()) {
69 LOG(ERROR) << "WriteIoVec(): file too large";
70 return false;
71 }
72 }
73
74 for (const WritableIoVec& iov : *iovecs) {
75 if (!Write(iov.iov_base, iov.iov_len)) {
76 return false;
77 }
78 }
79
80 #ifndef NDEBUG
81 // The interface says that |iovecs| is not sacred, so scramble it to make sure
82 // that nobody depends on it.
83 memset(&(*iovecs)[0], 0xa5, sizeof((*iovecs)[0]) * iovecs->size());
84 #endif
85
86 return true;
87 }
88
89 off_t StringFileWriter::Seek(off_t offset, int whence) {
90 DCHECK(offset_.IsValid());
91
92 size_t base_offset;
93
94 switch (whence) {
95 case SEEK_SET:
96 base_offset = 0;
97 break;
98
99 case SEEK_CUR:
100 base_offset = offset_.ValueOrDie();
101 break;
102
103 case SEEK_END:
104 base_offset = string_.size();
105 break;
106
107 default:
108 LOG(ERROR) << "Seek(): invalid whence " << whence;
109 return -1;
110 }
111
112 if (!base::IsValueInRangeForNumericType<off_t>(base_offset)) {
113 LOG(ERROR) << "Seek(): base_offset " << base_offset << " invalid for off_t";
114 return -1;
115 }
116
117 base::CheckedNumeric<off_t> new_offset_checked(base_offset);
Robert Sesek 2014/08/01 14:38:04 Could use AssignIfInRange() for lines 112-117.
Mark Mentovai 2014/08/01 16:09:35 rsesek wrote:
118 new_offset_checked += offset;
119 if (!new_offset_checked.IsValid()) {
120 LOG(ERROR) << "Seek(): new_offset invalid";
121 return -1;
122 }
123
124 off_t new_offset = new_offset_checked.ValueOrDie();
125 if (!base::IsValueInRangeForNumericType<size_t>(new_offset)) {
Robert Sesek 2014/08/01 14:38:04 Same.
126 LOG(ERROR) << "Seek(): new_offset " << new_offset << " invalid for size_t";
127 return -1;
128 }
129
130 offset_ = new_offset;
131
132 return offset_.ValueOrDie();
133 }
134
135 } // namespace crashpad
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698