Skip Menu |

This queue is for tickets about the Compress-Raw-Zlib CPAN distribution.

Report information
The Basics
Id: 78079
Status: resolved
Priority: 0/
Queue: Compress-Raw-Zlib

People
Owner: Nobody in particular
Requestors: chip [...] pobox.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.054
Fixed in: 2.057



Subject: [PATCH] fix misuse of magic in API
It's required for all users of SVs that they arrange for get magic to be called exactly once. The code doesn't obey this, and as a result fails under the pending magicflags core patch; but in any case it's a Perl API violation. A patch is attached.
Subject: compress-magic-zlib.diff
diff --git a/cpan/Compress-Raw-Zlib/Zlib.xs b/cpan/Compress-Raw-Zlib/Zlib.xs index 9c493ae..e57a38a 100644 --- a/cpan/Compress-Raw-Zlib/Zlib.xs +++ b/cpan/Compress-Raw-Zlib/Zlib.xs @@ -575,9 +575,8 @@ char * string; croak("%s: buffer parameter is a reference to a reference", string) ; } - if (!SvOK(sv)) { - sv = newSVpv("", 0); - } + if (!SvOK(sv)) + sv = sv_2mortal(newSVpv("", 0)); return sv ; } @@ -593,6 +592,7 @@ char * string ; { dTHX; bool wipe = 0 ; + STRLEN na; SvGETMAGIC(sv); wipe = ! SvOK(sv) ; @@ -617,14 +617,11 @@ char * string ; if (SvREADONLY(sv) && PL_curcop != &PL_compiling) croak("%s: buffer parameter is read-only", string); - SvUPGRADE(sv, SVt_PV); - + SvUPGRADE(sv, SVt_PV) ; if (wipe) - SvCUR_set(sv, 0); - - SvOOK_off(sv); - SvPOK_only(sv); - + sv_setpv(sv, "") ; + else + (void)SvPVbyte_force(sv, na) ; return sv ; } @@ -797,13 +794,13 @@ _deflateInit(flags,level, method, windowBits, memLevel, strategy, bufsize, dicti /* Check if a dictionary has been specified */ - if (err == Z_OK && SvCUR(dictionary)) { + SvGETMAGIC(dictionary); + if (err == Z_OK && SvPOK(dictionary) && SvCUR(dictionary)) { #ifdef UTF8_AVAILABLE - if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1)) - croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter"); + if (DO_UTF8(dictionary) && !sv_utf8_downgrade(dictionary, 1)) + croak("Wide character in Compress::Raw::Zlib::Deflate::new dicrionary parameter"); #endif - err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVbyte_nolen(dictionary), - SvCUR(dictionary)) ; + err = deflateSetDictionary(&(s->stream), (const Bytef*) SvPVX(dictionary), SvCUR(dictionary)) ; s->dict_adler = s->stream.adler ; } @@ -926,11 +923,11 @@ deflate (s, buf, output) Compress::Raw::Zlib::deflateStream s SV * buf SV * output - uInt cur_length = NO_INIT - uInt increment = NO_INIT - uInt prefix = NO_INIT - int RETVAL = 0; - uLong bufinc = NO_INIT + PREINIT: + uInt cur_length; + uInt increment; + uInt prefix; + uLong bufinc; CODE: bufinc = s->bufsize; @@ -942,7 +939,7 @@ deflate (s, buf, output) if (DO_UTF8(buf) && !sv_utf8_downgrade(buf, 1)) croak("Wide character in Compress::Raw::Zlib::Deflate::deflate input parameter"); #endif - s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ; + s->stream.next_in = (Bytef*)SvPV_nomg_nolen(buf) ; s->stream.avail_in = SvCUR(buf) ; if (s->flags & FLAG_CRC32) @@ -963,7 +960,7 @@ deflate (s, buf, output) /* sv_setpvn(output, "", 0); */ } prefix = cur_length = SvCUR(output) ; - s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length; + s->stream.next_out = (Bytef*) SvPVX(output) + cur_length; increment = SvLEN(output) - cur_length; s->stream.avail_out = increment; #ifdef SETP_BYTE @@ -994,13 +991,14 @@ deflate (s, buf, output) s->deflateParams_out_length = 0; } #endif + RETVAL = Z_OK ; while (s->stream.avail_in != 0) { if (s->stream.avail_out == 0) { /* out of space in the output buffer so make it bigger */ Sv_Grow(output, SvLEN(output) + bufinc) ; cur_length += increment ; - s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ; + s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ; increment = bufinc ; s->stream.avail_out = increment; bufinc *= 2 ; @@ -1064,7 +1062,7 @@ flush(s, output, f=Z_FINISH) /* sv_setpvn(output, "", 0); */ } prefix = cur_length = SvCUR(output) ; - s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length; + s->stream.next_out = (Bytef*) SvPVX(output) + cur_length; increment = SvLEN(output) - cur_length; s->stream.avail_out = increment; #ifdef SETP_BYTE @@ -1101,7 +1099,7 @@ flush(s, output, f=Z_FINISH) /* consumed all the available output, so extend it */ Sv_Grow(output, SvLEN(output) + bufinc) ; cur_length += increment ; - s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ; + s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ; increment = bufinc ; s->stream.avail_out = increment; bufinc *= 2 ; @@ -1321,12 +1319,11 @@ inflate (s, buf, output, eof=FALSE) SV * buf SV * output bool eof + PREINIT: uInt cur_length = 0; uInt prefix_length = 0; int increment = 0; - STRLEN stmp = NO_INIT - uLong bufinc = NO_INIT - PREINIT: + uLong bufinc; #ifdef UTF8_AVAILABLE bool out_utf8 = FALSE; #endif @@ -1343,7 +1340,7 @@ inflate (s, buf, output, eof=FALSE) #endif /* initialise the input buffer */ - s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ; + s->stream.next_in = (Bytef*)SvPV_nomg_nolen(buf) ; s->stream.avail_in = SvCUR(buf) ; /* and retrieve the output buffer */ @@ -1375,7 +1372,7 @@ inflate (s, buf, output, eof=FALSE) */ if (SvLEN(output) > cur_length + 1) { - s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length; + s->stream.next_out = (Bytef*) SvPVX(output) + cur_length; increment = SvLEN(output) - cur_length - 1; s->stream.avail_out = increment; } @@ -1391,7 +1388,7 @@ inflate (s, buf, output, eof=FALSE) /* out of space in the output buffer so make it bigger */ Sv_Grow(output, SvLEN(output) + bufinc +1) ; cur_length += increment ; - s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ; + s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ; increment = bufinc ; s->stream.avail_out = increment; bufinc *= 2 ; @@ -1409,7 +1406,7 @@ Perl_sv_dump(output); */ if (RETVAL == Z_NEED_DICT && s->dictionary) { s->dict_adler = s->stream.adler ; RETVAL = inflateSetDictionary(&(s->stream), - (const Bytef*)SvPVbyte_nolen(s->dictionary), + (const Bytef*)SvPVX(s->dictionary), SvCUR(s->dictionary)); if (RETVAL == Z_OK) continue; @@ -1442,7 +1439,7 @@ Perl_sv_dump(output); */ /* out of space in the output buffer so make it bigger */ Sv_Grow(output, SvLEN(output) + bufinc) ; cur_length += increment ; - s->stream.next_out = (Bytef*) SvPVbyte_nolen(output) + cur_length ; + s->stream.next_out = (Bytef*) SvPVX(output) + cur_length ; increment = bufinc ; s->stream.avail_out = increment; bufinc *= 2 ; @@ -1472,12 +1469,12 @@ Perl_sv_dump(output); */ if (s->flags & FLAG_CRC32 ) s->crc32 = crc32(s->crc32, - (const Bytef*)SvPVbyte_nolen(output)+prefix_length, + (const Bytef*)SvPVX(output)+prefix_length, SvCUR(output)-prefix_length) ; if (s->flags & FLAG_ADLER32) s->adler32 = adler32(s->adler32, - (const Bytef*)SvPVbyte_nolen(output)+prefix_length, + (const Bytef*)SvPVX(output)+prefix_length, SvCUR(output)-prefix_length) ; /* fix the input buffer */ @@ -1485,7 +1482,7 @@ Perl_sv_dump(output); */ in = s->stream.avail_in ; SvCUR_set(buf, in) ; if (in) - Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ; + Move(s->stream.next_in, SvPVX(buf), in, char) ; *SvEND(buf) = '\0'; SvSETMAGIC(buf); } @@ -1533,7 +1530,7 @@ inflateSync (s, buf) #endif /* initialise the input buffer */ - s->stream.next_in = (Bytef*)SvPVbyte_nolen(buf) ; + s->stream.next_in = (Bytef*)SvPV_nomg_nolen(buf) ; s->stream.avail_in = SvCUR(buf) ; /* inflateSync doesn't create any output */ @@ -1548,7 +1545,7 @@ inflateSync (s, buf) unsigned in = s->stream.avail_in ; SvCUR_set(buf, in) ; if (in) - Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ; + Move(s->stream.next_in, SvPVX(buf), in, char) ; *SvEND(buf) = '\0'; SvSETMAGIC(buf); } @@ -1694,7 +1691,6 @@ scan(s, buf, out=NULL, eof=FALSE) bool eof bool eof_mode = FALSE; int start_len = NO_INIT - STRLEN stmp = NO_INIT CODE: /* If the input buffer is a reference, dereference it */ #ifndef MAGIC_APPEND @@ -1707,7 +1703,7 @@ scan(s, buf, out=NULL, eof=FALSE) croak("Wide character in Compress::Raw::Zlib::InflateScan::scan input parameter"); #endif /* initialise the input buffer */ - s->stream.next_in = (Bytef*)SvPVbyte_force(buf, stmp) ; + s->stream.next_in = (Bytef*)SvPV_nomg_nolen(buf) ; s->stream.avail_in = SvCUR(buf) ; start_len = s->stream.avail_in ; s->bytesInflated = 0 ; @@ -1792,9 +1788,9 @@ scan(s, buf, out=NULL, eof=FALSE) unsigned in = s->stream.avail_in ; SvCUR_set(buf, in) ; if (in) - Move(s->stream.next_in, SvPVbyte_nolen(buf), in, char) ; - *SvEND(buf) = '\0'; - SvSETMAGIC(buf); + Move(s->stream.next_in, SvPVX(buf), in, char) ; + *SvEND(buf) = '\0'; + SvSETMAGIC(buf); } } #endif
Patch blocked until SvPV_nomg_nolen is added to Devel::PPPort. See ticket #78271 for the request to update Devel::PPPort. This is needed to allow the patch to work with Perl < 5.14
Version 2.058 uploaded to CPAN with this fix included. Paul