Skip Menu |

This queue is for tickets about the YAML-Syck CPAN distribution.

Report information
The Basics
Id: 34166
Status: rejected
Priority: 0/
Queue: YAML-Syck

People
Owner: Nobody in particular
Requestors: SREZIC [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.04
Fixed in: (no value)



Subject: Dump should reset hash iterators
It seems that YAML::Syck::Dump() does not reset hash iterators. The attached script generates the following output: 1.04 Before resetting %hash After resetting %hash c at /tmp/yml.pl line 17. a at /tmp/yml.pl line 17. b at /tmp/yml.pl line 17. This is somewhat confusing when using Data::Dumper on a hash which was dumped with YAML::Syck. Regards, Slaven
Subject: yml.pl
#!/usr/bin/perl use YAML::Syck qw(Dump); warn $YAML::Syck::VERSION, "\n"; %hash = qw(a a b b c c); Dump \%hash; warn "Before resetting \%hash\n"; while($key = each %hash) { warn $key; } keys %hash; warn "After resetting \%hash\n"; while($key = each %hash) { warn $key; } __END__
Le Lun. Mar. 17 14:28:52 2008, SREZIC a écrit : Show quoted text
> It seems that YAML::Syck::Dump() does not reset hash iterators.
I lost one day in deep debugging my Catalyst application before finding out that YAML::Syck::Dump was the culprit, and that the bug was already documented... So to here is a patch to fix this issue. Please consider including it in a next release. Best regards, Laurent Dami
diff -Naur YAML-Syck-1.07/Changes YAML-Syck-1.08/Changes --- YAML-Syck-1.07/Changes Sat Apr 25 05:39:18 2009 +++ YAML-Syck-1.08/Changes Sun May 3 08:28:05 2009 @@ -1,3 +1,6 @@ +* Dump() no longer leaves hash iterators in an improper state + Contributed by: Laurent Dami + [Changes for 1.07 (JSON::Syck 0.30) - 2009-04-25] * Added the missing Loadfile function to JSON::Syck. diff -Naur YAML-Syck-1.07/perl_syck.h YAML-Syck-1.08/perl_syck.h --- YAML-Syck-1.07/perl_syck.h Sun Jun 8 19:53:09 2008 +++ YAML-Syck-1.08/perl_syck.h Sun May 3 08:03:57 2009 @@ -703,19 +703,15 @@ break; } case SVt_PVHV: { - I32 len, i; -#ifdef HAS_RESTRICTED_HASHES - len = HvTOTALKEYS((HV*)sv); -#else - len = HvKEYS((HV*)sv); -#endif hv_iterinit((HV*)sv); - for (i = 0; i < len; i++) { + HE *he; + while (he = #ifdef HV_ITERNEXT_WANTPLACEHOLDERS - HE *he = hv_iternext_flags((HV*)sv, HV_ITERNEXT_WANTPLACEHOLDERS); + hv_iternext_flags((HV*)sv, HV_ITERNEXT_WANTPLACEHOLDERS) #else - HE *he = hv_iternext((HV*)sv); + hv_iternext((HV*)sv) #endif + ) { SV *val = hv_iterval((HV*)sv, he); PERL_SYCK_MARK_EMITTER( e, val ); } @@ -929,30 +925,27 @@ e->indent = PERL_SYCK_INDENT_LEVEL; *tag = '\0'; -#ifdef HAS_RESTRICTED_HASHES - len = HvTOTALKEYS((HV*)sv); -#else - len = HvKEYS((HV*)sv); -#endif hv_iterinit((HV*)sv); - if (e->sort_keys) { AV *av = (AV*)sv_2mortal((SV*)newAV()); - for (i = 0; i < len; i++) { + HE *he; + while (he = #ifdef HAS_RESTRICTED_HASHES - HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS); + hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS) #else - HE *he = hv_iternext(hv); + hv_iternext(hv) #endif + ) { SV *key = hv_iterkeysv(he); av_store(av, AvFILLp(av)+1, key); /* av_push(), really */ } - STORE_HASH_SORT; - for (i = 0; i < len; i++) { + STORE_HASH_SORT(av); + + SV *key; + while ((key = av_shift(av)) != &PL_sv_undef) { #ifdef HAS_RESTRICTED_HASHES int placeholders = (int)HvPLACEHOLDERS_get(hv); #endif - SV *key = av_shift(av); HE *he = hv_fetch_ent(hv, key, 0, 0); SV *val = HeVAL(he); if (val == NULL) { val = &PL_sv_undef; } @@ -961,12 +954,14 @@ } } else { - for (i = 0; i < len; i++) { + HE *he; + while (he = #ifdef HV_ITERNEXT_WANTPLACEHOLDERS - HE *he = hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS); + hv_iternext_flags(hv, HV_ITERNEXT_WANTPLACEHOLDERS) #else - HE *he = hv_iternext(hv); + hv_iternext(hv) #endif + ) { SV *key = hv_iterkeysv(he); SV *val = hv_iterval(hv, he); syck_emit_item( e, (st_data_t)key ); diff -Naur YAML-Syck-1.07/ppport_sort.h YAML-Syck-1.08/ppport_sort.h --- YAML-Syck-1.07/ppport_sort.h Sat Oct 20 10:47:56 2007 +++ YAML-Syck-1.08/ppport_sort.h Sun May 3 08:05:28 2009 @@ -6,25 +6,25 @@ #if defined(USE_ITHREADS) -#define STORE_HASH_SORT \ +#define STORE_HASH_SORT(arg) \ ENTER; { \ PerlInterpreter *orig_perl = PERL_GET_CONTEXT; \ SAVESPTR(orig_perl); \ PERL_SET_CONTEXT(aTHX); \ - qsort((char *) AvARRAY(av), len, sizeof(SV *), sortcmp); \ + qsort((char *) AvARRAY(arg), av_len(arg)+1, sizeof(SV *), sortcmp); \ } LEAVE; #else /* ! USE_ITHREADS */ -#define STORE_HASH_SORT \ - qsort((char *) AvARRAY(av), len, sizeof(SV *), sortcmp); +#define STORE_HASH_SORT(arg) \ + qsort((char *) AvARRAY(arg), av_len(arg)+1, sizeof(SV *), sortcmp); #endif /* USE_ITHREADS */ #else /* PATCHLEVEL > 6 */ -#define STORE_HASH_SORT \ - sortsv(AvARRAY(av), len, Perl_sv_cmp); +#define STORE_HASH_SORT(arg) \ + sortsv(AvARRAY(arg), av_len(arg)+1, Perl_sv_cmp); #endif /* PATCHLEVEL <= 6 */ diff -Naur YAML-Syck-1.07/t/5-iterhash.t YAML-Syck-1.08/t/5-iterhash.t --- YAML-Syck-1.07/t/5-iterhash.t Thu Jan 1 01:00:00 1970 +++ YAML-Syck-1.08/t/5-iterhash.t Sun May 3 06:14:03 2009 @@ -0,0 +1,24 @@ +use t::TestYAML tests => 3; + +my $hash = {foo => 1, subhash => {bar => 2, buz => 3, bobo => 4}}; + +is (Dump($hash), <<"", "dumped text"); +--- +foo: 1 +subhash: + bar: 2 + bobo: 4 + buz: 3 + + +my $count = 0; +while (my ($k, $v) = each %$hash) { + $count ++; +} +is ($count, 2, "iterator on main hash"); + +$count = 0; +while (my ($k, $v) = each %{$hash->{subhash}}) { + $count ++; +} +is ($count, 3, "iterator on subhash");
On Sun May 03 03:04:09 2009, DAMI wrote: Show quoted text
> Le Lun. Mar. 17 14:28:52 2008, SREZIC a écrit :
> > It seems that YAML::Syck::Dump() does not reset hash iterators.
> > I lost one day in deep debugging my Catalyst application before
finding Show quoted text
> out that YAML::Syck::Dump was the culprit, and that the bug was
already Show quoted text
> documented... > > So to here is a patch to fix this issue. Please consider including it
in Show quoted text
> a next release.
Hi, can you check if rocco's patch in #54167 also solves your issue, or does it just solve part of it? Anyway, have the form letter I'm pasting around now: (This is a form-reply that isn't specific to your particular report) YAML::Syck has just acquired one new maintainer (me), it still doesn't have anyone that *cares* about it. But I'm willing to help solve your report & release a new version with the fix if it's easy for me. It now has a Git repository at: http://github.com/avar/YAML-Syck If your report is a patch that fixes a problem, great. Please remake the patch against Git by forking that repo and sending me a pull request on GitHub (or an update to this bug if you prefer git-format-patch(1) or some other repo provider..). Make sure to include a test for what you fixed. If your report is some code that fails (and you have a testcase for it) a patch against the test suite to demonstrate that failure would be very useful. It's OK if the test crashes and burns, see Test::More's docs for how to make TODO tests that fail now, but shouldn't. Even if it segfaults perl C<system $^X => qw/ -Mblib -MYAML::Syck .../> or something like that and checking the return value will do.
On Thu May 20 07:15:54 2010, AVAR wrote: Show quoted text
> On Sun May 03 03:04:09 2009, DAMI wrote:
> > Le Lun. Mar. 17 14:28:52 2008, SREZIC a écrit :
> > > It seems that YAML::Syck::Dump() does not reset hash iterators.
> > > > I lost one day in deep debugging my Catalyst application before
> finding
> > out that YAML::Syck::Dump was the culprit, and that the bug was
> already
> > documented... > > > > So to here is a patch to fix this issue. Please consider including
it Show quoted text
> in
> > a next release.
> > Hi, can you check if rocco's patch in #54167 also solves your issue,
or Show quoted text
> does it just solve part of it?
Confirmed dupe of #54167