Coverage Report

Created: 2024-07-27 06:13

/src/lzma-fuzz/common-buffer.h
Line
Count
Source (jump to first uncovered line)
1
/**
2
 *
3
 * @copyright Copyright (c) 2019 Joachim Bauch <mail@joachim-bauch.de>
4
 *
5
 * @license GNU GPL version 3 or any later version
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 *
20
 */
21
22
#include <assert.h>
23
#include <stdint.h>
24
#include <stdlib.h>
25
#include <string.h>
26
27
#include "7zTypes.h"
28
29
class OutputBuffer {
30
 public:
31
  OutputBuffer();
32
  ~OutputBuffer();
33
34
7.24k
  ISeqOutStream *stream() { return &stream_.vt; };
35
0
  const uint8_t *data() const { return data_; }
36
0
  size_t size() const { return position_; }
37
38
 private:
39
  static const size_t kInitialSize = 128;
40
41
  typedef struct {
42
    ISeqOutStream vt;
43
    OutputBuffer *buffer;
44
  } OutputBufferStream;
45
46
  static size_t _Write(const ISeqOutStream *pp, const void *data, size_t size);
47
  size_t Write(const void *data, size_t size);
48
49
  OutputBufferStream stream_;
50
  uint8_t *data_ = nullptr;
51
  size_t size_ = 0;
52
  size_t position_ = 0;
53
};
54
55
7.24k
OutputBuffer::OutputBuffer() {
56
7.24k
  stream_.vt.Write = &OutputBuffer::_Write;
57
7.24k
  stream_.buffer = this;
58
7.24k
}
59
60
7.24k
OutputBuffer::~OutputBuffer() {
61
7.24k
  free(data_);
62
7.24k
}
63
64
// static
65
size_t OutputBuffer::_Write(const ISeqOutStream *p, const void *data,
66
4.72k
    size_t size) {
67
4.72k
  OutputBufferStream *stream = CONTAINER_FROM_VTBL(p, OutputBufferStream, vt);
68
4.72k
  return stream->buffer->Write(data, size);
69
4.72k
}
70
71
4.72k
size_t OutputBuffer::Write(const void *data, size_t size) {
72
4.72k
  size_t available = size_ - position_;
73
4.72k
  if (available < size) {
74
4.50k
    if (!size_) {
75
4.22k
      size_ = kInitialSize;
76
4.22k
    }
77
17.2k
    while (size_ - position_ < size) {
78
12.7k
      size_ *= 2;
79
12.7k
    }
80
4.50k
    uint8_t *tmp = static_cast<uint8_t*>(malloc(size_));
81
4.50k
    assert(tmp);
82
4.50k
    if (data_) {
83
282
      memcpy(tmp, data_, position_);
84
282
      free(data_);
85
282
    }
86
4.50k
    data_ = tmp;
87
4.50k
  }
88
89
4.72k
  memcpy(data_ + position_, data, size);
90
4.72k
  position_ += size;
91
4.72k
  return size;
92
4.72k
}
93
94
class OutputByteBuffer {
95
 public:
96
  OutputByteBuffer();
97
  ~OutputByteBuffer();
98
99
0
  IByteOut *stream() { return &stream_.vt; };
100
0
  const uint8_t *data() const { return data_; }
101
0
  size_t size() const { return position_; }
102
103
 private:
104
  static const size_t kInitialSize = 128;
105
106
  typedef struct {
107
    IByteOut vt;
108
    OutputByteBuffer *buffer;
109
  } ByteOutStream;
110
111
  static void _Write(const IByteOut *pp, Byte b);
112
  void Write(Byte b);
113
114
  ByteOutStream stream_;
115
  uint8_t *data_ = nullptr;
116
  size_t size_ = 0;
117
  size_t position_ = 0;
118
};
119
120
0
OutputByteBuffer::OutputByteBuffer() {
121
0
  stream_.vt.Write = &OutputByteBuffer::_Write;
122
0
  stream_.buffer = this;
123
0
}
124
125
0
OutputByteBuffer::~OutputByteBuffer() {
126
0
  free(data_);
127
0
}
128
129
// static
130
0
void OutputByteBuffer::_Write(const IByteOut *p, Byte b) {
131
0
  ByteOutStream *stream = CONTAINER_FROM_VTBL(p, ByteOutStream, vt);
132
0
  stream->buffer->Write(b);
133
0
}
134
135
0
void OutputByteBuffer::Write(Byte b) {
136
0
  if (size_ == position_) {
137
0
    if (!size_) {
138
0
      size_ = kInitialSize;
139
0
    } else {
140
0
      size_ *= 2;
141
0
    }
142
0
    uint8_t *tmp = static_cast<uint8_t*>(malloc(size_));
143
0
    assert(tmp);
144
0
    if (data_) {
145
0
      memcpy(tmp, data_, position_);
146
0
      free(data_);
147
0
    }
148
0
    data_ = tmp;
149
0
  }
150
151
0
  data_[position_++] = b;
152
0
}
153
154
class InputBuffer {
155
 public:
156
  InputBuffer(const uint8_t *data, size_t size);
157
158
7.24k
  ISeqInStream *stream() { return &stream_.vt; };
159
160
 private:
161
  typedef struct {
162
    ISeqInStream vt;
163
    InputBuffer *buffer;
164
  } InputBufferStream;
165
166
  static SRes _Read(const ISeqInStream *p, void *data, size_t *size);
167
  SRes Read(void *data, size_t *size);
168
169
  InputBufferStream stream_;
170
  const uint8_t *data_;
171
  size_t size_;
172
};
173
174
InputBuffer::InputBuffer(const uint8_t *data, size_t size)
175
7.24k
  : data_(data), size_(size) {
176
7.24k
  stream_.vt.Read = &InputBuffer::_Read;
177
7.24k
  stream_.buffer = this;
178
7.24k
}
179
180
// static
181
12.3k
SRes InputBuffer::_Read(const ISeqInStream *p, void *data, size_t *size) {
182
12.3k
  InputBufferStream *stream = CONTAINER_FROM_VTBL(p, InputBufferStream, vt);
183
12.3k
  return stream->buffer->Read(data, size);
184
12.3k
}
185
186
12.3k
SRes InputBuffer::Read(void *data, size_t *size) {
187
12.3k
  if (size_ < *size) {
188
12.1k
    *size = size_;
189
12.1k
  }
190
12.3k
  if (*size > 0) {
191
7.38k
    memcpy(data, data_, *size);
192
7.38k
    size_ -= *size;
193
7.38k
    data_ += *size;
194
7.38k
  }
195
12.3k
  return SZ_OK;
196
12.3k
}
197
198
class InputByteBuffer {
199
 public:
200
  InputByteBuffer(const uint8_t *data, size_t size);
201
202
0
  IByteIn *stream() { return &stream_.vt; };
203
204
 private:
205
  typedef struct {
206
    IByteIn vt;
207
    InputByteBuffer *buffer;
208
  } ByteInStream;
209
210
  static Byte _Read(const IByteIn *p);
211
  Byte Read();
212
213
  ByteInStream stream_;
214
  const uint8_t *data_;
215
  size_t size_;
216
  size_t position_ = 0;
217
};
218
219
InputByteBuffer::InputByteBuffer(const uint8_t *data, size_t size)
220
0
  : data_(data), size_(size) {
221
0
  stream_.vt.Read = &InputByteBuffer::_Read;
222
0
  stream_.buffer = this;
223
0
}
224
225
// static
226
0
Byte InputByteBuffer::_Read(const IByteIn *p) {
227
0
  ByteInStream *stream = CONTAINER_FROM_VTBL(p, ByteInStream, vt);
228
0
  return stream->buffer->Read();
229
0
}
230
231
0
Byte InputByteBuffer::Read() {
232
0
  if (size_ == position_) {
233
0
    return 0;
234
0
  }
235
236
0
  return data_[position_++];
237
0
}
238
239
class InputLookBuffer {
240
 public:
241
  InputLookBuffer(const uint8_t *data, size_t size);
242
243
0
  ILookInStream *stream() { return &stream_.vt; };
244
245
 private:
246
  typedef struct {
247
    ILookInStream vt;
248
    InputLookBuffer *buffer;
249
  } InputLookBufferStream;
250
251
  static SRes _Look(const ILookInStream *p, const void **data, size_t *size);
252
  SRes Look(const void **data, size_t *size);
253
  static SRes _Skip(const ILookInStream *p, size_t offset);
254
  SRes Skip(size_t offset);
255
  static SRes _Read(const ILookInStream *p, void *data, size_t *size);
256
  SRes Read(void *data, size_t *size);
257
  static SRes _Seek(const ILookInStream *p, Int64 *pos, ESzSeek origin);
258
  SRes Seek(Int64 *pos, ESzSeek origin);
259
260
  InputLookBufferStream stream_;
261
  const uint8_t *data_;
262
  size_t size_;
263
  size_t position_ = 0;
264
};
265
266
InputLookBuffer::InputLookBuffer(const uint8_t *data, size_t size)
267
0
  : data_(data), size_(size) {
268
0
  stream_.vt.Look = &InputLookBuffer::_Look;
269
0
  stream_.vt.Skip = &InputLookBuffer::_Skip;
270
0
  stream_.vt.Read = &InputLookBuffer::_Read;
271
0
  stream_.vt.Seek = &InputLookBuffer::_Seek;
272
0
  stream_.buffer = this;
273
0
}
274
275
// static
276
SRes InputLookBuffer::_Look(const ILookInStream *p, const void **data,
277
0
    size_t *size) {
278
0
  InputLookBufferStream *stream =
279
0
      CONTAINER_FROM_VTBL(p, InputLookBufferStream, vt);
280
0
  return stream->buffer->Look(data, size);
281
0
}
282
283
0
SRes InputLookBuffer::Look(const void **data, size_t *size) {
284
0
  size_t available = size_ - position_;
285
0
  if (available < *size) {
286
0
    *size = available;
287
0
  }
288
0
  *data = data_ + position_;
289
0
  return SZ_OK;
290
0
}
291
292
// static
293
0
SRes InputLookBuffer::_Skip(const ILookInStream *p, size_t offset) {
294
0
  InputLookBufferStream *stream =
295
0
      CONTAINER_FROM_VTBL(p, InputLookBufferStream, vt);
296
0
  return stream->buffer->Skip(offset);
297
0
}
298
299
0
SRes InputLookBuffer::Skip(size_t offset) {
300
0
  size_t available = size_ - position_;
301
0
  if (offset > available) {
302
0
    offset = available;
303
0
  }
304
0
  position_ += offset;
305
0
  return SZ_OK;
306
0
}
307
308
// static
309
0
SRes InputLookBuffer::_Read(const ILookInStream *p, void *data, size_t *size) {
310
0
  InputLookBufferStream *stream =
311
0
      CONTAINER_FROM_VTBL(p, InputLookBufferStream, vt);
312
0
  return stream->buffer->Read(data, size);
313
0
}
314
315
0
SRes InputLookBuffer::Read(void *data, size_t *size) {
316
0
  size_t available = size_ - position_;
317
0
  if (available < *size) {
318
0
    *size = available;
319
0
  }
320
0
  if (*size > 0) {
321
0
    memcpy(data, data_ + position_, *size);
322
0
    position_ += *size;
323
0
  }
324
0
  return SZ_OK;
325
0
}
326
327
// static
328
SRes InputLookBuffer::_Seek(const ILookInStream *p, Int64 *pos,
329
0
    ESzSeek origin) {
330
0
  InputLookBufferStream *stream =
331
0
      CONTAINER_FROM_VTBL(p, InputLookBufferStream, vt);
332
0
  return stream->buffer->Seek(pos, origin);
333
0
}
334
335
0
SRes InputLookBuffer::Seek(Int64 *pos, ESzSeek origin) {
336
0
  switch (origin) {
337
0
    case SZ_SEEK_SET:
338
0
      if (*pos > size_) {
339
0
        *pos = size_;
340
0
      } else if (*pos < 0) {
341
0
        *pos = 0;
342
0
      }
343
0
      position_ = *pos;
344
0
      break;
345
0
    case SZ_SEEK_CUR:
346
0
      if (*pos > size_ || position_ + *pos > size_) {
347
0
        *pos = size_;
348
0
      } else if (position_ < -*pos) {
349
0
        *pos = 0;
350
0
      }
351
0
      position_ += *pos;
352
0
      break;
353
0
    case SZ_SEEK_END:
354
0
      if (*pos >= 0) {
355
0
        *pos = size_;
356
0
      } else if (-(*pos) > size_) {
357
0
        *pos = 0;
358
0
      } else {
359
0
        *pos = size_ + *pos;
360
0
      }
361
0
      position_ = *pos;
362
0
      break;
363
0
    default:
364
0
      return SZ_ERROR_PARAM;
365
0
  }
366
0
  return SZ_OK;
367
0
}