Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
cpython
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
cpython
Commits
5f8f0d67
Kaydet (Commit)
5f8f0d67
authored
Eki 21, 2012
tarafından
Nadeem Vawda
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Issue #14398: Fix size truncation and overflow bugs in bz2 module.
üst
66510fed
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
199 additions
and
135 deletions
+199
-135
test_bz2.py
Lib/test/test_bz2.py
+39
-1
testbz2_bigmem.bz2
Lib/test/testbz2_bigmem.bz2
+0
-0
NEWS
Misc/NEWS
+2
-0
bz2module.c
Modules/bz2module.c
+158
-134
No files found.
Lib/test/test_bz2.py
Dosyayı görüntüle @
5f8f0d67
#!/usr/bin/env python3
from
test
import
support
from
test.support
import
TESTFN
from
test.support
import
TESTFN
,
_4G
,
bigmemtest
,
findfile
import
unittest
from
io
import
BytesIO
...
...
@@ -25,6 +25,9 @@ class BaseTest(unittest.TestCase):
DATA
=
b
'BZh91AY&SY.
\xc8
N
\x18\x00\x01
>_
\x80\x00\x10
@
\x02\xff\xf0\x01\x07
n
\x00
?
\xe7\xff\xe0
0
\x01\x99\xaa\x00\xc0\x03
F
\x86\x8c
#&
\x83
F
\x9a\x03\x06\xa6\xd0\xa6\x93
M
\x0f
Q
\xa7\xa8\x06\x80
4hh
\x12
$
\x11\xa4
i4
\xf1
4S
\xd2
<Q
\xb5\x0f
H
\xd3\xd4\xdd\xd5\x87\xbb\xf8\x94\r\x8f\xaf
I
\x12\xe1\xc9\xf8
/E
\x00
pu
\x89\x12
]
\xc9\xbb
DL
\n
Q
\x0e\t
1
\x12\xdf\xa0\xc0\x97\xac
2O9
\x89\x13\x94\x0e\x1c
7
\x0e
d
\x95
I
\x0c\xaa
J
\xa4\x18
L
\x10\x05
#
\x9c\xaf\xba\xbc
/
\x97\x8a
#C
\xc8\xe1\x8c
W
\xf9\xe2\xd0\xd6
M
\xa7\x8b
Xa<e
\x84
t
\xcb
L
\xb3\xa7\xd9\xcd\xd1\xcb\x84
.
\xaf\xb3\xab\xab\xad
`n}
\xa0
lh
\t
E,
\x8e
Z
\x15\x17
VH>
\x88\xe5\xcd
9gd6
\x0b\n\xe9\x9b\xd5\x8a\x99\xf7\x08
.K
\x8e
v
\xfb\xf7
xw
\xbb\xdf\xa1\x92\xf1\xdd
|/";
\xa2\xba\x9f\xd5\xb1
#A
\xb6\xf6\xb3
o
\xc9\xc5
y
\\\xeb
O
\xe7\x85\x9a\xbc\xb6
f8
\x95
2
\xd5\xd7
"
%
\x89
>V,
\xf7\xa6
z
\xe2\x9f\xa3\xdf\x11\x11
"
\xd6
E)I
\xa9\x13
^
\xca\xf3
r
\xd0\x03
U
\x92
2
\xf2
6
\xec\xb6\xed\x8b\xc3
U
\x13\x9d\xc5\x17
0
\xa4\xfa
^
\x92\xac
DF
\x8a\x97\xd6\x19\xfe\xdd\xb8\xbd\x1a\x9a\x19\xa3\x80
ankR
\x8b\xe5\xd8
3]
\xa9\xc6\x08\x82
f
\xf6\xb9
"6l$
\xb8
j@
\xc0\x8a\xb0
l1..
\xba
k
\x83
ls
\x15\xbc\xf4\xc1\x13\xbe\xf8
E
\xb8\x9d\r\xa8\x9d
k
\x84\xd3
n
\xfa\xac
Q
\x07\xb1
%
y
\xaa
v
\xb4\x08\xe0
z
\x1b\x16\xf5\x04\xe9\xcc\xb9\x08
z
\x1e
n7.G
\xfc
]
\xc9\x14\xe1
B@
\xbb
!8`'
DATA_CRLF
=
b
'BZh91AY&SY
\xae
z
\xbb
N
\x00\x01
H
\xdf\x80\x00\x12
@
\x02\xff\xf0\x01\x07
n
\x00
?
\xe7\xff\xe0
@
\x01\xbc\xc6
`
\x86
*
\x8d
=M
\xa9\x9a\x86\xd0
L@
\x0f
I
\xa6
!
\xa1\x13\xc8\x88
jdi
\x8d
@
\x03
@
\x1a\x1a\x0c\x0c\x83
\x00\xc4
h2
\x19\x01\x82
D
\x84
e
\t\xe8\x99\x89\x19\x1a
h
\x00\r\x1a\x11\xaf\x9b\x0f
G
\xf5
(
\x1b\x1f
?
\t\x12\xcf\xb5\xfc\x95
E
\x00
ps
\x89\x12
^
\xa4\xdd\xa2
&
\x05
(
\x87\x04\x98\x89
u
\xe4
0
%
\xb6\x19\'\x8c\xc4\x89\xca\x07\x0e\x1b
!
\x91
UIFU
%
C
\x99
4!DI
\xd2\xfa\xf0\xf1
N8W
\xde\x13
A
\xf5\x9c
r
%
?
\x9f
3;I45A
\xd1\x8b
T
\xb1
<l
\xba\xcb
_
\xc0
0xY
\x17
r
\x17\x88\x08\x08
@
\xa0\r
y@
\x10\x04
$)`
\xf2\xce\x89
z
\xb0
s
\xec\x9b
.iW
\x9d\x81\xb5
-+t
\x9f\x1a\'\x97
dB
\xf5
x
\xb5\xbe
.[.
\xd7\x0e\x81\xe7\x08\x1c
N`
\x88\x10\xca\x87\xc3
!"
\x80\x92
R
\xa1
/
\xd1\xc0\xe6
mf
\xac\xbd\x99\xcc
a
\xb3\x87
80>
\xa4\xc7\x8d\x1a\\
"
\xad\xa1\xab
yBg
\x15\xb9
l
\x88\x88\x91
k"
\x94\xa4\xd4\x89\xae
*
\xa6\x0b\x10\x0c\xd6\xd4
m
\xe8
6
\xec\xb5
j
\x8a\x86
j
\'
;
\xca
.
\x01
I
\xf2\xaa
J
\xe8\x88\x8c
U+t3
\xfb\x0c\n\xa3
3
\x13
r2
\r\x16\xe0\xb3
(
\xbf\x1d\x83
r
\xe7
M
\xf0
D
\x13
65
\xd8\x88\xd3\xa4\x92\xcb
2
\x06\x04\\\xc1\xb0\xea
//
\xbe
k&
\xd8\xe6
+t
\xe5\xa1\x13\xad
a
\x16\xde
r5"w]
\xa2
i
\xb7
[
\x97
R
\xe2
IT
\xcd
;Z
\x04
dk4
\xad\x8a\t\xd3\x81
z
\x10\xf1
:^`
\xab\x1f\xc5\xdc\x91
N
\x14
$+
\x9e\xae\xd3\x80
'
with
open
(
findfile
(
"testbz2_bigmem.bz2"
),
"rb"
)
as
f
:
DATA_BIGMEM
=
f
.
read
()
if
has_cmdline_bunzip2
:
def
decompress
(
self
,
data
):
pop
=
subprocess
.
Popen
(
"bunzip2"
,
shell
=
True
,
...
...
@@ -44,6 +47,7 @@ class BaseTest(unittest.TestCase):
def
decompress
(
self
,
data
):
return
bz2
.
decompress
(
data
)
class
BZ2FileTest
(
BaseTest
):
"Test BZ2File type miscellaneous methods."
...
...
@@ -313,6 +317,17 @@ class BZ2CompressorTest(BaseTest):
data
+=
bz2c
.
flush
()
self
.
assertEqual
(
self
.
decompress
(
data
),
self
.
TEXT
)
@bigmemtest
(
size
=
_4G
,
memuse
=
1.25
)
def
testBigmem
(
self
,
size
):
text
=
b
"a"
*
size
bz2c
=
bz2
.
BZ2Compressor
()
data
=
bz2c
.
compress
(
text
)
+
bz2c
.
flush
()
del
text
text
=
self
.
decompress
(
data
)
self
.
assertEqual
(
len
(
text
),
size
)
self
.
assertEqual
(
text
.
strip
(
b
"a"
),
b
""
)
class
BZ2DecompressorTest
(
BaseTest
):
def
test_Constructor
(
self
):
self
.
assertRaises
(
TypeError
,
BZ2Decompressor
,
42
)
...
...
@@ -351,6 +366,13 @@ class BZ2DecompressorTest(BaseTest):
text
=
bz2d
.
decompress
(
self
.
DATA
)
self
.
assertRaises
(
EOFError
,
bz2d
.
decompress
,
b
"anything"
)
@bigmemtest
(
size
=
_4G
,
memuse
=
1.25
,
dry_run
=
False
)
def
testBigmem
(
self
,
unused_size
):
# Issue #14398: decompression fails when output data is >=2GB.
text
=
bz2
.
BZ2Decompressor
()
.
decompress
(
self
.
DATA_BIGMEM
)
self
.
assertEqual
(
len
(
text
),
_4G
)
self
.
assertEqual
(
text
.
strip
(
b
"
\0
"
),
b
""
)
class
FuncTest
(
BaseTest
):
"Test module functions"
...
...
@@ -374,6 +396,22 @@ class FuncTest(BaseTest):
# "Test decompress() function with incomplete data"
self
.
assertRaises
(
ValueError
,
bz2
.
decompress
,
self
.
DATA
[:
-
10
])
@bigmemtest
(
size
=
_4G
,
memuse
=
1.25
)
def
testCompressBigmem
(
self
,
size
):
text
=
b
"a"
*
size
data
=
bz2
.
compress
(
text
)
del
text
text
=
self
.
decompress
(
data
)
self
.
assertEqual
(
len
(
text
),
size
)
self
.
assertEqual
(
text
.
strip
(
b
"a"
),
b
""
)
@bigmemtest
(
size
=
_4G
,
memuse
=
1.25
,
dry_run
=
False
)
def
testDecompressBigmem
(
self
,
unused_size
):
# Issue #14398: decompression fails when output data is >=2GB.
text
=
bz2
.
decompress
(
self
.
DATA_BIGMEM
)
self
.
assertEqual
(
len
(
text
),
_4G
)
self
.
assertEqual
(
text
.
strip
(
b
"
\0
"
),
b
""
)
def
test_main
():
support
.
run_unittest
(
BZ2FileTest
,
...
...
Lib/test/testbz2_bigmem.bz2
0 → 100644
Dosyayı görüntüle @
5f8f0d67
File added
Misc/NEWS
Dosyayı görüntüle @
5f8f0d67
...
...
@@ -132,6 +132,8 @@ Core and Builtins
Library
-------
- Issue #14398: Fix size truncation and overflow bugs in the bz2 module.
- Issue #16220: wsgiref now always calls close() on an iterable response.
Patch by Brent Tubbs.
...
...
Modules/bz2module.c
Dosyayı görüntüle @
5f8f0d67
...
...
@@ -41,23 +41,8 @@ typedef fpos_t Py_off_t;
#define MODE_READ_EOF 2
#define MODE_WRITE 3
#define BZ2FileObject_Check(v) (Py_TYPE(v) == &BZ2File_Type)
#ifdef BZ_CONFIG_ERROR
#if SIZEOF_LONG >= 8
#define BZS_TOTAL_OUT(bzs) \
(((long)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
#elif SIZEOF_LONG_LONG >= 8
#define BZS_TOTAL_OUT(bzs) \
(((PY_LONG_LONG)bzs->total_out_hi32 << 32) + bzs->total_out_lo32)
#else
#define BZS_TOTAL_OUT(bzs) \
bzs->total_out_lo32
#endif
#else
/* ! BZ_CONFIG_ERROR */
#ifndef BZ_CONFIG_ERROR
#define BZ2_bzRead bzRead
#define BZ2_bzReadOpen bzReadOpen
...
...
@@ -72,8 +57,6 @@ typedef fpos_t Py_off_t;
#define BZ2_bzDecompressInit bzDecompressInit
#define BZ2_bzDecompressEnd bzDecompressEnd
#define BZS_TOTAL_OUT(bzs) bzs->total_out
#endif
/* ! BZ_CONFIG_ERROR */
...
...
@@ -90,11 +73,7 @@ typedef fpos_t Py_off_t;
#define RELEASE_LOCK(obj)
#endif
/* Bits in f_newlinetypes */
#define NEWLINE_UNKNOWN 0
/* No newline seen, yet */
#define NEWLINE_CR 1
/* \r newline seen */
#define NEWLINE_LF 2
/* \n newline seen */
#define NEWLINE_CRLF 4
/* \r\n newline seen */
#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))
/* ===================================================================== */
/* Structure definitions. */
...
...
@@ -228,6 +207,20 @@ Util_NewBufferSize(size_t currentsize)
return
currentsize
+
(
currentsize
>>
3
)
+
6
;
}
static
int
Util_GrowBuffer
(
PyObject
**
buf
)
{
size_t
size
=
PyBytes_GET_SIZE
(
*
buf
);
size_t
new_size
=
Util_NewBufferSize
(
size
);
if
(
new_size
>
size
)
{
return
_PyBytes_Resize
(
buf
,
new_size
);
}
else
{
/* overflow */
PyErr_SetString
(
PyExc_OverflowError
,
"Unable to allocate buffer - output too large"
);
return
-
1
;
}
}
/* This is a hacked version of Python's fileobject.c:get_line(). */
static
PyObject
*
Util_GetLine
(
BZ2FileObject
*
f
,
int
n
)
...
...
@@ -1418,20 +1411,16 @@ static PyObject *
BZ2Comp_compress
(
BZ2CompObject
*
self
,
PyObject
*
args
)
{
Py_buffer
pdata
;
char
*
data
;
int
datasize
;
int
bufsize
=
SMALLCHUNK
;
PY_LONG_LONG
totalout
;
size_t
input_left
;
size_t
output_size
=
0
;
PyObject
*
ret
=
NULL
;
bz_stream
*
bzs
=
&
self
->
bzs
;
int
bzerror
;
if
(
!
PyArg_ParseTuple
(
args
,
"y*:compress"
,
&
pdata
))
return
NULL
;
data
=
pdata
.
buf
;
datasize
=
pdata
.
len
;
if
(
datasize
==
0
)
{
if
(
pdata
.
len
==
0
)
{
PyBuffer_Release
(
&
pdata
);
return
PyBytes_FromStringAndSize
(
""
,
0
);
}
...
...
@@ -1443,41 +1432,51 @@ BZ2Comp_compress(BZ2CompObject *self, PyObject *args)
goto
error
;
}
ret
=
PyBytes_FromStringAndSize
(
NULL
,
bufsize
);
ret
=
PyBytes_FromStringAndSize
(
NULL
,
SMALLCHUNK
);
if
(
!
ret
)
goto
error
;
bzs
->
next_in
=
data
;
bzs
->
avail_in
=
datasize
;
bzs
->
next_out
=
BUF
(
ret
);
bzs
->
avail_out
=
bufsize
;
bzs
->
next_in
=
pdata
.
buf
;
bzs
->
avail_in
=
MIN
(
pdata
.
len
,
UINT_MAX
);
input_left
=
pdata
.
len
-
bzs
->
avail_in
;
totalout
=
BZS_TOTAL_OUT
(
bzs
);
bzs
->
next_out
=
BUF
(
ret
);
bzs
->
avail_out
=
PyBytes_GET_SIZE
(
ret
);
for
(;;)
{
char
*
saved_next_out
;
Py_BEGIN_ALLOW_THREADS
saved_next_out
=
bzs
->
next_out
;
bzerror
=
BZ2_bzCompress
(
bzs
,
BZ_RUN
);
output_size
+=
bzs
->
next_out
-
saved_next_out
;
Py_END_ALLOW_THREADS
if
(
bzerror
!=
BZ_RUN_OK
)
{
Util_CatchBZ2Error
(
bzerror
);
goto
error
;
}
if
(
bzs
->
avail_in
==
0
)
if
(
bzs
->
avail_in
==
0
)
{
if
(
input_left
==
0
)
break
;
/* no more input data */
bzs
->
avail_in
=
MIN
(
input_left
,
UINT_MAX
);
input_left
-=
bzs
->
avail_in
;
}
if
(
bzs
->
avail_out
==
0
)
{
bufsize
=
Util_NewBufferSize
(
bufsize
);
if
(
_PyBytes_Resize
(
&
ret
,
bufsize
)
<
0
)
{
size_t
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
if
(
buffer_left
==
0
)
{
if
(
Util_GrowBuffer
(
&
ret
)
<
0
)
{
BZ2_bzCompressEnd
(
bzs
);
goto
error
;
}
bzs
->
next_out
=
BUF
(
ret
)
+
(
BZS_TOTAL_OUT
(
bzs
)
-
totalout
);
bzs
->
avail_out
=
bufsize
-
(
bzs
->
next_out
-
BUF
(
ret
));
bzs
->
next_out
=
BUF
(
ret
)
+
output_size
;
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
}
bzs
->
avail_out
=
MIN
(
buffer_left
,
UINT_MAX
);
}
}
if
(
_PyBytes_Resize
(
&
ret
,
(
Py_ssize_t
)(
BZS_TOTAL_OUT
(
bzs
)
-
totalout
))
<
0
)
if
(
_PyBytes_Resize
(
&
ret
,
output_size
)
<
0
)
goto
error
;
RELEASE_LOCK
(
self
);
...
...
@@ -1501,33 +1500,34 @@ You must not use the compressor object after calling this method.\n\
static
PyObject
*
BZ2Comp_flush
(
BZ2CompObject
*
self
)
{
int
bufsize
=
SMALLCHUNK
;
size_t
output_size
=
0
;
PyObject
*
ret
=
NULL
;
bz_stream
*
bzs
=
&
self
->
bzs
;
PY_LONG_LONG
totalout
;
int
bzerror
;
ACQUIRE_LOCK
(
self
);
if
(
!
self
->
running
)
{
PyErr_SetString
(
PyExc_ValueError
,
"object was already "
"flushed"
);
PyErr_SetString
(
PyExc_ValueError
,
"object was already flushed"
);
goto
error
;
}
self
->
running
=
0
;
ret
=
PyBytes_FromStringAndSize
(
NULL
,
bufsize
);
ret
=
PyBytes_FromStringAndSize
(
NULL
,
SMALLCHUNK
);
if
(
!
ret
)
goto
error
;
bzs
->
next_out
=
BUF
(
ret
);
bzs
->
avail_out
=
bufsize
;
totalout
=
BZS_TOTAL_OUT
(
bzs
);
bzs
->
avail_out
=
PyBytes_GET_SIZE
(
ret
);
for
(;;)
{
char
*
saved_next_out
;
Py_BEGIN_ALLOW_THREADS
saved_next_out
=
bzs
->
next_out
;
bzerror
=
BZ2_bzCompress
(
bzs
,
BZ_FINISH
);
output_size
+=
bzs
->
next_out
-
saved_next_out
;
Py_END_ALLOW_THREADS
if
(
bzerror
==
BZ_STREAM_END
)
{
break
;
}
else
if
(
bzerror
!=
BZ_FINISH_OK
)
{
...
...
@@ -1535,21 +1535,20 @@ BZ2Comp_flush(BZ2CompObject *self)
goto
error
;
}
if
(
bzs
->
avail_out
==
0
)
{
bufsize
=
Util_NewBufferSize
(
bufsize
);
if
(
_PyBytes_Resize
(
&
ret
,
bufsize
)
<
0
)
size_t
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
if
(
buffer_left
==
0
)
{
if
(
Util_GrowBuffer
(
&
ret
)
<
0
)
goto
error
;
bzs
->
next_out
=
BUF
(
ret
)
;
bzs
->
next_out
=
BUF
(
ret
)
+
(
BZS_TOTAL_OUT
(
bzs
)
-
totalout
);
bzs
->
avail_out
=
bufsize
-
(
bzs
->
next_out
-
BUF
(
ret
)
);
bzs
->
next_out
=
BUF
(
ret
)
+
output_size
;
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
}
bzs
->
avail_out
=
MIN
(
buffer_left
,
UINT_MAX
);
}
}
if
(
bzs
->
avail_out
!=
0
)
{
if
(
_PyBytes_Resize
(
&
ret
,
(
Py_ssize_t
)(
BZS_TOTAL_OUT
(
bzs
)
-
totalout
))
<
0
)
if
(
output_size
!=
PyBytes_GET_SIZE
(
ret
))
if
(
_PyBytes_Resize
(
&
ret
,
output_size
)
<
0
)
goto
error
;
}
RELEASE_LOCK
(
self
);
return
ret
;
...
...
@@ -1714,18 +1713,14 @@ static PyObject *
BZ2Decomp_decompress
(
BZ2DecompObject
*
self
,
PyObject
*
args
)
{
Py_buffer
pdata
;
char
*
data
;
int
datasize
;
int
bufsize
=
SMALLCHUNK
;
PY_LONG_LONG
totalout
;
size_t
input_left
;
size_t
output_size
=
0
;
PyObject
*
ret
=
NULL
;
bz_stream
*
bzs
=
&
self
->
bzs
;
int
bzerror
;
if
(
!
PyArg_ParseTuple
(
args
,
"y*:decompress"
,
&
pdata
))
return
NULL
;
data
=
pdata
.
buf
;
datasize
=
pdata
.
len
;
ACQUIRE_LOCK
(
self
);
if
(
!
self
->
running
)
{
...
...
@@ -1734,55 +1729,65 @@ BZ2Decomp_decompress(BZ2DecompObject *self, PyObject *args)
goto
error
;
}
ret
=
PyBytes_FromStringAndSize
(
NULL
,
bufsize
);
ret
=
PyBytes_FromStringAndSize
(
NULL
,
SMALLCHUNK
);
if
(
!
ret
)
goto
error
;
bzs
->
next_in
=
data
;
bzs
->
avail_in
=
datasize
;
bzs
->
next_out
=
BUF
(
ret
);
bzs
->
avail_out
=
bufsize
;
bzs
->
next_in
=
pdata
.
buf
;
bzs
->
avail_in
=
MIN
(
pdata
.
len
,
UINT_MAX
);
input_left
=
pdata
.
len
-
bzs
->
avail_in
;
totalout
=
BZS_TOTAL_OUT
(
bzs
);
bzs
->
next_out
=
BUF
(
ret
);
bzs
->
avail_out
=
PyBytes_GET_SIZE
(
ret
);
for
(;;)
{
char
*
saved_next_out
;
Py_BEGIN_ALLOW_THREADS
saved_next_out
=
bzs
->
next_out
;
bzerror
=
BZ2_bzDecompress
(
bzs
);
output_size
+=
bzs
->
next_out
-
saved_next_out
;
Py_END_ALLOW_THREADS
if
(
bzerror
==
BZ_STREAM_END
)
{
if
(
bzs
->
avail_in
!=
0
)
{
self
->
running
=
0
;
input_left
+=
bzs
->
avail_in
;
if
(
input_left
!=
0
)
{
Py_DECREF
(
self
->
unused_data
);
self
->
unused_data
=
PyBytes_FromStringAndSize
(
bzs
->
next_in
,
bzs
->
avail_in
);
PyBytes_FromStringAndSize
(
bzs
->
next_in
,
input_left
);
if
(
self
->
unused_data
==
NULL
)
goto
error
;
}
self
->
running
=
0
;
break
;
}
if
(
bzerror
!=
BZ_OK
)
{
Util_CatchBZ2Error
(
bzerror
);
goto
error
;
}
if
(
bzs
->
avail_in
==
0
)
if
(
bzs
->
avail_in
==
0
)
{
if
(
input_left
==
0
)
break
;
/* no more input data */
bzs
->
avail_in
=
MIN
(
input_left
,
UINT_MAX
);
input_left
-=
bzs
->
avail_in
;
}
if
(
bzs
->
avail_out
==
0
)
{
bufsize
=
Util_NewBufferSize
(
bufsize
);
if
(
_PyBytes_Resize
(
&
ret
,
bufsize
)
<
0
)
{
size_t
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
if
(
buffer_left
==
0
)
{
if
(
Util_GrowBuffer
(
&
ret
)
<
0
)
{
BZ2_bzDecompressEnd
(
bzs
);
goto
error
;
}
bzs
->
next_out
=
BUF
(
ret
)
;
bzs
->
next_out
=
BUF
(
ret
)
+
(
BZS_TOTAL_OUT
(
bzs
)
-
totalout
);
bzs
->
avail_out
=
bufsize
-
(
bzs
->
next_out
-
BUF
(
ret
)
);
bzs
->
next_out
=
BUF
(
ret
)
+
output_size
;
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
}
bzs
->
avail_out
=
MIN
(
buffer_left
,
UINT_MAX
);
}
}
if
(
bzs
->
avail_out
!=
0
)
{
if
(
_PyBytes_Resize
(
&
ret
,
(
Py_ssize_t
)(
BZS_TOTAL_OUT
(
bzs
)
-
totalout
))
<
0
)
if
(
output_size
!=
PyBytes_GET_SIZE
(
ret
))
if
(
_PyBytes_Resize
(
&
ret
,
output_size
)
<
0
)
goto
error
;
}
RELEASE_LOCK
(
self
);
PyBuffer_Release
(
&
pdata
);
...
...
@@ -1929,10 +1934,10 @@ static PyObject *
bz2_compress
(
PyObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
int
compresslevel
=
9
;
int
action
;
Py_buffer
pdata
;
char
*
data
;
int
datasize
;
int
bufsize
;
size_t
input_left
;
size_t
output_size
=
0
;
PyObject
*
ret
=
NULL
;
bz_stream
_bzs
;
bz_stream
*
bzs
=
&
_bzs
;
...
...
@@ -1943,8 +1948,6 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
kwlist
,
&
pdata
,
&
compresslevel
))
return
NULL
;
data
=
pdata
.
buf
;
datasize
=
pdata
.
len
;
if
(
compresslevel
<
1
||
compresslevel
>
9
)
{
PyErr_SetString
(
PyExc_ValueError
,
...
...
@@ -1953,11 +1956,7 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
return
NULL
;
}
/* Conforming to bz2 manual, this is large enough to fit compressed
* data in one shot. We will check it later anyway. */
bufsize
=
datasize
+
(
datasize
/
100
+
1
)
+
600
;
ret
=
PyBytes_FromStringAndSize
(
NULL
,
bufsize
);
ret
=
PyBytes_FromStringAndSize
(
NULL
,
SMALLCHUNK
);
if
(
!
ret
)
{
PyBuffer_Release
(
&
pdata
);
return
NULL
;
...
...
@@ -1965,10 +1964,12 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
memset
(
bzs
,
0
,
sizeof
(
bz_stream
));
bzs
->
next_in
=
data
;
bzs
->
avail_in
=
datasize
;
bzs
->
next_in
=
pdata
.
buf
;
bzs
->
avail_in
=
MIN
(
pdata
.
len
,
UINT_MAX
);
input_left
=
pdata
.
len
-
bzs
->
avail_in
;
bzs
->
next_out
=
BUF
(
ret
);
bzs
->
avail_out
=
bufsize
;
bzs
->
avail_out
=
PyBytes_GET_SIZE
(
ret
)
;
bzerror
=
BZ2_bzCompressInit
(
bzs
,
compresslevel
,
0
,
0
);
if
(
bzerror
!=
BZ_OK
)
{
...
...
@@ -1978,38 +1979,53 @@ bz2_compress(PyObject *self, PyObject *args, PyObject *kwargs)
return
NULL
;
}
action
=
BZ_RUN
;
for
(;;)
{
char
*
saved_next_out
;
Py_BEGIN_ALLOW_THREADS
bzerror
=
BZ2_bzCompress
(
bzs
,
BZ_FINISH
);
saved_next_out
=
bzs
->
next_out
;
bzerror
=
BZ2_bzCompress
(
bzs
,
action
);
output_size
+=
bzs
->
next_out
-
saved_next_out
;
Py_END_ALLOW_THREADS
if
(
bzerror
==
BZ_STREAM_END
)
{
break
;
}
else
if
(
bzerror
!=
BZ_FINISH_OK
)
{
}
else
if
(
bzerror
!=
BZ_
RUN_OK
&&
bzerror
!=
BZ_
FINISH_OK
)
{
BZ2_bzCompressEnd
(
bzs
);
Util_CatchBZ2Error
(
bzerror
);
PyBuffer_Release
(
&
pdata
);
Py_DECREF
(
ret
);
return
NULL
;
}
if
(
action
==
BZ_RUN
&&
bzs
->
avail_in
==
0
)
{
if
(
input_left
==
0
)
{
action
=
BZ_FINISH
;
}
else
{
bzs
->
avail_in
=
MIN
(
input_left
,
UINT_MAX
);
input_left
-=
bzs
->
avail_in
;
}
}
if
(
bzs
->
avail_out
==
0
)
{
bufsize
=
Util_NewBufferSize
(
bufsize
);
if
(
_PyBytes_Resize
(
&
ret
,
bufsize
)
<
0
)
{
size_t
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
if
(
buffer_left
==
0
)
{
if
(
Util_GrowBuffer
(
&
ret
)
<
0
)
{
BZ2_bzCompressEnd
(
bzs
);
PyBuffer_Release
(
&
pdata
);
return
NULL
;
}
bzs
->
next_out
=
BUF
(
ret
)
+
BZS_TOTAL_OUT
(
bzs
)
;
bzs
->
avail_out
=
bufsize
-
(
bzs
->
next_out
-
BUF
(
ret
))
;
bzs
->
next_out
=
BUF
(
ret
)
+
output_size
;
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
}
bzs
->
avail_out
=
MIN
(
buffer_left
,
UINT_MAX
);
}
if
(
bzs
->
avail_out
!=
0
)
{
if
(
_PyBytes_Resize
(
&
ret
,
(
Py_ssize_t
)
BZS_TOTAL_OUT
(
bzs
))
<
0
)
{
ret
=
NULL
;
}
}
BZ2_bzCompressEnd
(
bzs
);
if
(
output_size
!=
PyBytes_GET_SIZE
(
ret
))
_PyBytes_Resize
(
&
ret
,
output_size
);
/* Sets ret to NULL on failure. */
BZ2_bzCompressEnd
(
bzs
);
PyBuffer_Release
(
&
pdata
);
return
ret
;
}
...
...
@@ -2025,9 +2041,8 @@ static PyObject *
bz2_decompress
(
PyObject
*
self
,
PyObject
*
args
)
{
Py_buffer
pdata
;
char
*
data
;
int
datasize
;
int
bufsize
=
SMALLCHUNK
;
size_t
input_left
;
size_t
output_size
=
0
;
PyObject
*
ret
;
bz_stream
_bzs
;
bz_stream
*
bzs
=
&
_bzs
;
...
...
@@ -2035,15 +2050,13 @@ bz2_decompress(PyObject *self, PyObject *args)
if
(
!
PyArg_ParseTuple
(
args
,
"y*:decompress"
,
&
pdata
))
return
NULL
;
data
=
pdata
.
buf
;
datasize
=
pdata
.
len
;
if
(
datasize
==
0
)
{
if
(
pdata
.
len
==
0
)
{
PyBuffer_Release
(
&
pdata
);
return
PyBytes_FromStringAndSize
(
""
,
0
);
}
ret
=
PyBytes_FromStringAndSize
(
NULL
,
bufsize
);
ret
=
PyBytes_FromStringAndSize
(
NULL
,
SMALLCHUNK
);
if
(
!
ret
)
{
PyBuffer_Release
(
&
pdata
);
return
NULL
;
...
...
@@ -2051,10 +2064,12 @@ bz2_decompress(PyObject *self, PyObject *args)
memset
(
bzs
,
0
,
sizeof
(
bz_stream
));
bzs
->
next_in
=
data
;
bzs
->
avail_in
=
datasize
;
bzs
->
next_in
=
pdata
.
buf
;
bzs
->
avail_in
=
MIN
(
pdata
.
len
,
UINT_MAX
);
input_left
=
pdata
.
len
-
bzs
->
avail_in
;
bzs
->
next_out
=
BUF
(
ret
);
bzs
->
avail_out
=
bufsize
;
bzs
->
avail_out
=
PyBytes_GET_SIZE
(
ret
)
;
bzerror
=
BZ2_bzDecompressInit
(
bzs
,
0
,
0
);
if
(
bzerror
!=
BZ_OK
)
{
...
...
@@ -2065,9 +2080,14 @@ bz2_decompress(PyObject *self, PyObject *args)
}
for
(;;)
{
char
*
saved_next_out
;
Py_BEGIN_ALLOW_THREADS
saved_next_out
=
bzs
->
next_out
;
bzerror
=
BZ2_bzDecompress
(
bzs
);
output_size
+=
bzs
->
next_out
-
saved_next_out
;
Py_END_ALLOW_THREADS
if
(
bzerror
==
BZ_STREAM_END
)
{
break
;
}
else
if
(
bzerror
!=
BZ_OK
)
{
...
...
@@ -2078,6 +2098,7 @@ bz2_decompress(PyObject *self, PyObject *args)
return
NULL
;
}
if
(
bzs
->
avail_in
==
0
)
{
if
(
input_left
==
0
)
{
BZ2_bzDecompressEnd
(
bzs
);
PyErr_SetString
(
PyExc_ValueError
,
"couldn't find end of stream"
);
...
...
@@ -2085,26 +2106,29 @@ bz2_decompress(PyObject *self, PyObject *args)
Py_DECREF
(
ret
);
return
NULL
;
}
bzs
->
avail_in
=
MIN
(
input_left
,
UINT_MAX
);
input_left
-=
bzs
->
avail_in
;
}
if
(
bzs
->
avail_out
==
0
)
{
bufsize
=
Util_NewBufferSize
(
bufsize
);
if
(
_PyBytes_Resize
(
&
ret
,
bufsize
)
<
0
)
{
size_t
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
if
(
buffer_left
==
0
)
{
if
(
Util_GrowBuffer
(
&
ret
)
<
0
)
{
BZ2_bzDecompressEnd
(
bzs
);
PyBuffer_Release
(
&
pdata
);
return
NULL
;
}
bzs
->
next_out
=
BUF
(
ret
)
+
BZS_TOTAL_OUT
(
bzs
)
;
bzs
->
avail_out
=
bufsize
-
(
bzs
->
next_out
-
BUF
(
ret
))
;
bzs
->
next_out
=
BUF
(
ret
)
+
output_size
;
buffer_left
=
PyBytes_GET_SIZE
(
ret
)
-
output_size
;
}
}
if
(
bzs
->
avail_out
!=
0
)
{
if
(
_PyBytes_Resize
(
&
ret
,
(
Py_ssize_t
)
BZS_TOTAL_OUT
(
bzs
))
<
0
)
{
ret
=
NULL
;
bzs
->
avail_out
=
MIN
(
buffer_left
,
UINT_MAX
);
}
}
if
(
output_size
!=
PyBytes_GET_SIZE
(
ret
))
_PyBytes_Resize
(
&
ret
,
output_size
);
/* Sets ret to NULL on failure. */
BZ2_bzDecompressEnd
(
bzs
);
PyBuffer_Release
(
&
pdata
);
return
ret
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment