Skip to content

Commit aa79253

Browse files
committed
Set max_length as initial buffer size to prevent resizing of the return value
1 parent 7f8d02f commit aa79253

File tree

2 files changed

+21
-11
lines changed

2 files changed

+21
-11
lines changed

src/isal/igzip_lib.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -121,12 +121,27 @@ decompress_buf(IgzipDecompressor *self, Py_ssize_t max_length)
121121
compare against max_length and PyBytes_GET_SIZE we declare it as
122122
signed */
123123
PyObject * RetVal = NULL;
124-
Py_ssize_t obuflen = DEF_BUF_SIZE;
124+
Py_ssize_t hard_limit;
125+
126+
Py_ssize_t obuflen;
127+
125128
int err;
126129

127-
if (obuflen > max_length)
130+
if (max_length < 0) {
131+
hard_limit = PY_SSIZE_T_MAX;
132+
obuflen = DEF_BUF_SIZE;
133+
} else {
134+
// Assume that decompressor is used in file decompression with a fixed
135+
// block size of max_length. In that case we will reach max_length almost
136+
// always (except at the end of the file). So it makes sense to allocate
137+
// max_length.
138+
hard_limit = max_length;
128139
obuflen = max_length;
129-
140+
if (obuflen > DEF_MAX_INITIAL_BUF_SIZE){
141+
// Safeguard against memory overflow.
142+
obuflen == DEF_MAX_INITIAL_BUF_SIZE;
143+
}
144+
}
130145

131146
do {
132147
arrange_input_buffer(&(self->state.avail_in), &(self->avail_in_real));
@@ -136,7 +151,7 @@ decompress_buf(IgzipDecompressor *self, Py_ssize_t max_length)
136151
&(self->state.next_out),
137152
&RetVal,
138153
obuflen,
139-
max_length);
154+
hard_limit);
140155
if (obuflen == -1){
141156
PyErr_SetString(PyExc_MemoryError,
142157
"Unsufficient memory for buffer allocation");
@@ -176,12 +191,6 @@ decompress(IgzipDecompressor *self, uint8_t *data, size_t len, Py_ssize_t max_le
176191
char input_buffer_in_use;
177192
PyObject *result;
178193

179-
Py_ssize_t hard_limit;
180-
if (max_length < 0) {
181-
hard_limit = PY_SSIZE_T_MAX;
182-
} else {
183-
hard_limit = max_length;
184-
}
185194
/* Prepend unconsumed input if necessary */
186195
if (self->state.next_in != NULL) {
187196
size_t avail_now, avail_total;
@@ -227,7 +236,7 @@ decompress(IgzipDecompressor *self, uint8_t *data, size_t len, Py_ssize_t max_le
227236
input_buffer_in_use = 0;
228237
}
229238

230-
result = decompress_buf(self, hard_limit);
239+
result = decompress_buf(self, max_length);
231240
if(result == NULL) {
232241
self->state.next_in = NULL;
233242
return NULL;

src/isal/igzip_lib_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
/* Initial buffer size. */
2828
#define DEF_BUF_SIZE (16*1024)
29+
#define DEF_MAX_INITIAL_BUF_SIZE (16 * 1024 * 1024)
2930
#define ISAL_BEST_SPEED ISAL_DEF_MIN_LEVEL
3031
#define ISAL_BEST_COMPRESSION ISAL_DEF_MAX_LEVEL
3132
#define ISAL_DEFAULT_COMPRESSION 2

0 commit comments

Comments
 (0)