From 8a629ad6fba97a8a1fde77616d21ce53e2add4ca Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 15:48:28 +0900 Subject: [PATCH 01/15] Fix streaming unpacking for splitted packed data --- perl/t/10_splitted_bytes.t | 4 +-- perl/t/16_unpacker_for_larges.t | 22 ++++++++++++ perl/xs-src/unpack.c | 59 +++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 21 deletions(-) create mode 100644 perl/t/16_unpacker_for_larges.t diff --git a/perl/t/10_splitted_bytes.t b/perl/t/10_splitted_bytes.t index 15598f4..d94472d 100644 --- a/perl/t/10_splitted_bytes.t +++ b/perl/t/10_splitted_bytes.t @@ -20,8 +20,6 @@ my $input = [ my $packed = Data::MessagePack->pack($input); foreach my $size(1 .. 16) { - local $TODO = "Splitted byte streaming is not yet supported (bufer size: $size)"; - my $up = Data::MessagePack::Unpacker->new(); open my $stream, '<:bytes :scalar', \$packed; @@ -29,7 +27,7 @@ foreach my $size(1 .. 16) { my $buff; my $done = 0; while( read($stream, $buff, $size) ) { - #note "buff: ", join " ", map { unpack 'H2', $_ } split //, $buff; + note "buff: ", join " ", map { unpack 'H2', $_ } split //, $buff; $done = $up->execute($buff); } diff --git a/perl/t/16_unpacker_for_larges.t b/perl/t/16_unpacker_for_larges.t new file mode 100644 index 0000000..81e7c6a --- /dev/null +++ b/perl/t/16_unpacker_for_larges.t @@ -0,0 +1,22 @@ +use strict; +use Test::More; +use Data::MessagePack; + +foreach my $data("abc") { + my $packed = Data::MessagePack->pack($data); + + my $unpacker = Data::MessagePack::Unpacker->new; + note "buff: ", join " ", map { unpack 'H2', $_ } split //, $packed; + + my $offset = 0; + foreach my $byte(split //, $packed) { + note "offset: $offset"; + $offset += $unpacker->execute($byte); + } + + ok $unpacker->is_finished, 'finished'; + is_deeply $unpacker->data, $data, 'data'; +} + +done_testing; + diff --git a/perl/xs-src/unpack.c b/perl/xs-src/unpack.c index db7e394..e3f62c6 100644 --- a/perl/xs-src/unpack.c +++ b/perl/xs-src/unpack.c @@ -9,11 +9,13 @@ typedef struct { } my_cxt_t; START_MY_CXT +// context data for execute_template() typedef struct { bool finished; - bool incremented; bool utf8; + SV* buffer; } unpack_user; +#define UNPACK_USER_INIT { false, false, NULL } #include "msgpack/unpack_define.h" @@ -301,7 +303,7 @@ XS(xs_unpack) { msgpack_unpack_t mp; template_init(&mp); - unpack_user const u = {false, false, false}; + unpack_user const u = UNPACK_USER_INIT; mp.user = u; size_t from = 0; @@ -326,14 +328,6 @@ XS(xs_unpack) { /* ------------------------------ stream -- */ /* http://twitter.com/frsyuki/status/13249304748 */ -STATIC_INLINE void _reset(SV* const self) { - dTHX; - unpack_user const u = {false, false, false}; - - UNPACKER(self, mp); - template_init(mp); - mp->user = u; -} XS(xs_unpacker_new) { dXSARGS; @@ -345,9 +339,14 @@ XS(xs_unpacker_new) { msgpack_unpack_t *mp; Newxz(mp, 1, msgpack_unpack_t); + template_init(mp); + unpack_user const u = UNPACK_USER_INIT; + mp->user = u; + + mp->user.buffer = newSV(80); + sv_setpvs(mp->user.buffer, ""); sv_setref_pv(self, "Data::MessagePack::Unpacker", mp); - _reset(self); ST(0) = self; XSRETURN(1); @@ -378,21 +377,44 @@ _execute_impl(SV* const self, SV* const data, UV const offset, UV const limit) { dTHX; if(offset >= limit) { - Perl_croak(aTHX_ "offset (%"UVuf") is bigger than data buffer size (%"UVuf")", + Perl_croak(aTHX_ + "offset (%"UVuf") is bigger than data buffer size (%"UVuf")", offset, limit); } UNPACKER(self, mp); size_t from = offset; - const char* const dptr = SvPV_nolen_const(data); + const char* dptr = SvPV_nolen_const(data); + STRLEN dlen = limit; - int const ret = template_execute(mp, dptr, limit, &from); + if(SvCUR(mp->user.buffer) != 0) { + sv_catpvn(mp->user.buffer, dptr, dlen); + dptr = SvPV_const(mp->user.buffer, dlen); + from = 0; + } + + int const ret = template_execute(mp, dptr, dlen, &from); + // ret < 0 : error + // ret == 0 : insufficient + // ret > 0 : success if(ret < 0) { - Perl_croak(aTHX_ "Data::MessagePack::Unpacker: parse error while executing"); + Perl_croak(aTHX_ + "Data::MessagePack::Unpacker: parse error while executing"); } + mp->user.finished = (ret > 0) ? true : false; + if(!mp->user.finished) { + template_init(mp); // reset the state + sv_setpvn(mp->user.buffer, dptr, dlen); + from = 0; + } + else { + sv_setpvs(mp->user.buffer, ""); + } + //warn(">> (%d) dlen=%d, from=%d, rest=%d", + // (int)ret, (int)dlen, (int)from, dlen - from); return from; } @@ -464,12 +486,12 @@ XS(xs_unpacker_reset) { } UNPACKER(ST(0), mp); - bool const utf8 = mp->user.utf8; // save SV* const data = template_data(mp); SvREFCNT_dec(data); - _reset(ST(0)); - mp->user.utf8 = utf8; + + template_init(mp); + sv_setpvs(mp->user.buffer, ""); XSRETURN(0); } @@ -484,6 +506,7 @@ XS(xs_unpacker_destroy) { SV* const data = template_data(mp); SvREFCNT_dec(data); + SvREFCNT_dec(mp->user.buffer); Safefree(mp); XSRETURN(0); From 82d33944e6f0ee1f98791e41feb06d0d665abfb6 Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 16:08:20 +0900 Subject: [PATCH 02/15] perl: cleanup --- perl/xs-src/pack.c | 38 ++++++++++++++++++++------------- perl/xs-src/unpack.c | 51 +++++++++++++++++++++++++++++--------------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/perl/xs-src/pack.c b/perl/xs-src/pack.c index 862808e..fe646f1 100644 --- a/perl/xs-src/pack.c +++ b/perl/xs-src/pack.c @@ -47,7 +47,8 @@ STATIC_INLINE void need(enc_t* const enc, STRLEN const len); #define ERR_NESTING_EXCEEDED "perl structure exceeds maximum nesting level (max_depth set too low?)" -STATIC_INLINE void need(enc_t* const enc, STRLEN const len) +STATIC_INLINE +void need(enc_t* const enc, STRLEN const len) { if (enc->cur + len >= enc->end) { dTHX; @@ -61,7 +62,8 @@ STATIC_INLINE void need(enc_t* const enc, STRLEN const len) static int s_pref_int = 0; -STATIC_INLINE int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { +STATIC_INLINE +int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { if (SvTRUE(sv)) { s_pref_int = 1; } else { @@ -90,7 +92,8 @@ void init_Data__MessagePack_pack(pTHX_ bool const cloning) { } -STATIC_INLINE int try_int(enc_t* enc, const char *p, size_t len) { +STATIC_INLINE +int try_int(enc_t* enc, const char *p, size_t len) { int negative = 0; const char* pe = p + len; uint64_t num = 0; @@ -144,9 +147,11 @@ STATIC_INLINE int try_int(enc_t* enc, const char *p, size_t len) { } -STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); +STATIC_INLINE +void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); -STATIC_INLINE void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { +STATIC_INLINE +void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { dTHX; assert(sv); if (UNLIKELY(depth <= 0)) Perl_croak(aTHX_ ERR_NESTING_EXCEEDED); @@ -185,12 +190,13 @@ STATIC_INLINE void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const de } } -STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { - svtype svt; +STATIC_INLINE +void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { dTHX; + assert(sv); SvGETMAGIC(sv); - svt = SvTYPE(sv); + svtype const svt = SvTYPE(sv); if (SvOBJECT (sv)) { HV *stash = gv_stashpv ("Data::MessagePack::Boolean", 1); // TODO: cache? @@ -201,8 +207,8 @@ STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); } } else { - croak ("encountered object '%s', Data::MessagePack doesn't allow the object", - SvPV_nolen(sv_2mortal(newRV_inc(sv)))); + croak ("encountered object '%"SVf"', Data::MessagePack doesn't allow the object", + sv_2mortal(newRV_inc(sv))); } } else if (svt == SVt_PVHV) { HV* hval = (HV*)sv; @@ -238,12 +244,12 @@ STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); else { //sv_dump(sv); - croak("cannot encode reference to scalar '%s' unless the scalar is 0 or 1", - SvPV_nolen (sv_2mortal (newRV_inc (sv)))); + croak("cannot encode reference to scalar '%"SVf"' unless the scalar is 0 or 1", + sv_2mortal(newRV_inc(sv))); } } else { - croak ("encountered %s, but msgpack can only represent references to arrays or hashes", - SvPV_nolen (sv_2mortal (newRV_inc (sv)))); + croak ("encountered %"SVf", but msgpack can only represent references to arrays or hashes", + sv_2mortal(newRV_inc(sv))); } } @@ -266,8 +272,10 @@ XS(xs_pack) { _msgpack_pack_sv(&enc, val, depth); SvCUR_set(enc.sv, enc.cur - SvPVX (enc.sv)); - *SvEND (enc.sv) = 0; /* many xs functions expect a trailing 0 for text strings */ + /* many C functions expect a trailing NUL for strings */ + *SvEND(enc.sv) = '\0'; ST(0) = enc.sv; XSRETURN(1); } + diff --git a/perl/xs-src/unpack.c b/perl/xs-src/unpack.c index e3f62c6..2294446 100644 --- a/perl/xs-src/unpack.c +++ b/perl/xs-src/unpack.c @@ -101,21 +101,24 @@ static SV* template_data(msgpack_unpack_t* u); static int template_execute(msgpack_unpack_t* u PERL_UNUSED_DECL, const char* data, size_t len, size_t* off); -STATIC_INLINE SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) +STATIC_INLINE +SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) { return NULL; } #if IVSIZE == 4 -STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE +int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); return 0; } -STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) +STATIC_INLINE +int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) { dTHX; *o = newSViv(d); @@ -123,7 +126,8 @@ STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const } /* workaround win32 problems (my_snprintf(%llu) returns incorrect values ) */ -static char* str_from_uint64(char* buf_end, uint64_t v) +static +char* str_from_uint64(char* buf_end, uint64_t v) { char *p = buf_end; *--p = '\0'; @@ -133,7 +137,8 @@ static char* str_from_uint64(char* buf_end, uint64_t v) return p; } -static const char* str_from_int64(char* buf_end, int64_t const v) { +static +const char* str_from_int64(char* buf_end, int64_t const v) { bool const minus = v < 0; char* p = str_from_uint64(buf_end, minus ? -v : v); if (minus) @@ -141,7 +146,8 @@ static const char* str_from_int64(char* buf_end, int64_t const v) { return p; } -static int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) +static +int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -150,7 +156,8 @@ static int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t co return 0; } -static int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) +static +int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -162,7 +169,8 @@ static int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t cons #else /* IVSIZE == 8 */ -STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE +int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); @@ -192,7 +200,8 @@ STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const #define template_callback_float template_callback_double -STATIC_INLINE int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) +STATIC_INLINE +int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) { dTHX; *o = newSVnv(d); @@ -200,26 +209,30 @@ STATIC_INLINE int template_callback_double(unpack_user* u PERL_UNUSED_DECL, doub } /* &PL_sv_undef is not so good. see http://gist.github.com/387743 */ -STATIC_INLINE int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE +int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) { dTHX; *o = newSV(0); return 0; } -STATIC_INLINE int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE +int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(true); return 0; } -STATIC_INLINE int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE +int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(false); return 0; } -STATIC_INLINE int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE +int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; AV* const a = newAV(); @@ -228,7 +241,8 @@ STATIC_INLINE int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsig return 0; } -STATIC_INLINE int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) +STATIC_INLINE +int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) { dTHX; AV* const a = (AV*)SvRV(*c); @@ -237,7 +251,8 @@ STATIC_INLINE int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, return 0; } -STATIC_INLINE int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE +int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; HV* const h = newHV(); @@ -246,7 +261,8 @@ STATIC_INLINE int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigne return 0; } -STATIC_INLINE int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) +STATIC_INLINE +int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) { dTHX; HV* const h = (HV*)SvRV(*c); @@ -256,7 +272,8 @@ STATIC_INLINE int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV return 0; } -STATIC_INLINE int template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) +STATIC_INLINE int +template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) { dTHX; /* newSVpvn(p, l) returns an undef if p == NULL */ From a7a23d3bc8bb7a5c156becb3b8a43e296986f42e Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 16:16:12 +0900 Subject: [PATCH 03/15] Revert "perl: cleanup" This reverts commit 82d33944e6f0ee1f98791e41feb06d0d665abfb6. --- perl/xs-src/pack.c | 38 +++++++++++++-------------------- perl/xs-src/unpack.c | 51 +++++++++++++++----------------------------- 2 files changed, 32 insertions(+), 57 deletions(-) diff --git a/perl/xs-src/pack.c b/perl/xs-src/pack.c index fe646f1..862808e 100644 --- a/perl/xs-src/pack.c +++ b/perl/xs-src/pack.c @@ -47,8 +47,7 @@ STATIC_INLINE void need(enc_t* const enc, STRLEN const len); #define ERR_NESTING_EXCEEDED "perl structure exceeds maximum nesting level (max_depth set too low?)" -STATIC_INLINE -void need(enc_t* const enc, STRLEN const len) +STATIC_INLINE void need(enc_t* const enc, STRLEN const len) { if (enc->cur + len >= enc->end) { dTHX; @@ -62,8 +61,7 @@ void need(enc_t* const enc, STRLEN const len) static int s_pref_int = 0; -STATIC_INLINE -int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { +STATIC_INLINE int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { if (SvTRUE(sv)) { s_pref_int = 1; } else { @@ -92,8 +90,7 @@ void init_Data__MessagePack_pack(pTHX_ bool const cloning) { } -STATIC_INLINE -int try_int(enc_t* enc, const char *p, size_t len) { +STATIC_INLINE int try_int(enc_t* enc, const char *p, size_t len) { int negative = 0; const char* pe = p + len; uint64_t num = 0; @@ -147,11 +144,9 @@ int try_int(enc_t* enc, const char *p, size_t len) { } -STATIC_INLINE -void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); +STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); -STATIC_INLINE -void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { +STATIC_INLINE void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { dTHX; assert(sv); if (UNLIKELY(depth <= 0)) Perl_croak(aTHX_ ERR_NESTING_EXCEEDED); @@ -190,13 +185,12 @@ void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { } } -STATIC_INLINE -void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { +STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { + svtype svt; dTHX; - assert(sv); SvGETMAGIC(sv); - svtype const svt = SvTYPE(sv); + svt = SvTYPE(sv); if (SvOBJECT (sv)) { HV *stash = gv_stashpv ("Data::MessagePack::Boolean", 1); // TODO: cache? @@ -207,8 +201,8 @@ void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); } } else { - croak ("encountered object '%"SVf"', Data::MessagePack doesn't allow the object", - sv_2mortal(newRV_inc(sv))); + croak ("encountered object '%s', Data::MessagePack doesn't allow the object", + SvPV_nolen(sv_2mortal(newRV_inc(sv)))); } } else if (svt == SVt_PVHV) { HV* hval = (HV*)sv; @@ -244,12 +238,12 @@ void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); else { //sv_dump(sv); - croak("cannot encode reference to scalar '%"SVf"' unless the scalar is 0 or 1", - sv_2mortal(newRV_inc(sv))); + croak("cannot encode reference to scalar '%s' unless the scalar is 0 or 1", + SvPV_nolen (sv_2mortal (newRV_inc (sv)))); } } else { - croak ("encountered %"SVf", but msgpack can only represent references to arrays or hashes", - sv_2mortal(newRV_inc(sv))); + croak ("encountered %s, but msgpack can only represent references to arrays or hashes", + SvPV_nolen (sv_2mortal (newRV_inc (sv)))); } } @@ -272,10 +266,8 @@ XS(xs_pack) { _msgpack_pack_sv(&enc, val, depth); SvCUR_set(enc.sv, enc.cur - SvPVX (enc.sv)); - /* many C functions expect a trailing NUL for strings */ - *SvEND(enc.sv) = '\0'; + *SvEND (enc.sv) = 0; /* many xs functions expect a trailing 0 for text strings */ ST(0) = enc.sv; XSRETURN(1); } - diff --git a/perl/xs-src/unpack.c b/perl/xs-src/unpack.c index 2294446..e3f62c6 100644 --- a/perl/xs-src/unpack.c +++ b/perl/xs-src/unpack.c @@ -101,24 +101,21 @@ static SV* template_data(msgpack_unpack_t* u); static int template_execute(msgpack_unpack_t* u PERL_UNUSED_DECL, const char* data, size_t len, size_t* off); -STATIC_INLINE -SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) +STATIC_INLINE SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) { return NULL; } #if IVSIZE == 4 -STATIC_INLINE -int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); return 0; } -STATIC_INLINE -int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) +STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) { dTHX; *o = newSViv(d); @@ -126,8 +123,7 @@ int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) } /* workaround win32 problems (my_snprintf(%llu) returns incorrect values ) */ -static -char* str_from_uint64(char* buf_end, uint64_t v) +static char* str_from_uint64(char* buf_end, uint64_t v) { char *p = buf_end; *--p = '\0'; @@ -137,8 +133,7 @@ char* str_from_uint64(char* buf_end, uint64_t v) return p; } -static -const char* str_from_int64(char* buf_end, int64_t const v) { +static const char* str_from_int64(char* buf_end, int64_t const v) { bool const minus = v < 0; char* p = str_from_uint64(buf_end, minus ? -v : v); if (minus) @@ -146,8 +141,7 @@ const char* str_from_int64(char* buf_end, int64_t const v) { return p; } -static -int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) +static int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -156,8 +150,7 @@ int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, return 0; } -static -int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) +static int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -169,8 +162,7 @@ int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV #else /* IVSIZE == 8 */ -STATIC_INLINE -int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); @@ -200,8 +192,7 @@ STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const #define template_callback_float template_callback_double -STATIC_INLINE -int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) +STATIC_INLINE int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) { dTHX; *o = newSVnv(d); @@ -209,30 +200,26 @@ int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) } /* &PL_sv_undef is not so good. see http://gist.github.com/387743 */ -STATIC_INLINE -int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) { dTHX; *o = newSV(0); return 0; } -STATIC_INLINE -int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(true); return 0; } -STATIC_INLINE -int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(false); return 0; } -STATIC_INLINE -int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; AV* const a = newAV(); @@ -241,8 +228,7 @@ int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV* return 0; } -STATIC_INLINE -int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) +STATIC_INLINE int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) { dTHX; AV* const a = (AV*)SvRV(*c); @@ -251,8 +237,7 @@ int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) return 0; } -STATIC_INLINE -int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; HV* const h = newHV(); @@ -261,8 +246,7 @@ int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** return 0; } -STATIC_INLINE -int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) +STATIC_INLINE int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) { dTHX; HV* const h = (HV*)SvRV(*c); @@ -272,8 +256,7 @@ int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, S return 0; } -STATIC_INLINE int -template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) +STATIC_INLINE int template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) { dTHX; /* newSVpvn(p, l) returns an undef if p == NULL */ From bc8d8ab65a0f0cecfa5af03b4c3b39a13da22a7b Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 16:17:53 +0900 Subject: [PATCH 04/15] Revert "Revert "perl: cleanup"" This reverts commit a7a23d3bc8bb7a5c156becb3b8a43e296986f42e. --- perl/xs-src/pack.c | 38 ++++++++++++++++++++------------- perl/xs-src/unpack.c | 51 +++++++++++++++++++++++++++++--------------- 2 files changed, 57 insertions(+), 32 deletions(-) diff --git a/perl/xs-src/pack.c b/perl/xs-src/pack.c index 862808e..fe646f1 100644 --- a/perl/xs-src/pack.c +++ b/perl/xs-src/pack.c @@ -47,7 +47,8 @@ STATIC_INLINE void need(enc_t* const enc, STRLEN const len); #define ERR_NESTING_EXCEEDED "perl structure exceeds maximum nesting level (max_depth set too low?)" -STATIC_INLINE void need(enc_t* const enc, STRLEN const len) +STATIC_INLINE +void need(enc_t* const enc, STRLEN const len) { if (enc->cur + len >= enc->end) { dTHX; @@ -61,7 +62,8 @@ STATIC_INLINE void need(enc_t* const enc, STRLEN const len) static int s_pref_int = 0; -STATIC_INLINE int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { +STATIC_INLINE +int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { if (SvTRUE(sv)) { s_pref_int = 1; } else { @@ -90,7 +92,8 @@ void init_Data__MessagePack_pack(pTHX_ bool const cloning) { } -STATIC_INLINE int try_int(enc_t* enc, const char *p, size_t len) { +STATIC_INLINE +int try_int(enc_t* enc, const char *p, size_t len) { int negative = 0; const char* pe = p + len; uint64_t num = 0; @@ -144,9 +147,11 @@ STATIC_INLINE int try_int(enc_t* enc, const char *p, size_t len) { } -STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); +STATIC_INLINE +void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); -STATIC_INLINE void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { +STATIC_INLINE +void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { dTHX; assert(sv); if (UNLIKELY(depth <= 0)) Perl_croak(aTHX_ ERR_NESTING_EXCEEDED); @@ -185,12 +190,13 @@ STATIC_INLINE void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const de } } -STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { - svtype svt; +STATIC_INLINE +void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { dTHX; + assert(sv); SvGETMAGIC(sv); - svt = SvTYPE(sv); + svtype const svt = SvTYPE(sv); if (SvOBJECT (sv)) { HV *stash = gv_stashpv ("Data::MessagePack::Boolean", 1); // TODO: cache? @@ -201,8 +207,8 @@ STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); } } else { - croak ("encountered object '%s', Data::MessagePack doesn't allow the object", - SvPV_nolen(sv_2mortal(newRV_inc(sv)))); + croak ("encountered object '%"SVf"', Data::MessagePack doesn't allow the object", + sv_2mortal(newRV_inc(sv))); } } else if (svt == SVt_PVHV) { HV* hval = (HV*)sv; @@ -238,12 +244,12 @@ STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); else { //sv_dump(sv); - croak("cannot encode reference to scalar '%s' unless the scalar is 0 or 1", - SvPV_nolen (sv_2mortal (newRV_inc (sv)))); + croak("cannot encode reference to scalar '%"SVf"' unless the scalar is 0 or 1", + sv_2mortal(newRV_inc(sv))); } } else { - croak ("encountered %s, but msgpack can only represent references to arrays or hashes", - SvPV_nolen (sv_2mortal (newRV_inc (sv)))); + croak ("encountered %"SVf", but msgpack can only represent references to arrays or hashes", + sv_2mortal(newRV_inc(sv))); } } @@ -266,8 +272,10 @@ XS(xs_pack) { _msgpack_pack_sv(&enc, val, depth); SvCUR_set(enc.sv, enc.cur - SvPVX (enc.sv)); - *SvEND (enc.sv) = 0; /* many xs functions expect a trailing 0 for text strings */ + /* many C functions expect a trailing NUL for strings */ + *SvEND(enc.sv) = '\0'; ST(0) = enc.sv; XSRETURN(1); } + diff --git a/perl/xs-src/unpack.c b/perl/xs-src/unpack.c index e3f62c6..2294446 100644 --- a/perl/xs-src/unpack.c +++ b/perl/xs-src/unpack.c @@ -101,21 +101,24 @@ static SV* template_data(msgpack_unpack_t* u); static int template_execute(msgpack_unpack_t* u PERL_UNUSED_DECL, const char* data, size_t len, size_t* off); -STATIC_INLINE SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) +STATIC_INLINE +SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) { return NULL; } #if IVSIZE == 4 -STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE +int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); return 0; } -STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) +STATIC_INLINE +int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) { dTHX; *o = newSViv(d); @@ -123,7 +126,8 @@ STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const } /* workaround win32 problems (my_snprintf(%llu) returns incorrect values ) */ -static char* str_from_uint64(char* buf_end, uint64_t v) +static +char* str_from_uint64(char* buf_end, uint64_t v) { char *p = buf_end; *--p = '\0'; @@ -133,7 +137,8 @@ static char* str_from_uint64(char* buf_end, uint64_t v) return p; } -static const char* str_from_int64(char* buf_end, int64_t const v) { +static +const char* str_from_int64(char* buf_end, int64_t const v) { bool const minus = v < 0; char* p = str_from_uint64(buf_end, minus ? -v : v); if (minus) @@ -141,7 +146,8 @@ static const char* str_from_int64(char* buf_end, int64_t const v) { return p; } -static int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) +static +int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -150,7 +156,8 @@ static int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t co return 0; } -static int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) +static +int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -162,7 +169,8 @@ static int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t cons #else /* IVSIZE == 8 */ -STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE +int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); @@ -192,7 +200,8 @@ STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const #define template_callback_float template_callback_double -STATIC_INLINE int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) +STATIC_INLINE +int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) { dTHX; *o = newSVnv(d); @@ -200,26 +209,30 @@ STATIC_INLINE int template_callback_double(unpack_user* u PERL_UNUSED_DECL, doub } /* &PL_sv_undef is not so good. see http://gist.github.com/387743 */ -STATIC_INLINE int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE +int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) { dTHX; *o = newSV(0); return 0; } -STATIC_INLINE int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE +int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(true); return 0; } -STATIC_INLINE int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE +int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(false); return 0; } -STATIC_INLINE int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE +int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; AV* const a = newAV(); @@ -228,7 +241,8 @@ STATIC_INLINE int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsig return 0; } -STATIC_INLINE int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) +STATIC_INLINE +int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) { dTHX; AV* const a = (AV*)SvRV(*c); @@ -237,7 +251,8 @@ STATIC_INLINE int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, return 0; } -STATIC_INLINE int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE +int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; HV* const h = newHV(); @@ -246,7 +261,8 @@ STATIC_INLINE int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigne return 0; } -STATIC_INLINE int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) +STATIC_INLINE +int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) { dTHX; HV* const h = (HV*)SvRV(*c); @@ -256,7 +272,8 @@ STATIC_INLINE int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV return 0; } -STATIC_INLINE int template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) +STATIC_INLINE int +template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) { dTHX; /* newSVpvn(p, l) returns an undef if p == NULL */ From 86ccfcc03c4346a44d7d64b4269cba5488634aaa Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 16:25:19 +0900 Subject: [PATCH 05/15] perl: changelogging --- perl/Changes | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/perl/Changes b/perl/Changes index 486f1c3..d219b4a 100644 --- a/perl/Changes +++ b/perl/Changes @@ -1,3 +1,8 @@ +0.35 + + - address issue/20 (cho45): Data::MessagePack did not finish correctly + when was given devided packed data + 0.34 - do not use the corrupt my_snprintf(%ll[du]) on win32(kazuho) From fedc37d079bade6135cbeac7f3b157dfcabe8093 Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 16:31:19 +0900 Subject: [PATCH 06/15] Revert "perl: cleanup" This reverts commit bc8d8ab65a0f0cecfa5af03b4c3b39a13da22a7b. --- perl/xs-src/pack.c | 38 +++++++++++++-------------------- perl/xs-src/unpack.c | 51 +++++++++++++++----------------------------- 2 files changed, 32 insertions(+), 57 deletions(-) diff --git a/perl/xs-src/pack.c b/perl/xs-src/pack.c index fe646f1..862808e 100644 --- a/perl/xs-src/pack.c +++ b/perl/xs-src/pack.c @@ -47,8 +47,7 @@ STATIC_INLINE void need(enc_t* const enc, STRLEN const len); #define ERR_NESTING_EXCEEDED "perl structure exceeds maximum nesting level (max_depth set too low?)" -STATIC_INLINE -void need(enc_t* const enc, STRLEN const len) +STATIC_INLINE void need(enc_t* const enc, STRLEN const len) { if (enc->cur + len >= enc->end) { dTHX; @@ -62,8 +61,7 @@ void need(enc_t* const enc, STRLEN const len) static int s_pref_int = 0; -STATIC_INLINE -int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { +STATIC_INLINE int pref_int_set(pTHX_ SV* sv, MAGIC* mg PERL_UNUSED_DECL) { if (SvTRUE(sv)) { s_pref_int = 1; } else { @@ -92,8 +90,7 @@ void init_Data__MessagePack_pack(pTHX_ bool const cloning) { } -STATIC_INLINE -int try_int(enc_t* enc, const char *p, size_t len) { +STATIC_INLINE int try_int(enc_t* enc, const char *p, size_t len) { int negative = 0; const char* pe = p + len; uint64_t num = 0; @@ -147,11 +144,9 @@ int try_int(enc_t* enc, const char *p, size_t len) { } -STATIC_INLINE -void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); +STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth); -STATIC_INLINE -void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { +STATIC_INLINE void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { dTHX; assert(sv); if (UNLIKELY(depth <= 0)) Perl_croak(aTHX_ ERR_NESTING_EXCEEDED); @@ -190,13 +185,12 @@ void _msgpack_pack_sv(enc_t* const enc, SV* const sv, int const depth) { } } -STATIC_INLINE -void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { +STATIC_INLINE void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { + svtype svt; dTHX; - assert(sv); SvGETMAGIC(sv); - svtype const svt = SvTYPE(sv); + svt = SvTYPE(sv); if (SvOBJECT (sv)) { HV *stash = gv_stashpv ("Data::MessagePack::Boolean", 1); // TODO: cache? @@ -207,8 +201,8 @@ void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); } } else { - croak ("encountered object '%"SVf"', Data::MessagePack doesn't allow the object", - sv_2mortal(newRV_inc(sv))); + croak ("encountered object '%s', Data::MessagePack doesn't allow the object", + SvPV_nolen(sv_2mortal(newRV_inc(sv)))); } } else if (svt == SVt_PVHV) { HV* hval = (HV*)sv; @@ -244,12 +238,12 @@ void _msgpack_pack_rv(enc_t *enc, SV* sv, int depth) { msgpack_pack_false(enc); else { //sv_dump(sv); - croak("cannot encode reference to scalar '%"SVf"' unless the scalar is 0 or 1", - sv_2mortal(newRV_inc(sv))); + croak("cannot encode reference to scalar '%s' unless the scalar is 0 or 1", + SvPV_nolen (sv_2mortal (newRV_inc (sv)))); } } else { - croak ("encountered %"SVf", but msgpack can only represent references to arrays or hashes", - sv_2mortal(newRV_inc(sv))); + croak ("encountered %s, but msgpack can only represent references to arrays or hashes", + SvPV_nolen (sv_2mortal (newRV_inc (sv)))); } } @@ -272,10 +266,8 @@ XS(xs_pack) { _msgpack_pack_sv(&enc, val, depth); SvCUR_set(enc.sv, enc.cur - SvPVX (enc.sv)); - /* many C functions expect a trailing NUL for strings */ - *SvEND(enc.sv) = '\0'; + *SvEND (enc.sv) = 0; /* many xs functions expect a trailing 0 for text strings */ ST(0) = enc.sv; XSRETURN(1); } - diff --git a/perl/xs-src/unpack.c b/perl/xs-src/unpack.c index 2294446..e3f62c6 100644 --- a/perl/xs-src/unpack.c +++ b/perl/xs-src/unpack.c @@ -101,24 +101,21 @@ static SV* template_data(msgpack_unpack_t* u); static int template_execute(msgpack_unpack_t* u PERL_UNUSED_DECL, const char* data, size_t len, size_t* off); -STATIC_INLINE -SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) +STATIC_INLINE SV* template_callback_root(unpack_user* u PERL_UNUSED_DECL) { return NULL; } #if IVSIZE == 4 -STATIC_INLINE -int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); return 0; } -STATIC_INLINE -int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) +STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) { dTHX; *o = newSViv(d); @@ -126,8 +123,7 @@ int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const d, SV** o) } /* workaround win32 problems (my_snprintf(%llu) returns incorrect values ) */ -static -char* str_from_uint64(char* buf_end, uint64_t v) +static char* str_from_uint64(char* buf_end, uint64_t v) { char *p = buf_end; *--p = '\0'; @@ -137,8 +133,7 @@ char* str_from_uint64(char* buf_end, uint64_t v) return p; } -static -const char* str_from_int64(char* buf_end, int64_t const v) { +static const char* str_from_int64(char* buf_end, int64_t const v) { bool const minus = v < 0; char* p = str_from_uint64(buf_end, minus ? -v : v); if (minus) @@ -146,8 +141,7 @@ const char* str_from_int64(char* buf_end, int64_t const v) { return p; } -static -int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) +static int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -156,8 +150,7 @@ int template_callback_uint64(unpack_user* u PERL_UNUSED_DECL, uint64_t const d, return 0; } -static -int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) +static int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV** o) { dTHX; char tbuf[64]; @@ -169,8 +162,7 @@ int template_callback_int64(unpack_user* u PERL_UNUSED_DECL, int64_t const d, SV #else /* IVSIZE == 8 */ -STATIC_INLINE -int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) +STATIC_INLINE int template_callback_UV(unpack_user* u PERL_UNUSED_DECL, UV const d, SV** o) { dTHX; *o = newSVuv(d); @@ -200,8 +192,7 @@ STATIC_INLINE int template_callback_IV(unpack_user* u PERL_UNUSED_DECL, IV const #define template_callback_float template_callback_double -STATIC_INLINE -int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) +STATIC_INLINE int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) { dTHX; *o = newSVnv(d); @@ -209,30 +200,26 @@ int template_callback_double(unpack_user* u PERL_UNUSED_DECL, double d, SV** o) } /* &PL_sv_undef is not so good. see http://gist.github.com/387743 */ -STATIC_INLINE -int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE int template_callback_nil(unpack_user* u PERL_UNUSED_DECL, SV** o) { dTHX; *o = newSV(0); return 0; } -STATIC_INLINE -int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE int template_callback_true(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(true); return 0; } -STATIC_INLINE -int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) +STATIC_INLINE int template_callback_false(unpack_user* u PERL_UNUSED_DECL, SV** o) { *o = get_bool(false); return 0; } -STATIC_INLINE -int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; AV* const a = newAV(); @@ -241,8 +228,7 @@ int template_callback_array(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV* return 0; } -STATIC_INLINE -int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) +STATIC_INLINE int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) { dTHX; AV* const a = (AV*)SvRV(*c); @@ -251,8 +237,7 @@ int template_callback_array_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* o) return 0; } -STATIC_INLINE -int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) +STATIC_INLINE int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** o) { dTHX; HV* const h = newHV(); @@ -261,8 +246,7 @@ int template_callback_map(unpack_user* u PERL_UNUSED_DECL, unsigned int n, SV** return 0; } -STATIC_INLINE -int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) +STATIC_INLINE int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, SV* v) { dTHX; HV* const h = (HV*)SvRV(*c); @@ -272,8 +256,7 @@ int template_callback_map_item(unpack_user* u PERL_UNUSED_DECL, SV** c, SV* k, S return 0; } -STATIC_INLINE int -template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) +STATIC_INLINE int template_callback_raw(unpack_user* u PERL_UNUSED_DECL, const char* b PERL_UNUSED_DECL, const char* p, unsigned int l, SV** o) { dTHX; /* newSVpvn(p, l) returns an undef if p == NULL */ From ea36ef310783b502af7125848ab9679a8fb3b293 Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 17:05:41 +0900 Subject: [PATCH 07/15] perl: tests --- perl/t/16_unpacker_for_larges.t | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/perl/t/16_unpacker_for_larges.t b/perl/t/16_unpacker_for_larges.t index 81e7c6a..8d0b5d7 100644 --- a/perl/t/16_unpacker_for_larges.t +++ b/perl/t/16_unpacker_for_larges.t @@ -2,16 +2,14 @@ use strict; use Test::More; use Data::MessagePack; -foreach my $data("abc") { +foreach my $data("abc", [42]) { my $packed = Data::MessagePack->pack($data); my $unpacker = Data::MessagePack::Unpacker->new; note "buff: ", join " ", map { unpack 'H2', $_ } split //, $packed; - my $offset = 0; foreach my $byte(split //, $packed) { - note "offset: $offset"; - $offset += $unpacker->execute($byte); + $unpacker->execute($byte); } ok $unpacker->is_finished, 'finished'; From c320e44a236762d73677bbf5780f8c3a42fd98ff Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Thu, 28 Oct 2010 17:26:04 +0900 Subject: [PATCH 08/15] perl: update Unpacker.pod --- perl/lib/Data/MessagePack/Unpacker.pod | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/perl/lib/Data/MessagePack/Unpacker.pod b/perl/lib/Data/MessagePack/Unpacker.pod index 24dafd0..04cb0a4 100644 --- a/perl/lib/Data/MessagePack/Unpacker.pod +++ b/perl/lib/Data/MessagePack/Unpacker.pod @@ -6,11 +6,16 @@ Data::MessagePack::Unpacker - messagepack streaming deserializer use Data::Dumper; my $up = Data::MessagePack::Unpacker->new; - my $ret = $up->execute($v, 0); - if ($ret != length($v)) { - fail "extra bytes"; + + open my $fh, $data or die $!; + + my $offset = 0; + while( read($fh, my $buf, 1024) ) { + $offset = $up->execute($buf, $offset); + if($up->is_finished) { + print Dumper($up->data); + } } - return Dumper($up->data); =head1 DESCRIPTION @@ -22,7 +27,7 @@ This is a streaming deserializer for messagepack. =item my $up = Data::MessagePack::Unpacker->new() -creates a new instance of stream deserializer. +creates a new instance of the stream deserializer. =item $up->utf8([$bool]) @@ -37,14 +42,15 @@ The utf8 mode is disabled by default. returns the utf8 mode flag of I<$up>. -=item my $ret = $up->execute($data, $offset); +=item $offset = $up->execute($data, $offset); -=item my $ret = $up->execute_limit($data, $offset, $limit) +=item $offset = $up->execute_limit($data, $offset, $limit) - $up->execute(substr($data, 0, 3), 0); - $up->execute($data, 3); +parses unpacked I<$data> from I<$offset> to I<$limit>. +returns a new offset of I<$data>, which is for the next . -$offset is the offset of $data. +If I<$data> is insufficient, I<$offset> does not change, saving +I<$data> in internal buffers. =item my $bool = $up->is_finished(); From f1c294ca5012329c3d550d7b32a34a5d8039de7c Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Sat, 30 Oct 2010 00:28:53 +0900 Subject: [PATCH 09/15] perl: make error messages compatible with XS --- perl/lib/Data/MessagePack/PP.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm index 5e64093..8d148d2 100644 --- a/perl/lib/Data/MessagePack/PP.pm +++ b/perl/lib/Data/MessagePack/PP.pm @@ -305,10 +305,10 @@ foreach my $pair( sub _unpack { my ( $value ) = @_; # get a header byte - my $byte = unpack "x$p C", $value; # "x$p" is faster than substr() + defined(my $byte = unpack "x$p C", $value) + or Carp::confess("Data::MessagePack->unpack: insufficient bytes"); $p++; - Carp::croak("invalid data") unless defined $byte; # +/- fixnum, nil, true, false return $byte2value[$byte] if $typemap[$byte] & $T_DIRECT; From 6a9cb5182882076429e2c6ed22ccaa6bfda94022 Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Sat, 30 Oct 2010 00:31:41 +0900 Subject: [PATCH 10/15] perl: modify internal names for the next refactoring --- perl/lib/Data/MessagePack/PP.pm | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm index 8d148d2..8daf248 100644 --- a/perl/lib/Data/MessagePack/PP.pm +++ b/perl/lib/Data/MessagePack/PP.pm @@ -423,7 +423,11 @@ package Data::MessagePack::PP::Unpacker; sub new { - bless { pos => 0, utf8 => 0 }, shift; + bless { + pos => 0, + utf8 => 0, + buff => '', + }, shift; } sub utf8 { @@ -447,13 +451,13 @@ sub execute { my $value = substr( $data, $offset, $limit ? $limit : length $data ); my $len = length $value; - $self->{data} .= $value; + $self->{buff} .= $value; local $self->{stack} = []; $p = 0; - while ( length($self->{data}) > $p ) { - _count( $self, $self->{data} ) or last; + while ( length($self->{buff}) > $p ) { + _count( $self, $self->{buff} ) or last; while ( @{ $self->{stack} } > 0 && --$self->{stack}->[-1] == 0) { pop @{ $self->{stack} }; @@ -568,7 +572,7 @@ sub _count { sub data { my($self) = @_; local $Data::MessagePack::PP::_utf8 = $self->{utf8}; - return Data::MessagePack->unpack( substr($self->{ data }, 0, $self->{pos}) ); + return Data::MessagePack->unpack( substr($self->{buff}, 0, $self->{pos}) ); } @@ -578,9 +582,9 @@ sub is_finished { } sub reset :method { - $_[0]->{ data } = undef; - $_[0]->{ pos } = 0; - $_[0]->{ is_finished } = 0; + $_[0]->{buff} = ''; + $_[0]->{pos} = 0; + $_[0]->{is_finished} = 0; } 1; From 5de2b974fb1709ee776a49ce4cecbddd6f54893b Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Sat, 30 Oct 2010 00:42:00 +0900 Subject: [PATCH 11/15] perl: ord(substr(...)) *is* faster than unpack() --- perl/lib/Data/MessagePack/PP.pm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm index 8daf248..0c19cb1 100644 --- a/perl/lib/Data/MessagePack/PP.pm +++ b/perl/lib/Data/MessagePack/PP.pm @@ -304,12 +304,12 @@ foreach my $pair( sub _unpack { my ( $value ) = @_; - # get a header byte - defined(my $byte = unpack "x$p C", $value) + $p < length($value) or Carp::confess("Data::MessagePack->unpack: insufficient bytes"); + # get a header byte + my $byte = ord( substr $value, $p, 1 ); $p++; - # +/- fixnum, nil, true, false return $byte2value[$byte] if $typemap[$byte] & $T_DIRECT; @@ -454,6 +454,9 @@ sub execute { $self->{buff} .= $value; local $self->{stack} = []; + #$p = 0; + #eval { Data::MessagePack::PP::_unpack($self->{buff}) }; + #warn "[$p][$@]"; $p = 0; while ( length($self->{buff}) > $p ) { From 3f16f080aca89758f8d8e4cc5c6000718598ce4f Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Sat, 30 Oct 2010 01:09:12 +0900 Subject: [PATCH 12/15] perl: add failing tests for PP --- perl/t/16_unpacker_for_larges.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/perl/t/16_unpacker_for_larges.t b/perl/t/16_unpacker_for_larges.t index 8d0b5d7..26894a2 100644 --- a/perl/t/16_unpacker_for_larges.t +++ b/perl/t/16_unpacker_for_larges.t @@ -2,7 +2,7 @@ use strict; use Test::More; use Data::MessagePack; -foreach my $data("abc", [42]) { +foreach my $data("abc", [ 'x' x 1024 ], [0xFFFF42]) { my $packed = Data::MessagePack->pack($data); my $unpacker = Data::MessagePack::Unpacker->new; From eac0f838645f4f1bedf0a66c92cd19339a5490b8 Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Sat, 30 Oct 2010 12:38:32 +0900 Subject: [PATCH 13/15] perl: check data strictly; which is slow, but required --- perl/lib/Data/MessagePack/PP.pm | 89 +++++++++++++++++---------------- perl/t/02_unpack.t | 5 +- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm index 0c19cb1..fca73b8 100644 --- a/perl/lib/Data/MessagePack/PP.pm +++ b/perl/lib/Data/MessagePack/PP.pm @@ -138,6 +138,7 @@ sub _unexpected { Carp::confess("Unexpected " . sprintf(shift, @_) . " found"); } + # # PACK # @@ -257,6 +258,10 @@ sub _pack { our $_utf8 = 0; my $p; # position variables for speed. +sub _insufficient { + Carp::confess("Insufficient bytes (pos=$p, type=@_)"); +} + sub unpack :method { $p = 0; # init my $data = _unpack( $_[1] ); @@ -302,10 +307,26 @@ foreach my $pair( $byte2value[ $pair->[0] ] = $pair->[1]; } +sub _fetch_size { + my($value_ref, $byte, $x16, $x32, $x_fixbits) = @_; + if ( $byte == $x16 ) { + $p += 2; + $p <= length(${$value_ref}) or _insufficient('x/16'); + return unpack 'n', substr( ${$value_ref}, $p - 2, 2 ); + } + elsif ( $byte == $x32 ) { + $p += 4; + $p <= length(${$value_ref}) or _insufficient('x/32'); + return unpack 'N', substr( ${$value_ref}, $p - 4, 4 ); + } + else { # fix raw + return $byte & ~$x_fixbits; + } +} + sub _unpack { my ( $value ) = @_; - $p < length($value) - or Carp::confess("Data::MessagePack->unpack: insufficient bytes"); + $p < length($value) or _insufficient('header byte'); # get a header byte my $byte = ord( substr $value, $p, 1 ); $p++; @@ -314,55 +335,23 @@ sub _unpack { return $byte2value[$byte] if $typemap[$byte] & $T_DIRECT; if ( $typemap[$byte] & $T_RAW ) { - my $num; - if ( $byte == 0xda ) { - $num = CORE::unpack 'n', substr( $value, $p, 2 ); - $p += 2 + $num; - } - elsif ( $byte == 0xdb ) { - $num = CORE::unpack 'N', substr( $value, $p, 4 ); - $p += 4 + $num; - } - else { # fix raw - $num = $byte & ~0xa0; - $p += $num; - } - my $s = substr( $value, $p - $num, $num ); + my $size = _fetch_size(\$value, $byte, 0xda, 0xdb, 0xa0); + my $s = substr( $value, $p, $size ); + length($s) == $size or _insufficient('raw'); + $p += $size; utf8::decode($s) if $_utf8; return $s; } elsif ( $typemap[$byte] & $T_ARRAY ) { - my $num; - if ( $byte == 0xdc ) { # array 16 - $num = CORE::unpack 'n', substr( $value, $p, 2 ); - $p += 2; - } - elsif ( $byte == 0xdd ) { # array 32 - $num = CORE::unpack 'N', substr( $value, $p, 4 ); - $p += 4; - } - else { # fix array - $num = $byte & ~0x90; - } + my $size = _fetch_size(\$value, $byte, 0xdc, 0xdd, 0x90); my @array; - push @array, _unpack( $value ) while --$num >= 0; + push @array, _unpack( $value ) while --$size >= 0; return \@array; } elsif ( $typemap[$byte] & $T_MAP ) { - my $num; - if ( $byte == 0xde ) { # map 16 - $num = CORE::unpack 'n', substr( $value, $p, 2 ); - $p += 2; - } - elsif ( $byte == 0xdf ) { # map 32 - $num = CORE::unpack 'N', substr( $value, $p, 4 ); - $p += 4; - } - else { # fix map - $num = $byte & ~0x80; - } + my $size = _fetch_size(\$value, $byte, 0xde, 0xdf, 0x80); my %map; - while ( --$num >= 0 ) { + while(--$size >= 0) { no warnings; # for undef key case my $key = _unpack( $value ); my $val = _unpack( $value ); @@ -372,41 +361,53 @@ sub _unpack { } elsif ( $byte == 0xcc ) { # uint8 - return CORE::unpack( 'C', substr( $value, $p++, 1 ) ); + $p++; + $p <= length($value) or _insufficient('uint8'); + return CORE::unpack( 'C', substr( $value, $p - 1, 1 ) ); } elsif ( $byte == 0xcd ) { # uint16 $p += 2; + $p <= length($value) or _insufficient('uint16'); return unpack_uint16( $value, $p - 2 ); } elsif ( $byte == 0xce ) { # unit32 $p += 4; + $p <= length($value) or _insufficient('uint32'); return unpack_uint32( $value, $p - 4 ); } elsif ( $byte == 0xcf ) { # unit64 $p += 8; + $p <= length($value) or _insufficient('uint64'); return unpack_uint64( $value, $p - 8 ); } elsif ( $byte == 0xd3 ) { # int64 $p += 8; + $p <= length($value) or _insufficient('int64'); return unpack_int64( $value, $p - 8 ); } elsif ( $byte == 0xd2 ) { # int32 $p += 4; + $p <= length($value) or _insufficient('int32'); return unpack_int32( $value, $p - 4 ); } elsif ( $byte == 0xd1 ) { # int16 $p += 2; + $p <= length($value) or _insufficient('int16'); return unpack_int16( $value, $p - 2 ); } elsif ( $byte == 0xd0 ) { # int8 - return CORE::unpack 'c', substr( $value, $p++, 1 ); # c / C + $p++; + $p <= length($value) or _insufficient('int8'); + return CORE::unpack 'c', substr( $value, $p - 1, 1 ); } elsif ( $byte == 0xcb ) { # double $p += 8; + $p <= length($value) or _insufficient('double'); return unpack_double( $value, $p - 8 ); } elsif ( $byte == 0xca ) { # float $p += 4; + $p <= length($value) or _insufficient('float'); return unpack_float( $value, $p - 4 ); } else { diff --git a/perl/t/02_unpack.t b/perl/t/02_unpack.t index 1087c40..9e471d1 100644 --- a/perl/t/02_unpack.t +++ b/perl/t/02_unpack.t @@ -12,7 +12,10 @@ sub unpackit { sub pis ($$) { is_deeply unpackit($_[0]), $_[1], 'dump ' . $_[0] - or diag( explain(unpackit($_[0])) ); + or do { + diag( 'got:', explain(unpackit($_[0])) ); + diag( 'expected:', explain($_[1]) ); + }; } my @dat = do 't/data.pl' or die $@; From b4ae6bf82c8bcd6012c805a2206fcb81ad39dd0b Mon Sep 17 00:00:00 2001 From: "Fuji, Goro" Date: Sat, 30 Oct 2010 13:04:30 +0900 Subject: [PATCH 14/15] perl: disable warnings --- perl/lib/Data/MessagePack/PP.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/perl/lib/Data/MessagePack/PP.pm b/perl/lib/Data/MessagePack/PP.pm index fca73b8..f179ad7 100644 --- a/perl/lib/Data/MessagePack/PP.pm +++ b/perl/lib/Data/MessagePack/PP.pm @@ -480,6 +480,7 @@ sub execute { sub _count { my ( $self, $value ) = @_; + no warnings; # FIXME my $byte = unpack( 'C', substr( $value, $p++, 1 ) ); # get header Carp::croak('invalid data') unless defined $byte; From bad69fd3977fca94d643a88d819badaca4839fd5 Mon Sep 17 00:00:00 2001 From: advect Date: Sat, 30 Oct 2010 16:06:50 +0900 Subject: [PATCH 15/15] php: fiexed unpacker --- php/ChangeLog | 4 + php/msgpack.c | 2 +- php/msgpack_class.c | 35 ++- php/package.xml | 62 ++--- php/php-msgpack.spec | 1 - php/php_msgpack.h | 2 +- php/tests/009.phpt | 28 +-- php/tests/009b.phpt | 28 ++- php/tests/024.phpt | 11 +- php/tests/024b.phpt | 11 +- php/tests/026.phpt | 52 +---- php/tests/026b.phpt | 52 ++++- php/tests/028.phpt | 544 ++----------------------------------------- php/tests/028b.phpt | 544 +++++++++++++++++++++++++++++++++++++++++-- php/tests/042.phpt | 2 +- php/tests/060.phpt | 12 +- php/tests/060b.phpt | 12 +- php/tests/061.phpt | 12 +- php/tests/061b.phpt | 12 +- php/tests/064.phpt | 315 +++++++++++++++++++++++++ php/tests/064b.phpt | 321 +++++++++++++++++++++++++ php/tests/065.phpt | 320 +++++++++++++++++++++++++ php/tests/065b.phpt | 326 ++++++++++++++++++++++++++ php/tests/066.phpt | 70 ++++++ php/tests/067.phpt | 74 ++++++ php/tests/070.phpt | 12 +- php/tests/070b.phpt | 12 +- php/tests/071.phpt | 12 +- php/tests/071b.phpt | 12 +- php/tests/072.phpt | 12 +- php/tests/072b.phpt | 12 +- php/tests/073.phpt | 12 +- php/tests/073b.phpt | 12 +- 33 files changed, 2206 insertions(+), 742 deletions(-) create mode 100644 php/tests/064.phpt create mode 100644 php/tests/064b.phpt create mode 100644 php/tests/065.phpt create mode 100644 php/tests/065b.phpt create mode 100644 php/tests/066.phpt create mode 100644 php/tests/067.phpt diff --git a/php/ChangeLog b/php/ChangeLog index 3cee3b6..3eb64e7 100644 --- a/php/ChangeLog +++ b/php/ChangeLog @@ -1,5 +1,9 @@ msgpack extension changelog +Version 0.3.1 +------------- + * Fix class MessagePackUnpacker. + Version 0.3.0 ------------- * Change msgpack_unpack.c (used template) diff --git a/php/msgpack.c b/php/msgpack.c index 5d4f926..3b375ba 100644 --- a/php/msgpack.c +++ b/php/msgpack.c @@ -113,7 +113,7 @@ zend_module_entry msgpack_module_entry = { NULL, ZEND_MINFO(msgpack), #if ZEND_MODULE_API_NO >= 20010901 - MSGPACK_VERSION, + MSGPACK_EXTENSION_VERSION, #endif STANDARD_MODULE_PROPERTIES }; diff --git a/php/msgpack_class.c b/php/msgpack_class.c index 5cfff8d..ce008d9 100644 --- a/php/msgpack_class.c +++ b/php/msgpack_class.c @@ -19,6 +19,7 @@ typedef struct { msgpack_unpack_t mp; php_unserialize_data_t var_hash; long php_only; + zend_bool finished; } php_msgpack_unpacker_t; #if ZEND_MODULE_API_NO >= 20060613 @@ -348,6 +349,7 @@ static ZEND_METHOD(msgpack_unpacker, __construct) unpacker->buffer.a = 0; unpacker->retval = NULL; unpacker->offset = 0; + unpacker->finished = 0; template_init(&unpacker->mp); @@ -460,6 +462,22 @@ static ZEND_METHOD(msgpack_unpacker, execute) { ALLOC_INIT_ZVAL(unpacker->retval); } + else if (unpacker->finished) + { + zval_ptr_dtor(&unpacker->retval); + + msgpack_unserialize_var_destroy(&unpacker->var_hash); + + + ALLOC_INIT_ZVAL(unpacker->retval); + + template_init(&unpacker->mp); + + msgpack_unserialize_var_init(&unpacker->var_hash); + + (&unpacker->mp)->user.var_hash = + (php_unserialize_data_t *)&unpacker->var_hash; + } (&unpacker->mp)->user.retval = (zval *)unpacker->retval; MSGPACK_G(error_display) = 0; @@ -483,6 +501,7 @@ static ZEND_METHOD(msgpack_unpacker, execute) { case MSGPACK_UNPACK_EXTRA_BYTES: case MSGPACK_UNPACK_SUCCESS: + unpacker->finished = 1; RETURN_TRUE; default: RETURN_FALSE; @@ -493,7 +512,16 @@ static ZEND_METHOD(msgpack_unpacker, data) { MSGPACK_UNPACKER_OBJECT; - RETURN_ZVAL(unpacker->retval, 1, 1); + if (unpacker->retval != NULL) + { + ZVAL_ZVAL(return_value, unpacker->retval, 1, 0); + + MSGPACK_METHOD(msgpack_unpacker, reset, NULL, getThis()); + + return; + } + + RETURN_FALSE; } static ZEND_METHOD(msgpack_unpacker, reset) @@ -513,6 +541,7 @@ static ZEND_METHOD(msgpack_unpacker, reset) unpacker->buffer.len = 0; unpacker->buffer.a = 0; unpacker->offset = 0; + unpacker->finished = 0; if (buffer.len > 0) { @@ -530,12 +559,12 @@ static ZEND_METHOD(msgpack_unpacker, reset) msgpack_unserialize_var_destroy(&unpacker->var_hash); + template_init(&unpacker->mp); + msgpack_unserialize_var_init(&unpacker->var_hash); (&unpacker->mp)->user.var_hash = (php_unserialize_data_t *)&unpacker->var_hash; - - msgpack_unserialize_init(&((&unpacker->mp)->user)); } void msgpack_init_class() diff --git a/php/package.xml b/php/package.xml index 6172a4c..803aa97 100644 --- a/php/package.xml +++ b/php/package.xml @@ -10,11 +10,11 @@ advect@gmail.com yes - 2010-09-28 - + 2010-10-26 + - 0.3.0 - 0.3.0 + 0.3.1 + 0.3.1 beta @@ -27,14 +27,14 @@ - - + + - + @@ -49,8 +49,8 @@ - - + + @@ -65,14 +65,14 @@ - - + + - - + + - - + + @@ -82,22 +82,28 @@ - + - - - - + + + + - - - - - - - - + + + + + + + + + + + + + + diff --git a/php/php-msgpack.spec b/php/php-msgpack.spec index 6a98288..7609ca4 100644 --- a/php/php-msgpack.spec +++ b/php/php-msgpack.spec @@ -12,7 +12,6 @@ Packager: advect Provides: php-pecl-msgpack BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRequires: php-devel -Requires: msgpack %if 0%{?php_zend_api} Requires: php(zend-abi) = %{php_zend_api} Requires: php(api) = %{php_core_api} diff --git a/php/php_msgpack.h b/php/php_msgpack.h index 61badea..0791deb 100644 --- a/php/php_msgpack.h +++ b/php/php_msgpack.h @@ -2,7 +2,7 @@ #ifndef PHP_MSGPACK_H #define PHP_MSGPACK_H -#define MSGPACK_EXTENSION_VERSION "0.3.0" +#define MSGPACK_EXTENSION_VERSION "0.3.1" #include "ext/standard/php_smart_str.h" diff --git a/php/tests/009.phpt b/php/tests/009.phpt index 9992988..a1534c9 100644 --- a/php/tests/009.phpt +++ b/php/tests/009.phpt @@ -2,8 +2,8 @@ Check for reference serialization --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } @@ -91,13 +85,7 @@ array(1) { [0]=> &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } @@ -107,13 +95,7 @@ array(1) { [0]=> &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/009b.phpt b/php/tests/009b.phpt index 7765d62..10e7259 100644 --- a/php/tests/009b.phpt +++ b/php/tests/009b.phpt @@ -2,8 +2,8 @@ Check for reference serialization --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } @@ -85,7 +91,13 @@ array(1) { [0]=> &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } @@ -95,7 +107,13 @@ array(1) { [0]=> &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } diff --git a/php/tests/024.phpt b/php/tests/024.phpt index 9b185f7..97db2a7 100644 --- a/php/tests/024.phpt +++ b/php/tests/024.phpt @@ -2,8 +2,8 @@ Recursive objects --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- int(100) [%r"?obj"?:("Obj4":)?private"?%r]=> - object(Obj4)#%d (2) { - [%r"?a"?:("Obj4":)?private"?%r]=> - int(100) - [%r"?obj"?:("Obj4":)?private"?%r]=> - *RECURSION* - } + *RECURSION* } OK diff --git a/php/tests/024b.phpt b/php/tests/024b.phpt index 7c691be..c7612d7 100644 --- a/php/tests/024b.phpt +++ b/php/tests/024b.phpt @@ -2,8 +2,8 @@ Recursive objects --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- int(100) [%r"?obj"?:("Obj4":)?private"?%r]=> - *RECURSION* + object(Obj4)#%d (2) { + [%r"?a"?:("Obj4":)?private"?%r]=> + int(100) + [%r"?obj"?:("Obj4":)?private"?%r]=> + *RECURSION* + } } OK diff --git a/php/tests/026.phpt b/php/tests/026.phpt index c243ef5..383289d 100644 --- a/php/tests/026.phpt +++ b/php/tests/026.phpt @@ -3,8 +3,8 @@ Cyclic array test --INI-- --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- - &array(2) { - ["a"]=> - array(2) { - ["b"]=> - string(1) "c" - ["d"]=> - string(1) "e" - } - ["f"]=> - *RECURSION* - } + *RECURSION* } } OK @@ -84,17 +74,7 @@ array(1) { [1]=> int(2) [2]=> - array(1) { - ["foo"]=> - &array(3) { - [0]=> - int(1) - [1]=> - int(2) - [2]=> - *RECURSION* - } - } + *RECURSION* } } array(1) { @@ -107,17 +87,7 @@ array(1) { [2]=> array(1) { ["foo"]=> - &array(3) { - [0]=> - int(1) - [1]=> - int(2) - [2]=> - array(1) { - ["foo"]=> - *RECURSION* - } - } + *RECURSION* } } } @@ -131,17 +101,7 @@ array(1) { [2]=> array(1) { ["foo"]=> - &array(3) { - [0]=> - int(1) - [1]=> - string(1) "b" - [2]=> - array(1) { - ["foo"]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/026b.phpt b/php/tests/026b.phpt index f7a3381..9eef7cb 100644 --- a/php/tests/026b.phpt +++ b/php/tests/026b.phpt @@ -3,8 +3,8 @@ Cyclic array test --INI-- --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- - *RECURSION* + &array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + *RECURSION* + } } } OK @@ -74,7 +84,17 @@ array(1) { [1]=> int(2) [2]=> - *RECURSION* + array(1) { + ["foo"]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + *RECURSION* + } + } } } array(1) { @@ -87,7 +107,17 @@ array(1) { [2]=> array(1) { ["foo"]=> - *RECURSION* + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } } } } @@ -101,7 +131,17 @@ array(1) { [2]=> array(1) { ["foo"]=> - *RECURSION* + &array(3) { + [0]=> + int(1) + [1]=> + string(1) "b" + [2]=> + array(1) { + ["foo"]=> + *RECURSION* + } + } } } } diff --git a/php/tests/028.phpt b/php/tests/028.phpt index 00db675..1d326ce 100644 --- a/php/tests/028.phpt +++ b/php/tests/028.phpt @@ -2,8 +2,8 @@ Serialize object into session, full set --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- object(Bar)#4 (3) { ["d1"]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* [%r"?d3"?:protected"?%r]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* } [%r"?d2"?:protected"?%r]=> object(Bar)#4 (3) { ["d1"]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* [%r"?d3"?:protected"?%r]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* } ["d3"]=> object(Bar)#4 (3) { ["d1"]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* [%r"?d3"?:protected"?%r]=> - object(Foo)#3 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - [%r"?d2"?:protected"?%r]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - ["d3"]=> - object(Bar)#4 (3) { - ["d1"]=> - *RECURSION* - [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* - [%r"?d3"?:protected"?%r]=> - *RECURSION* - } - } + *RECURSION* } } ["test"]=> @@ -391,281 +139,29 @@ array(3) { ["d1"]=> object(Foo)#6 (3) { [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* [%r"?d2"?:protected"?%r]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* ["d3"]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* } [%r"?d2"?:("Bar":)?private"?%r]=> object(Foo)#6 (3) { [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* [%r"?d2"?:protected"?%r]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* ["d3"]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* } [%r"?d3"?:protected"?%r]=> object(Foo)#6 (3) { [%r"?d1"?:("Foo":)?private"?%r]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* [%r"?d2"?:protected"?%r]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* ["d3"]=> - object(Bar)#5 (3) { - ["d1"]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d2"?:("Bar":)?private"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - [%r"?d3"?:protected"?%r]=> - object(Foo)#6 (3) { - [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* - [%r"?d2"?:protected"?%r]=> - *RECURSION* - ["d3"]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/028b.phpt b/php/tests/028b.phpt index 7331a57..0efba18 100644 --- a/php/tests/028b.phpt +++ b/php/tests/028b.phpt @@ -2,8 +2,8 @@ Serialize object into session, full set --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- object(Bar)#4 (3) { ["d1"]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } [%r"?d3"?:protected"?%r]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } } [%r"?d2"?:protected"?%r]=> object(Bar)#4 (3) { ["d1"]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } [%r"?d3"?:protected"?%r]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } } ["d3"]=> object(Bar)#4 (3) { ["d1"]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } [%r"?d2"?:("Bar":)?private"?%r]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } [%r"?d3"?:protected"?%r]=> - *RECURSION* + object(Foo)#3 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + [%r"?d2"?:protected"?%r]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + ["d3"]=> + object(Bar)#4 (3) { + ["d1"]=> + *RECURSION* + [%r"?d2"?:("Bar":)?private"?%r]=> + *RECURSION* + [%r"?d3"?:protected"?%r]=> + *RECURSION* + } + } } } ["test"]=> @@ -139,29 +391,281 @@ array(3) { ["d1"]=> object(Foo)#6 (3) { [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } [%r"?d2"?:protected"?%r]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } ["d3"]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } } [%r"?d2"?:("Bar":)?private"?%r]=> object(Foo)#6 (3) { [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } [%r"?d2"?:protected"?%r]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } ["d3"]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } } [%r"?d3"?:protected"?%r]=> object(Foo)#6 (3) { [%r"?d1"?:("Foo":)?private"?%r]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } [%r"?d2"?:protected"?%r]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } ["d3"]=> - *RECURSION* + object(Bar)#5 (3) { + ["d1"]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d2"?:("Bar":)?private"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + [%r"?d3"?:protected"?%r]=> + object(Foo)#6 (3) { + [%r"?d1"?:("Foo":)?private"?%r]=> + *RECURSION* + [%r"?d2"?:protected"?%r]=> + *RECURSION* + ["d3"]=> + *RECURSION* + } + } } } } diff --git a/php/tests/042.phpt b/php/tests/042.phpt index 2ba73ac..83e8bc7 100644 --- a/php/tests/042.phpt +++ b/php/tests/042.phpt @@ -3,7 +3,7 @@ Closure --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/060b.phpt b/php/tests/060b.phpt index 0b947c8..a2e50bc 100644 --- a/php/tests/060b.phpt +++ b/php/tests/060b.phpt @@ -2,8 +2,8 @@ Check for buffered streaming unserialization --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } diff --git a/php/tests/061.phpt b/php/tests/061.phpt index 7ecc0c9..2b42d31 100644 --- a/php/tests/061.phpt +++ b/php/tests/061.phpt @@ -2,8 +2,8 @@ Check for unbuffered streaming unserialization --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/061b.phpt b/php/tests/061b.phpt index efb3a9b..21706db 100644 --- a/php/tests/061b.phpt +++ b/php/tests/061b.phpt @@ -2,8 +2,8 @@ Check for unbuffered streaming unserialization --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } diff --git a/php/tests/064.phpt b/php/tests/064.phpt new file mode 100644 index 0000000..a7a2f3b --- /dev/null +++ b/php/tests/064.phpt @@ -0,0 +1,315 @@ +--TEST-- +Check for buffered streaming unserialization (single) +--SKIPIF-- +feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('bool: true', true); +test('bool: false', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('array', array(), false); +test('array(1, 2, 3)', array(1, 2, 3), false); +test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/064b.phpt b/php/tests/064b.phpt new file mode 100644 index 0000000..aba7a2d --- /dev/null +++ b/php/tests/064b.phpt @@ -0,0 +1,321 @@ +--TEST-- +Check for buffered streaming unserialization (single) +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 or older"; +} +--FILE-- +feed($str); + if ($unpacker->execute()) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('bool: true', true); +test('bool: false', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('array', array(), false); +test('array(1, 2, 3)', array(1, 2, 3), false); +test('array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/065.phpt b/php/tests/065.phpt new file mode 100644 index 0000000..c37ca12 --- /dev/null +++ b/php/tests/065.phpt @@ -0,0 +1,320 @@ +--TEST-- +Check for unbuffered streaming unserialization (single) +--SKIPIF-- +execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/065b.phpt b/php/tests/065b.phpt new file mode 100644 index 0000000..c623d9a --- /dev/null +++ b/php/tests/065b.phpt @@ -0,0 +1,326 @@ +--TEST-- +Check for unbuffered streaming unserialization (single) +--SKIPIF-- += 0) { + echo "skip tests in PHP 5.3.2 or older"; +} +--FILE-- +execute($str, $offset)) + { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = ""; + $offset = 0; + } + + $i += $len; + } + + if (!is_bool($test)) + { + echo $unserialized === $variable ? 'OK' : 'ERROR', PHP_EOL; + } + else + { + echo $test || $unserialized == $variable ? 'OK' : 'ERROR', PHP_EOL; + } +} + +test('null', null); + +test('boo:l true', true); +test('bool: true', false); + +test('zero: 0', 0); +test('small: 1', 1); +test('small: -1', -1); +test('medium: 1000', 1000); +test('medium: -1000', -1000); +test('large: 100000', 100000); +test('large: -100000', -100000); + +test('double: 123.456', 123.456); + +test('empty: ""', ""); +test('string: "foobar"', "foobar"); + +test('empty: array', array(), false); +test('empty: array(1, 2, 3)', array(1, 2, 3), false); +test('empty: array(array(1, 2, 3), arr...', array(array(1, 2, 3), array(4, 5, 6), array(7, 8, 9)), false); + +test('array("foo", "foo", "foo")', array("foo", "foo", "foo"), false); +test('array("one" => 1, "two" => 2))', array("one" => 1, "two" => 2), false); +test('array("kek" => "lol", "lol" => "kek")', array("kek" => "lol", "lol" => "kek"), false); +test('array("" => "empty")', array("" => "empty"), false); + +$a = array('foo'); +test('array($a, $a)', array($a, $a), false); +test('array(&$a, &$a)', array(&$a, &$a), false); + +$a = array(null); +$b = array(&$a); +$a[0] = &$b; + +test('cyclic', $a, true); + +$a = array( + 'a' => array( + 'b' => 'c', + 'd' => 'e' + ), + 'f' => array( + 'g' => 'h' + ) + ); + +test('array', $a, false); + +class Obj { + public $a; + protected $b; + private $c; + + function __construct($a, $b, $c) { + $this->a = $a; + $this->b = $b; + $this->c = $c; + } +} + +test('object', new Obj(1, 2, 3), false); + +test('object', array(new Obj(1, 2, 3), new Obj(4, 5, 6)), false); + +$o = new Obj(1, 2, 3); + +test('object', array(&$o, &$o), false); +--EXPECTF-- +NULL +OK +bool(true) +OK +bool(false) +OK +int(0) +OK +int(1) +OK +int(-1) +OK +int(1000) +OK +int(-1000) +OK +int(100000) +OK +int(-100000) +OK +float(123.456) +OK +string(0) "" +OK +string(6) "foobar" +OK +array(0) { +} +OK +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +OK +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } +} +OK +array(3) { + [0]=> + string(3) "foo" + [1]=> + string(3) "foo" + [2]=> + string(3) "foo" +} +OK +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +OK +array(2) { + ["kek"]=> + string(3) "lol" + ["lol"]=> + string(3) "kek" +} +OK +array(1) { + [""]=> + string(5) "empty" +} +OK +array(2) { + [0]=> + array(1) { + [0]=> + string(3) "foo" + } + [1]=> + array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(2) { + [0]=> + &array(1) { + [0]=> + string(3) "foo" + } + [1]=> + &array(1) { + [0]=> + string(3) "foo" + } +} +OK +array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } + } + } +} +OK +array(2) { + ["a"]=> + array(2) { + ["b"]=> + string(1) "c" + ["d"]=> + string(1) "e" + } + ["f"]=> + array(1) { + ["g"]=> + string(1) "h" + } +} +OK +object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) +} +OK +array(2) { + [0]=> + object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + object(Obj)#%d (3) { + ["a"]=> + int(4) + [%r"?b"?:protected"?%r]=> + int(5) + [%r"?c"?:("Obj":)?private"?%r]=> + int(6) + } +} +OK +array(2) { + [0]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } + [1]=> + &object(Obj)#%d (3) { + ["a"]=> + int(1) + [%r"?b"?:protected"?%r]=> + int(2) + [%r"?c"?:("Obj":)?private"?%r]=> + int(3) + } +} +OK diff --git a/php/tests/066.phpt b/php/tests/066.phpt new file mode 100644 index 0000000..d2e430d --- /dev/null +++ b/php/tests/066.phpt @@ -0,0 +1,70 @@ +--TEST-- +Extra bytes buffered streaming unserialization (single) +--SKIPIF-- +--FILE-- +feed($str); + + while (true) { + if ($unpacker->execute()) { + $unserialized = $unpacker->data(); + var_dump($unserialized); + $unpacker->reset(); + } else { + break; + } + } + $i += $len; + } + } +} + +test('array(1, 2, 3)', array('9301020392')); +test('array(1, 2, 3), array(3, 9), 4', array('9301020392', '030904')); +--EXPECTF-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(9) + } +} +int(4) diff --git a/php/tests/067.phpt b/php/tests/067.phpt new file mode 100644 index 0000000..96c1442 --- /dev/null +++ b/php/tests/067.phpt @@ -0,0 +1,74 @@ +--TEST-- +Extra bytes unbuffered streaming unserialization (single) +--SKIPIF-- +--FILE-- +execute($str, $offset)) { + $unserialized = $unpacker->data(); + var_dump($unserialized); + + $unpacker->reset(); + $str = substr($str, $offset); + $offset = 0; + } else { + break; + } + } + $i += $len; + } + } +} + +test('array(1, 2, 3)', array('9301020392')); +test('array(1, 2, 3), array(3, 9), 4', array('9301020392', '030904')); +--EXPECTF-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(9) + } +} +int(4) diff --git a/php/tests/070.phpt b/php/tests/070.phpt index 893023b..affcc72 100644 --- a/php/tests/070.phpt +++ b/php/tests/070.phpt @@ -2,8 +2,8 @@ Check for alias functions --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/070b.phpt b/php/tests/070b.phpt index 109ddc1..0aaa4e7 100644 --- a/php/tests/070b.phpt +++ b/php/tests/070b.phpt @@ -2,8 +2,8 @@ Check for alias functions --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } diff --git a/php/tests/071.phpt b/php/tests/071.phpt index 431303b..20041d4 100644 --- a/php/tests/071.phpt +++ b/php/tests/071.phpt @@ -2,8 +2,8 @@ Check for class methods --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/071b.phpt b/php/tests/071b.phpt index 770d06e..f663073 100644 --- a/php/tests/071b.phpt +++ b/php/tests/071b.phpt @@ -2,8 +2,8 @@ Check for class methods --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } diff --git a/php/tests/072.phpt b/php/tests/072.phpt index ea79a56..0f89e0a 100644 --- a/php/tests/072.phpt +++ b/php/tests/072.phpt @@ -2,8 +2,8 @@ Check for class methods unpacker --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/072b.phpt b/php/tests/072b.phpt index c7b0c3c..05fe41e 100644 --- a/php/tests/072b.phpt +++ b/php/tests/072b.phpt @@ -2,8 +2,8 @@ Check for class methods unpacker --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } } diff --git a/php/tests/073.phpt b/php/tests/073.phpt index d3a7637..f6a91a6 100644 --- a/php/tests/073.phpt +++ b/php/tests/073.phpt @@ -2,8 +2,8 @@ Check for class unpacker --SKIPIF-- = 0) { - echo "skip tests in PHP 5.3.2 and lower"; +if (version_compare(PHP_VERSION, '5.3.2') <= 0) { + echo "skip tests in PHP 5.3.3 or newer"; } --FILE-- &array(1) { [0]=> - &array(1) { - [0]=> - &array(1) { - [0]=> - *RECURSION* - } - } + *RECURSION* } } } diff --git a/php/tests/073b.phpt b/php/tests/073b.phpt index 131a534..065a2aa 100644 --- a/php/tests/073b.phpt +++ b/php/tests/073b.phpt @@ -2,8 +2,8 @@ Check for class unpacker --SKIPIF-- = 0) { + echo "skip tests in PHP 5.3.2 or older"; } --FILE-- &array(1) { [0]=> - *RECURSION* + &array(1) { + [0]=> + &array(1) { + [0]=> + *RECURSION* + } + } } } }