CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/ext/libzip/zip_buffer.c
Views: 1401
1
/*
2
zip_buffer.c -- bounds checked access to memory buffer
3
Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
4
5
This file is part of libzip, a library to manipulate ZIP archives.
6
The authors can be contacted at <[email protected]>
7
8
Redistribution and use in source and binary forms, with or without
9
modification, are permitted provided that the following conditions
10
are met:
11
1. Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
2. Redistributions in binary form must reproduce the above copyright
14
notice, this list of conditions and the following disclaimer in
15
the documentation and/or other materials provided with the
16
distribution.
17
3. The names of the authors may not be used to endorse or promote
18
products derived from this software without specific prior
19
written permission.
20
21
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
22
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
25
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
29
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
31
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
*/
33
34
#include <stdlib.h>
35
#include <string.h>
36
37
#include "zipint.h"
38
39
zip_uint8_t *
40
_zip_buffer_data(zip_buffer_t *buffer) {
41
return buffer->data;
42
}
43
44
45
void
46
_zip_buffer_free(zip_buffer_t *buffer) {
47
if (buffer == NULL) {
48
return;
49
}
50
51
if (buffer->free_data) {
52
free(buffer->data);
53
}
54
55
free(buffer);
56
}
57
58
59
bool
60
_zip_buffer_eof(zip_buffer_t *buffer) {
61
return buffer->ok && buffer->offset == buffer->size;
62
}
63
64
65
zip_uint8_t *
66
_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length) {
67
zip_uint8_t *data;
68
69
data = _zip_buffer_peek(buffer, length);
70
71
if (data != NULL) {
72
buffer->offset += length;
73
}
74
75
return data;
76
}
77
78
79
zip_uint16_t
80
_zip_buffer_get_16(zip_buffer_t *buffer) {
81
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
82
83
if (data == NULL) {
84
return 0;
85
}
86
87
return (zip_uint16_t)(data[0] + (data[1] << 8));
88
}
89
90
91
zip_uint32_t
92
_zip_buffer_get_32(zip_buffer_t *buffer) {
93
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
94
95
if (data == NULL) {
96
return 0;
97
}
98
99
return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0];
100
}
101
102
103
zip_uint64_t
104
_zip_buffer_get_64(zip_buffer_t *buffer) {
105
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
106
107
if (data == NULL) {
108
return 0;
109
}
110
111
return ((zip_uint64_t)data[7] << 56) + ((zip_uint64_t)data[6] << 48) + ((zip_uint64_t)data[5] << 40) + ((zip_uint64_t)data[4] << 32) + ((zip_uint64_t)data[3] << 24) + ((zip_uint64_t)data[2] << 16) + ((zip_uint64_t)data[1] << 8) + (zip_uint64_t)data[0];
112
}
113
114
115
zip_uint8_t
116
_zip_buffer_get_8(zip_buffer_t *buffer) {
117
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
118
119
if (data == NULL) {
120
return 0;
121
}
122
123
return data[0];
124
}
125
126
127
zip_uint64_t
128
_zip_buffer_left(zip_buffer_t *buffer) {
129
return buffer->ok ? buffer->size - buffer->offset : 0;
130
}
131
132
133
zip_uint64_t
134
_zip_buffer_read(zip_buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length) {
135
if (_zip_buffer_left(buffer) < length) {
136
length = _zip_buffer_left(buffer);
137
}
138
139
memcpy(data, _zip_buffer_get(buffer, length), length);
140
141
return length;
142
}
143
144
145
zip_buffer_t *
146
_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size) {
147
bool free_data = (data == NULL);
148
zip_buffer_t *buffer;
149
150
if (data == NULL) {
151
if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
152
return NULL;
153
}
154
}
155
156
if ((buffer = (zip_buffer_t *)malloc(sizeof(*buffer))) == NULL) {
157
if (free_data) {
158
free(data);
159
}
160
return NULL;
161
}
162
163
buffer->ok = true;
164
buffer->data = data;
165
buffer->size = size;
166
buffer->offset = 0;
167
buffer->free_data = free_data;
168
169
return buffer;
170
}
171
172
173
zip_buffer_t *
174
_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error) {
175
zip_buffer_t *buffer;
176
177
if ((buffer = _zip_buffer_new(buf, size)) == NULL) {
178
zip_error_set(error, ZIP_ER_MEMORY, 0);
179
return NULL;
180
}
181
182
if (_zip_read(src, buffer->data, size, error) < 0) {
183
_zip_buffer_free(buffer);
184
return NULL;
185
}
186
187
return buffer;
188
}
189
190
191
zip_uint64_t
192
_zip_buffer_offset(zip_buffer_t *buffer) {
193
return buffer->ok ? buffer->offset : 0;
194
}
195
196
197
bool
198
_zip_buffer_ok(zip_buffer_t *buffer) {
199
return buffer->ok;
200
}
201
202
203
zip_uint8_t *
204
_zip_buffer_peek(zip_buffer_t *buffer, zip_uint64_t length) {
205
zip_uint8_t *data;
206
207
if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
208
buffer->ok = false;
209
return NULL;
210
}
211
212
data = buffer->data + buffer->offset;
213
return data;
214
}
215
216
int
217
_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length) {
218
zip_uint8_t *dst = _zip_buffer_get(buffer, length);
219
220
if (dst == NULL) {
221
return -1;
222
}
223
224
memcpy(dst, src, length);
225
return 0;
226
}
227
228
229
int
230
_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i) {
231
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
232
233
if (data == NULL) {
234
return -1;
235
}
236
237
data[0] = (zip_uint8_t)(i & 0xff);
238
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
239
240
return 0;
241
}
242
243
244
int
245
_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i) {
246
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
247
248
if (data == NULL) {
249
return -1;
250
}
251
252
data[0] = (zip_uint8_t)(i & 0xff);
253
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
254
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
255
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
256
257
return 0;
258
}
259
260
261
int
262
_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i) {
263
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
264
265
if (data == NULL) {
266
return -1;
267
}
268
269
data[0] = (zip_uint8_t)(i & 0xff);
270
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
271
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
272
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
273
data[4] = (zip_uint8_t)((i >> 32) & 0xff);
274
data[5] = (zip_uint8_t)((i >> 40) & 0xff);
275
data[6] = (zip_uint8_t)((i >> 48) & 0xff);
276
data[7] = (zip_uint8_t)((i >> 56) & 0xff);
277
278
return 0;
279
}
280
281
282
int
283
_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i) {
284
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
285
286
if (data == NULL) {
287
return -1;
288
}
289
290
data[0] = i;
291
292
return 0;
293
}
294
295
296
int
297
_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset) {
298
if (offset > buffer->size) {
299
buffer->ok = false;
300
return -1;
301
}
302
303
buffer->ok = true;
304
buffer->offset = offset;
305
306
return 0;
307
}
308
309
310
int
311
_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) {
312
zip_uint64_t offset = buffer->offset + length;
313
314
if (offset < buffer->offset) {
315
buffer->ok = false;
316
return -1;
317
}
318
return _zip_buffer_set_offset(buffer, offset);
319
}
320
321
zip_uint64_t
322
_zip_buffer_size(zip_buffer_t *buffer) {
323
return buffer->size;
324
}
325
326