-
Notifications
You must be signed in to change notification settings - Fork 578
EXTEND changes visible size of file and array. [rt.cpan.org #39196] #17496
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'm transferring this issue to https://github.com/Perl/perl5 since it is issue with a module in dist. |
The bug is still present in 5.30.1. It can be demonstrated with the following program:
Results:
See perlmonks 710580 for good analysis by @ikegami. Thank you very much. |
On Thu, 30 Jan 2020, 05:46 James E Keenan, ***@***.***> wrote:
The bug is still present in 5.30.1. It can be demonstrated with the
following program:
$ cat perlmonks-710580-tie-file.pl
#!/usr/bin/env perl
use 5.14.0;
use warnings;
use Data::Dumper; $Data::Dumper::Indent=1;
use Carp;
use Tie::File;
my $g = 'tiefile';
unlink $g if -f $g;
tie my @tied_array, 'Tie::File', $g or die "Could not tie to $g: $!";
***@***.***_array, $_) for (1..3);
print ***@***.***_array has " . scalar @tied_array . " elements before sorting\n";
@tied_array = sort {uc($a) cmp uc($b)} @tied_array;
print ***@***.***_array has " . scalar @tied_array . " elements after sorting\n";
say Dumper ***@***.***_array);
untie @tied_array;
Results:
$ perl perlmonks-710580-tie-file.pl
@tied_array has 3 elements before sorting
@tied_array has 4 elements after sorting
$VAR1 = [
'1',
'2',
'3',
''
];
See perlmonks 710580 <http://www.perlmonks.org/?node_id=710580> for good
analysis by @ikegami <https://github.com/ikegami>
Imo this is a bug in perl not in Tie::File.
I can imagine why the sort code might want to extend the array, but the
fact that it breaks tie modules shows it's not correct to do so.
Yves
… |
It doesn't break tie modules in general. The linked post above shows that
the bug is to specific to Tie::File by demonstrating that Tie::StdArray is
not affected.
(I didn't analyze the problem de novo since I'm on my phone.)
On Wed., Jan. 29, 2020, 8:26 p.m. Yves Orton, <[email protected]>
wrote:
… On Thu, 30 Jan 2020, 05:46 James E Keenan, ***@***.***>
wrote:
> The bug is still present in 5.30.1. It can be demonstrated with the
> following program:
>
> $ cat perlmonks-710580-tie-file.pl
> #!/usr/bin/env perl
> use 5.14.0;
> use warnings;
> use Data::Dumper; $Data::Dumper::Indent=1;
> use Carp;
> use Tie::File;
>
> my $g = 'tiefile';
> unlink $g if -f $g;
>
> tie my @tied_array, 'Tie::File', $g or die "Could not tie to $g: $!";
>
> ***@***.***_array, $_) for (1..3);
>
> print ***@***.***_array has " . scalar @tied_array . " elements before
sorting\n";
> @tied_array = sort {uc($a) cmp uc($b)} @tied_array;
>
> print ***@***.***_array has " . scalar @tied_array . " elements after
sorting\n";
> say Dumper ***@***.***_array);
> untie @tied_array;
>
> Results:
>
> $ perl perlmonks-710580-tie-file.pl
> @tied_array has 3 elements before sorting
> @tied_array has 4 elements after sorting
> $VAR1 = [
> '1',
> '2',
> '3',
> ''
> ];
>
> See perlmonks 710580 <http://www.perlmonks.org/?node_id=710580> for good
> analysis by @ikegami <https://github.com/ikegami>
>
Imo this is a bug in perl not in Tie::File.
I can imagine why the sort code might want to extend the array, but the
fact that it breaks tie modules shows it's not correct to do so.
Yves
>
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#17496?email_source=notifications&email_token=AAFK2ZJ7A263WJSHBA3GLLTRAIUFRA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKJL27Y#issuecomment-580042111>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAFK2ZI4AVXSFOFBP4DJQLDRAIUFRANCNFSM4KL355LA>
.
|
I don't think that really settles this.
EXTEND implies in memory semantics where the size of the allocated buffer
differs from what is visible to the user of the array.
A tie to some kind of external store, like Tie::File, cannot support this
distinction. Whatever is allocated is necessarily "visible".
So arguably calling EXTEND as part of sort() is a bug. I imagine it is
done to provide oinline space for swaps (but I havent checked), but this
means it expects to be able to store into an element that has not been
properly made part of the array which seems pretty dodgy to me. If after
the sort it "de-extended" the array then it might be ok, but then Tie::File
wouldn't be broken either.
So imo this is a perl bug as we are subtly assuming the array
implementation is capable of over allocating invisible elements of the
array which are usable but not visible which imo is not possible with any
"hard storage" type Tie.
Yves
…On Thu, 30 Jan 2020, 11:19 Eric Brine, ***@***.***> wrote:
It doesn't break tie modules in general. The linked post above shows that
the bug is to specific to Tie::File by demonstrating that Tie::StdArray is
not affected.
(I didn't analyze the problem de novo since I'm on my phone.)
On Wed., Jan. 29, 2020, 8:26 p.m. Yves Orton, ***@***.***>
wrote:
> On Thu, 30 Jan 2020, 05:46 James E Keenan, ***@***.***>
> wrote:
>
> > The bug is still present in 5.30.1. It can be demonstrated with the
> > following program:
> >
> > $ cat perlmonks-710580-tie-file.pl
> > #!/usr/bin/env perl
> > use 5.14.0;
> > use warnings;
> > use Data::Dumper; $Data::Dumper::Indent=1;
> > use Carp;
> > use Tie::File;
> >
> > my $g = 'tiefile';
> > unlink $g if -f $g;
> >
> > tie my @tied_array, 'Tie::File', $g or die "Could not tie to $g: $!";
> >
> > ***@***.***_array, $_) for (1..3);
> >
> > print ***@***.***_array has " . scalar @tied_array . " elements before
> sorting\n";
> > @tied_array = sort {uc($a) cmp uc($b)} @tied_array;
> >
> > print ***@***.***_array has " . scalar @tied_array . " elements after
> sorting\n";
> > say Dumper ***@***.***_array);
> > untie @tied_array;
> >
> > Results:
> >
> > $ perl perlmonks-710580-tie-file.pl
> > @tied_array has 3 elements before sorting
> > @tied_array has 4 elements after sorting
> > $VAR1 = [
> > '1',
> > '2',
> > '3',
> > ''
> > ];
> >
> > See perlmonks 710580 <http://www.perlmonks.org/?node_id=710580> for
good
> > analysis by @ikegami <https://github.com/ikegami>
> >
>
> Imo this is a bug in perl not in Tie::File.
>
> I can imagine why the sort code might want to extend the array, but the
> fact that it breaks tie modules shows it's not correct to do so.
>
> Yves
>
> >
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <
#17496?email_source=notifications&email_token=AAFK2ZJ7A263WJSHBA3GLLTRAIUFRA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKJL27Y#issuecomment-580042111
>,
> or unsubscribe
> <
https://github.com/notifications/unsubscribe-auth/AAFK2ZI4AVXSFOFBP4DJQLDRAIUFRANCNFSM4KL355LA
>
> .
>
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#17496?email_source=notifications&email_token=AAAZ5R5YDLT4QONZULIQMMLRAJBNBA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKJRTLI#issuecomment-580065709>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAZ5RZPNCF3DGQ7776QHHDRAJBNBANCNFSM4KL355LA>
.
|
To add to this, imo any tied array should function perfectly fine if EXTEND
is a noop. EXTEND is essentially an optimization that says "preallocate
space efficiently in a chunk so that later I can efficiently allocate in
piecemeal fashion without a penalty each time". If sort breaks or accesses
an element outside of the actually allocated space because it has called
EXTEND then it is making unwarranted assumptions about the internal
implementation of the array.
Yves
…On Thu, 30 Jan 2020, 11:33 demerphq, ***@***.***> wrote:
I don't think that really settles this.
EXTEND implies in memory semantics where the size of the allocated buffer
differs from what is visible to the user of the array.
A tie to some kind of external store, like Tie::File, cannot support this
distinction. Whatever is allocated is necessarily "visible".
So arguably calling EXTEND as part of sort() is a bug. I imagine it is
done to provide oinline space for swaps (but I havent checked), but this
means it expects to be able to store into an element that has not been
properly made part of the array which seems pretty dodgy to me. If after
the sort it "de-extended" the array then it might be ok, but then Tie::File
wouldn't be broken either.
So imo this is a perl bug as we are subtly assuming the array
implementation is capable of over allocating invisible elements of the
array which are usable but not visible which imo is not possible with any
"hard storage" type Tie.
Yves
On Thu, 30 Jan 2020, 11:19 Eric Brine, ***@***.***> wrote:
> It doesn't break tie modules in general. The linked post above shows that
> the bug is to specific to Tie::File by demonstrating that Tie::StdArray is
> not affected.
>
> (I didn't analyze the problem de novo since I'm on my phone.)
>
> On Wed., Jan. 29, 2020, 8:26 p.m. Yves Orton, ***@***.***>
> wrote:
>
> > On Thu, 30 Jan 2020, 05:46 James E Keenan, ***@***.***>
> > wrote:
> >
> > > The bug is still present in 5.30.1. It can be demonstrated with the
> > > following program:
> > >
> > > $ cat perlmonks-710580-tie-file.pl
> > > #!/usr/bin/env perl
> > > use 5.14.0;
> > > use warnings;
> > > use Data::Dumper; $Data::Dumper::Indent=1;
> > > use Carp;
> > > use Tie::File;
> > >
> > > my $g = 'tiefile';
> > > unlink $g if -f $g;
> > >
> > > tie my @tied_array, 'Tie::File', $g or die "Could not tie to $g: $!";
> > >
> > > ***@***.***_array, $_) for (1..3);
> > >
> > > print ***@***.***_array has " . scalar @tied_array . " elements before
> > sorting\n";
> > > @tied_array = sort {uc($a) cmp uc($b)} @tied_array;
> > >
> > > print ***@***.***_array has " . scalar @tied_array . " elements after
> > sorting\n";
> > > say Dumper ***@***.***_array);
> > > untie @tied_array;
> > >
> > > Results:
> > >
> > > $ perl perlmonks-710580-tie-file.pl
> > > @tied_array has 3 elements before sorting
> > > @tied_array has 4 elements after sorting
> > > $VAR1 = [
> > > '1',
> > > '2',
> > > '3',
> > > ''
> > > ];
> > >
> > > See perlmonks 710580 <http://www.perlmonks.org/?node_id=710580> for
> good
> > > analysis by @ikegami <https://github.com/ikegami>
> > >
> >
> > Imo this is a bug in perl not in Tie::File.
> >
> > I can imagine why the sort code might want to extend the array, but the
> > fact that it breaks tie modules shows it's not correct to do so.
> >
> > Yves
> >
> > >
> >
> > —
> > You are receiving this because you were mentioned.
> > Reply to this email directly, view it on GitHub
> > <
> #17496?email_source=notifications&email_token=AAFK2ZJ7A263WJSHBA3GLLTRAIUFRA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKJL27Y#issuecomment-580042111
> >,
> > or unsubscribe
> > <
> https://github.com/notifications/unsubscribe-auth/AAFK2ZI4AVXSFOFBP4DJQLDRAIUFRANCNFSM4KL355LA
> >
> > .
> >
>
> —
> You are receiving this because you commented.
> Reply to this email directly, view it on GitHub
> <#17496?email_source=notifications&email_token=AAAZ5R5YDLT4QONZULIQMMLRAJBNBA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKJRTLI#issuecomment-580065709>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAAZ5RZPNCF3DGQ7776QHHDRAJBNBANCNFSM4KL355LA>
> .
>
|
So after instrumenting a tied array I slightly modify my position. Both
Perl and the tied module are buggy. 😀
I claim both are buggy because there doesnt seem to be any reason to do the
EXTEND at all, *and* the perltie sample code for EXTEND incorrectly
conflates it with STORESIZE when it shouldn't.
Tie::File is buggy presumably because it followed that broken example.
Yves
…On Thu, 30 Jan 2020, 11:38 demerphq, ***@***.***> wrote:
To add to this, imo any tied array should function perfectly fine if
EXTEND is a noop. EXTEND is essentially an optimization that says
"preallocate space efficiently in a chunk so that later I can efficiently
allocate in piecemeal fashion without a penalty each time". If sort breaks
or accesses an element outside of the actually allocated space because it
has called EXTEND then it is making unwarranted assumptions about the
internal implementation of the array.
Yves
On Thu, 30 Jan 2020, 11:33 demerphq, ***@***.***> wrote:
> I don't think that really settles this.
>
> EXTEND implies in memory semantics where the size of the allocated buffer
> differs from what is visible to the user of the array.
>
> A tie to some kind of external store, like Tie::File, cannot support this
> distinction. Whatever is allocated is necessarily "visible".
>
> So arguably calling EXTEND as part of sort() is a bug. I imagine it is
> done to provide oinline space for swaps (but I havent checked), but this
> means it expects to be able to store into an element that has not been
> properly made part of the array which seems pretty dodgy to me. If after
> the sort it "de-extended" the array then it might be ok, but then Tie::File
> wouldn't be broken either.
>
> So imo this is a perl bug as we are subtly assuming the array
> implementation is capable of over allocating invisible elements of the
> array which are usable but not visible which imo is not possible with any
> "hard storage" type Tie.
>
> Yves
>
> On Thu, 30 Jan 2020, 11:19 Eric Brine, ***@***.***> wrote:
>
>> It doesn't break tie modules in general. The linked post above shows that
>> the bug is to specific to Tie::File by demonstrating that Tie::StdArray
>> is
>> not affected.
>>
>> (I didn't analyze the problem de novo since I'm on my phone.)
>>
>> On Wed., Jan. 29, 2020, 8:26 p.m. Yves Orton, ***@***.***>
>> wrote:
>>
>> > On Thu, 30 Jan 2020, 05:46 James E Keenan, ***@***.***>
>> > wrote:
>> >
>> > > The bug is still present in 5.30.1. It can be demonstrated with the
>> > > following program:
>> > >
>> > > $ cat perlmonks-710580-tie-file.pl
>> > > #!/usr/bin/env perl
>> > > use 5.14.0;
>> > > use warnings;
>> > > use Data::Dumper; $Data::Dumper::Indent=1;
>> > > use Carp;
>> > > use Tie::File;
>> > >
>> > > my $g = 'tiefile';
>> > > unlink $g if -f $g;
>> > >
>> > > tie my @tied_array, 'Tie::File', $g or die "Could not tie to $g: $!";
>> > >
>> > > ***@***.***_array, $_) for (1..3);
>> > >
>> > > print ***@***.***_array has " . scalar @tied_array . " elements before
>> > sorting\n";
>> > > @tied_array = sort {uc($a) cmp uc($b)} @tied_array;
>> > >
>> > > print ***@***.***_array has " . scalar @tied_array . " elements after
>> > sorting\n";
>> > > say Dumper ***@***.***_array);
>> > > untie @tied_array;
>> > >
>> > > Results:
>> > >
>> > > $ perl perlmonks-710580-tie-file.pl
>> > > @tied_array has 3 elements before sorting
>> > > @tied_array has 4 elements after sorting
>> > > $VAR1 = [
>> > > '1',
>> > > '2',
>> > > '3',
>> > > ''
>> > > ];
>> > >
>> > > See perlmonks 710580 <http://www.perlmonks.org/?node_id=710580> for
>> good
>> > > analysis by @ikegami <https://github.com/ikegami>
>> > >
>> >
>> > Imo this is a bug in perl not in Tie::File.
>> >
>> > I can imagine why the sort code might want to extend the array, but the
>> > fact that it breaks tie modules shows it's not correct to do so.
>> >
>> > Yves
>> >
>> > >
>> >
>> > —
>> > You are receiving this because you were mentioned.
>> > Reply to this email directly, view it on GitHub
>> > <
>> #17496?email_source=notifications&email_token=AAFK2ZJ7A263WJSHBA3GLLTRAIUFRA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKJL27Y#issuecomment-580042111
>> >,
>> > or unsubscribe
>> > <
>> https://github.com/notifications/unsubscribe-auth/AAFK2ZI4AVXSFOFBP4DJQLDRAIUFRANCNFSM4KL355LA
>> >
>> > .
>> >
>>
>> —
>> You are receiving this because you commented.
>> Reply to this email directly, view it on GitHub
>> <#17496?email_source=notifications&email_token=AAAZ5R5YDLT4QONZULIQMMLRAJBNBA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKJRTLI#issuecomment-580065709>,
>> or unsubscribe
>> <https://github.com/notifications/unsubscribe-auth/AAAZ5RZPNCF3DGQ7776QHHDRAJBNBANCNFSM4KL355LA>
>> .
>>
>
|
On Wed, Jan 29, 2020 at 10:33 PM Yves Orton ***@***.***> wrote:
EXTEND implies in memory semantics where the size of the allocated buffer
differs from what is visible to the user of the array.
A tie to some kind of external store, like Tie::File, cannot support this
distinction. Whatever is allocated is necessarily "visible".
I see what you're saying.
Is one allowed to access allocated elements beyond the length of the array?
If so, then Tie::File is screwed.
If not, then Tie::File could use STORESIZE instead of EXTEND (which would
truly be just a *hint* that memory will be needed), and there's no reason
for sort to extend the array.
|
On Thu, 30 Jan 2020 at 05:54, Eric Brine ***@***.***> wrote:
On Wed, Jan 29, 2020 at 10:33 PM Yves Orton ***@***.***>
wrote:
> EXTEND implies in memory semantics where the size of the allocated buffer
> differs from what is visible to the user of the array.
>
> A tie to some kind of external store, like Tie::File, cannot support this
> distinction. Whatever is allocated is necessarily "visible".
>
I see what you're saying.
Is one allowed to access allocated elements beyond the length of the array?
Exactly what I was trying to say. But from the trace output (code attached
as files):
TiedArray_Test::TIEARRAY -
TiedArray_Test::PUSH - 1
TiedArray_Test::PUSH - 2
TiedArray_Test::PUSH - 3
TiedArray_Test::FETCHSIZE -
@tied_array has 3 elements before sorting
TiedArray_Test::FETCHSIZE -
TiedArray_Test::FETCH - 0
TiedArray_Test::FETCH - 1
TiedArray_Test::FETCH - 2
TiedArray_Test::CLEAR -
TiedArray_Test::EXTEND - 4
TiedArray_Test::STORE - 0 1
TiedArray_Test::STORE - 1 2
TiedArray_Test::STORE - 2 3
TiedArray_Test::FETCHSIZE -
@tied_array has 3 elements after sorting
TiedArray_Test::FETCHSIZE -
TiedArray_Test::FETCH - 0
TiedArray_Test::FETCH - 1
TiedArray_Test::FETCH - 2
$VAR1 = [
1,
2,
3
];
It seems like the EXTEND is not even used.
If so, then Tie::File is screwed.
If not, then Tie::File could use STORESIZE instead of EXTEND (which would
truly be just a *hint* that memory will be needed), and there's no reason
for sort to extend the array.
Yes, exactly my point.
I think Tie::File just needs to make EXTEND a no-op, and we need to change
the documentation for EXTEND in perltie to specifically say "it is a bug to
make EXTEND map to STORESIZE" and change the sample code to be a no-op.
I will try to get such a patch pushed today or tomorrow.
Yves
|
On Thu, 30 Jan 2020 at 07:12, demerphq ***@***.***> wrote:
Exactly what I was trying to say. But from the trace output (code attached
as files):
TiedArray_Test::TIEARRAY -
TiedArray_Test::PUSH - 1
TiedArray_Test::PUSH - 2
TiedArray_Test::PUSH - 3
TiedArray_Test::FETCHSIZE -
@tied_array has 3 elements before sorting
TiedArray_Test::FETCHSIZE -
TiedArray_Test::FETCH - 0
TiedArray_Test::FETCH - 1
TiedArray_Test::FETCH - 2
TiedArray_Test::CLEAR -
TiedArray_Test::EXTEND - 4
TiedArray_Test::STORE - 0 1
TiedArray_Test::STORE - 1 2
TiedArray_Test::STORE - 2 3
TiedArray_Test::FETCHSIZE -
@tied_array has 3 elements after sorting
TiedArray_Test::FETCHSIZE -
TiedArray_Test::FETCH - 0
TiedArray_Test::FETCH - 1
TiedArray_Test::FETCH - 2
$VAR1 = [
1,
2,
3
];
Doh, forgot the files....
|
As far as the perltie change goes:
```diff
diff --git a/pod/perltie.pod b/pod/perltie.pod
index 2d433e8204..239a28e979 100644
--- a/pod/perltie.pod
+++ b/pod/perltie.pod
@@ -301,7 +301,7 @@ spaces so we have a little more work to do here:
croak "length of $value is greater than $self->{ELEMSIZE}";
}
# fill in the blanks
- $self->EXTEND( $index ) if $index > $self->FETCHSIZE();
+ $self->STORESIZE( $index ) if $index > $self->FETCHSIZE();
# right justify to keep element size for smaller elements
$self->{ARRAY}->[$index] = sprintf "%$self->{ELEMSIZE}s", $value;
}
@@ -351,16 +351,24 @@ X<EXTEND>
Informative call that array is likely to grow to have I<count> entries.
Can be used to optimize allocation. This method need do nothing.
…-In our example, we want to make sure there are no blank (C<undef>)
-entries, so C<EXTEND> will make use of C<STORESIZE> to fill elements
-as needed:
+In our example there is no reason to implement this method, so we leave
+it as a no-op. Most pure-perl tied array implementations will not need
+to implement this, it is mostly present for low level implementations
+where a call to EXTEND might be triggered by something like PUSH when
+pushing multiple items into the array.
sub EXTEND {
my $self = shift;
my $count = shift;
- $self->STORESIZE( $count );
+ # nothing to see here, move along.
}
+B<NOTE:> It is generally an error to make this equivalent to STORESIZE.
+Perl may from time to time call EXTEND without wanting to actually change
+the array size directly. Any tied array should function correctly if this
+method is a no-op, if perhaps not be as efficient as it would if it
+implemented this method.
+
=item EXISTS this, key
X<EXISTS>
```
Yves
--
perl -Mre=debug -e "/just|another|perl|hacker/"
|
On Thu, 30 Jan 2020 at 05:23, demerphq ***@***.***> wrote:
So after instrumenting a tied array I slightly modify my position. Both
Perl and the tied module are buggy. 😀
I claim both are buggy because there doesnt seem to be any reason to do
the EXTEND at all, *and* the perltie sample code for EXTEND incorrectly
conflates it with STORESIZE when it shouldn't.
Digging into this further I observe the following:
pp_sort calls
av_extend(av, 3);
in the case of the test code. But for some reason the code in av_extend for
a tied hash does this:
if (mg) {
SV *arg1 = sv_newmortal();
sv_setiv(arg1, (IV)(key + 1));
Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(EXTEND),
G_DISCARD, 1,
arg1);
return;
}
Notice the key+1, which means av_extend increments the count it was called
with by 1 before calling EXTEND.
It is not clear to me why it does this, but it seems to me that it is the
wrong thing to do, especially as the NON mg does not add 1.
This logic has been present since Nick Ing-Simmons added support for tied
arrays to Perl. I do not know why. I am testing if changing this will break
anything right now.
Yves
|
Most tied array implementations can and should NO-OP the EXTEND method, and the sample code should not conflate EXTEND with STORESIZE. EXTEND is actually less usefull used by the core than it could be as AvMAX() does not have an equivalent tied method. So we cannot check if we need to extend. This is related to [rt.cpan.org #39196] / Issue #17496.
…d to av_extend() apparently over the years there has been confusion about what the count argument to av_extend() is for, and at least some of our code has been incorrectly assuming it means the *index* in the array that one wants to write to, and not the number of elements that one expects to be available to write to. This means that part of the code was calling av_extend with arguments one less than they should have been. One such example is the code in pp_aassign() which passes in 1 less than it should, and the code in av_extend() for tied hashes would then add 1 back, thus making the tied interface seem to behave properly. However this is wrong, and it shows up in @tied_array = sort @tied_array; which correctly calls av_extend with the number of elements in the array, which in turn would cause tied hashes to EXTEND one more element than they should, which for something like Tie::File causes the creation of an empty element at the end of the file. It is a little debatable whether Tie::File::EXTEND should be a no-op or not (I lean towards not once the internals are fixed) but it is certainly the case that what we were doing before this was not correct. This fixes [rt.cpan.org #39196] Issue #17496, although does not add tests, which will come in a follow up patch once I have time and I have seen the smoke tests from this patch.
On Thu, 30 Jan 2020 at 08:40, demerphq ***@***.***> wrote:
On Thu, 30 Jan 2020 at 05:23, demerphq ***@***.***> wrote:
> So after instrumenting a tied array I slightly modify my position. Both
> Perl and the tied module are buggy. 😀
>
> I claim both are buggy because there doesnt seem to be any reason to do
> the EXTEND at all, *and* the perltie sample code for EXTEND incorrectly
> conflates it with STORESIZE when it shouldn't.
>
Digging into this further I observe the following:
pp_sort calls
av_extend(av, 3);
in the case of the test code. But for some reason the code in av_extend
for a tied hash does this:
if (mg) {
SV *arg1 = sv_newmortal();
sv_setiv(arg1, (IV)(key + 1));
Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(EXTEND),
G_DISCARD, 1,
arg1);
return;
}
Notice the key+1, which means av_extend increments the count it was called
with by 1 before calling EXTEND.
It is not clear to me why it does this, but it seems to me that it is the
wrong thing to do, especially as the NON mg does not add 1.
I now believe that historically there has been confusion about what the
count argument to av_extend() is supposed to be. Some of the code seems to
mistakenly believe that the count refers to the *index* that you want
available, which is wrong, it should be the number of elements that you
want available.
This mistake seems to be present in pp_aassign, which seems to be the
reason that the tied array branch of aassign increments the argument by 1,
effectively introducing a bug to cancel out the other. When i make
pp_aassign pass in the expected number of elements in the array, and remove
the decrement noted in the quote above, all test pass.
This then lead me to do an audit of all calls to av_extend in the rest of
the C codebase (eg not modules), and it seems this mistake is repeated a
few places.
A related issue is that there is no perlapi documentation of AvMAX, nor is
there a tied method for accessing it, which I feel is a bit odd, we support
EXTEND but have no way to introspect the number of elements that have
actually been allocated. It seems to me that AvMAX should also have a tied
method.
Another issue is that av_extend gets called relatively rarely, one of the
reasons auditing the calls was even approachable. For instance i would
expect the code for pp_push to check AvMAX and if we are going to push more
than the number of items onto the array than it can store then it should
call av_extend, and then do its business.
So at this point I return to my original position, this is a bug in Perl.
Whether there actually is a bug in Tie::File is less clear, for instance by
fixing the fencepost errors in av_extend() and pp_aassign the bug goes away
in my test code and in the test file posted by James.
I have pushed a patch which fixes this issue and also fixes all the other
places that I could find where it seemed that av_extend() was being called
with an index instead of a count. It passed all tests for me locally. I
will add tests later once I see some smoke results and I hear feedback from
the list.
See smoke-me/fix_issue_17496
Yves
|
In [rt.cpan.org #39196] issue #17496 there is a report that Tie::File produced spurious blank lines in the file after @tied= sort @tied; it turns out that this is because Tie::File treats EXTEND similarly to STORESIZE (which is arguably not entirely correct, but also not that weird) coupled with an off by one error in the calls to av_extend() in pp_sort. This patch fixes the fencepost error, adds some comments to av_extend() to make it clear what it is doing, and adds a test that EXTEND is called by this code with correct argument.
On Thu, 30 Jan 2020 at 09:52, demerphq ***@***.***> wrote:
On Thu, 30 Jan 2020 at 08:40, demerphq ***@***.***> wrote:
> On Thu, 30 Jan 2020 at 05:23, demerphq ***@***.***> wrote:
>
>> So after instrumenting a tied array I slightly modify my position. Both
>> Perl and the tied module are buggy. 😀
>>
>> I claim both are buggy because there doesnt seem to be any reason to do
>> the EXTEND at all, *and* the perltie sample code for EXTEND incorrectly
>> conflates it with STORESIZE when it shouldn't.
>>
>
> Digging into this further I observe the following:
>
> pp_sort calls
>
> av_extend(av, 3);
>
> in the case of the test code. But for some reason the code in av_extend
> for a tied hash does this:
>
> if (mg) {
> SV *arg1 = sv_newmortal();
> sv_setiv(arg1, (IV)(key + 1));
> Perl_magic_methcall(aTHX_ MUTABLE_SV(av), mg, SV_CONST(EXTEND),
> G_DISCARD, 1,
> arg1);
> return;
> }
>
> Notice the key+1, which means av_extend increments the count it was
> called with by 1 before calling EXTEND.
>
> It is not clear to me why it does this, but it seems to me that it is the
> wrong thing to do, especially as the NON mg does not add 1.
>
I now believe that historically there has been confusion about what the
count argument to av_extend() is supposed to be. Some of the code seems to
mistakenly believe that the count refers to the *index* that you want
available, which is wrong, it should be the number of elements that you
want available.
Well, I think now I was wrong on this. I mean, I think there is confusion,
and that some of our code calls av_extend() incorrectly, but its the other
way round from what I said in my previous post. The buggy code calls
av_extend() with a *count* when it should call it with an *index* (key in
the .c code). This includes the calls to av_extend() in pp_sort. Once those
calls are changed to subtract one from the count things work out fine.
I pushed a new patch in: 'smoke-me/better_fix_for_17496' which does this
version of the fix, and includes tests. The confusion was because EXTEND
*does* take a count, and not an index, which is why the logic for tied
arrays in av_extend() added 1 to its argument. So i added some additional
comments to the code to explain what was going on so nobody makes the same
mistake I did.
I think my previous branch smoke-me/fix_issue_17496 can be deleted, but ill
wait a few days first.
Cheers,
Yves
|
On Thu, Jan 30, 2020 at 09:37:37AM -0800, Yves Orton wrote:
Well, I think now I was wrong on this. I mean, I think there is confusion,
and that some of our code calls av_extend() incorrectly, but its the other
way round from what I said in my previous post.
Agreed
I pushed a new patch in: 'smoke-me/better_fix_for_17496' which does this
version of the fix, and includes tests. The confusion was because EXTEND
*does* take a count, and not an index, which is why the logic for tied
arrays in av_extend() added 1 to its argument. So i added some additional
comments to the code to explain what was going on so nobody makes the same
mistake I did.
The patch appears sound to me, although I'm not keen on the changed working
for the av_extend API entry. In clarifying whether 'key' is an index or
size, it seems at the same time to make more ambiguous whether av_extend()
creates new keys or just allocates space for potential new key.
Also strictly speaking, directly accessing AvARRAY(av)[key] isn't part of
the public API.
So how about instead:
Pre-extend an array so that it is capable of storing values at indexes
0..key. Thus av_extend(av,99) guarantees that the array can store 100
elements, i.e. that av_store(av, 0, sv) through av_store(av, 99, sv)
on a plain array will work without any further memory allocation.
…--
Never do today what you can put off till tomorrow.
|
On Fri, 31 Jan 2020 at 14:06, iabyn ***@***.***> wrote:
On Thu, Jan 30, 2020 at 09:37:37AM -0800, Yves Orton wrote:
> Well, I think now I was wrong on this. I mean, I think there is
confusion,
> and that some of our code calls av_extend() incorrectly, but its the
other
> way round from what I said in my previous post.
Agreed
Ok, cool.
FWIW, I still see a lot of code that seems to be assuming that av_extend()
takes a count not an index.
Do you think its worth us doing a further audit?
> I pushed a new patch in: 'smoke-me/better_fix_for_17496' which does this
> version of the fix, and includes tests. The confusion was because EXTEND
> *does* take a count, and not an index, which is why the logic for tied
> arrays in av_extend() added 1 to its argument. So i added some additional
> comments to the code to explain what was going on so nobody makes the
same
> mistake I did.
The patch appears sound to me, although I'm not keen on the changed working
for the av_extend API entry. In clarifying whether 'key' is an index or
size, it seems at the same time to make more ambiguous whether av_extend()
creates new keys or just allocates space for potential new key.
Also strictly speaking, directly accessing AvARRAY(av)[key] isn't part of
the public API.
So how about instead:
Pre-extend an array so that it is capable of storing values at indexes
0..key. Thus av_extend(av,99) guarantees that the array can store 100
elements, i.e. that av_store(av, 0, sv) through av_store(av, 99, sv)
on a plain array will work without any further memory allocation.
Sounds good to me, ill put together a new version with that wording.
I think I will also add a note that it will call EXTEND if the av is tied.
Any objection?
Thanks for the review!
cheers,
Yves
|
On Fri, Jan 31, 2020 at 05:47:03AM -0800, Yves Orton wrote:
FWIW, I still see a lot of code that seems to be assuming that av_extend()
takes a count not an index.
Do you think its worth us doing a further audit?
Perhaps add a debugging build option such that av_extend() etc
only ever reallocs() the requested size - no rounding up and adding a bit
etc. The valgrind et al are likely to find bad uses of av_extend().
I think I will also add a note that it will call EXTEND if the av is tied.
Any objection?
Sounds good - perhaps also mention that it calls EXTEND(key+1).
…--
Monto Blanco... scorchio!
|
Most tied array implementations can and should NO-OP the EXTEND method, and the sample code should not conflate EXTEND with STORESIZE. EXTEND is actually less usefully used by the core than it could be as AvMAX() does not have an equivalent tied method. So we cannot check if we need to extend for a tied array. This is related to [rt.cpan.org #39196] / Issue #17496.
In [rt.cpan.org #39196] issue #17496 there is a report that Tie::File produced spurious blank lines in the file after @tied= sort @tied; it turns out that this is because Tie::File treats EXTEND similarly to STORESIZE (which is arguably not entirely correct, but also not that weird) coupled with an off by one error in the calls to av_extend() in pp_sort. This patch fixes the fencepost error, adds some comments to av_extend() to make it clear what it is doing, and adds a test that EXTEND is called by this code with correct argument.
On Fri, 31 Jan 2020 at 15:02, iabyn ***@***.***> wrote:
On Fri, Jan 31, 2020 at 05:47:03AM -0800, Yves Orton wrote:
> FWIW, I still see a lot of code that seems to be assuming that
av_extend()
> takes a count not an index.
>
> Do you think its worth us doing a further audit?
Perhaps add a debugging build option such that av_extend() etc
only ever reallocs() the requested size - no rounding up and adding a bit
etc. The valgrind et al are likely to find bad uses of av_extend().
But if they are passing in the count instead of the index they are asking
for 1 more than they need, so unless im missing something valgrind wouldn't
notice. The only thing that might notice is something like Tie::File which
would Do The Wrong Thing.
> I think I will also add a note that it will call EXTEND if the av is
tied.
> Any objection?
Sounds good - perhaps also mention that it calls EXTEND(key+1).
Done. Merged into blead as 2b30192
Pod change to perltie.pod is 3eb35b0
I will close this ticket -- although I am still troubled by the way
Tie::File implements EXTEND, but maybe we should open a new ticket for that
if someone can find a circumstance where it matters.
cheers,
Yves
…--
perl -Mre=debug -e "/just|another|perl|hacker/"
|
Thanks for the report Eric! Sorry it took so long to fix. :-( |
We had a failure from this commit: https://github.com/Perl/perl5/runs/419405069?check_suite_focus=true |
On Fri, 31 Jan 2020 at 17:26, Todd Rinaldo ***@***.***> wrote:
We had a failure from this commit:
https://github.com/Perl/perl5/runs/419405069?check_suite_focus=true
Hrm. On win32 only. :-(
I can revert, but it would be nice to see what went wrong with this test.
If someone can build under win32 I would love to see the output of:
make test_harness TEST_ARGS="-v -re op/sort"
Yves
|
|
I didn't investigate it further, but the backtrace looks very similar to #16729, which basically seems to be a compiler/linker/something bug triggered by random, harmless code changes. BTW, I also ran into it on my private branch where I was doing some optimizations in pp_sort. |
Let me rerun it |
I got the same results as xenu with the default build options, but the error went away when I switched to a debug build.
|
I feel like we should keep this ticket closed and open a new ticket for
this bug. It isnt coming from the change I made, and we should fix it
specifically and not leave the EXTEND bug while we figure out what to do.
This exception comes from testing that sorting a readonly array croaks.
The issue that xenu mentioned, #16729 is also related to croaking.
Both end up triggered an exception from Perl_die_unwind, also mentioned is
that this could be a Linker bug and it is specific to certain compilers
also both tickets mention that enabling DEBUGGING fixes it.
Leaving aside whether it is a linker bug, could this mean that perhaps we
are somehow messing up something related to Perl_die_unwind()?
Anyway, i vote we close this ticket, and create a new ticket consolidating
this error with the one reported in #16729.
If we are pressed to make a release then we can revert, but it just feels
wrong to not fix one bug because it happens to tickle a compiler/linker bug
somewhere else.
Yves
…On Fri, 31 Jan 2020 at 20:43, Eric Brine ***@***.***> wrote:
I got the same results as xenu with the default build options, but the
error went away when I switched to a debug build.
C:\Users\ikegami\x\t>gdb --args ..\perl -I ..\lib op\sort.t
GNU gdb (GDB) 8.2.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-w64-mingw32".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ..\perl...done.
(gdb) run
Starting program: C:\Users\ikegami\x\perl.exe -I ..\lib op\sort.t
[New Thread 3252.0xccc]
[New Thread 3252.0x4250]
[New Thread 3252.0x3ff4]
[New Thread 3252.0x54e8]
1..203
ok 1 - upper first 1
ok 2 - upper first 2
ok 3 - upper first 3
ok 4 - sort of non-utf8 list worked
ok 5 - No elements were wrongly converted to utf8 in sorting
ok 6 - sort of utf8 list worked
ok 7 - No elements were wrongly converted from utf8 in sorting
ok 8 - upper first 4
ok 9 - reverse 1
ok 10 - reverse 2
ok 11 - reverse 3
ok 12 - reverse 4
ok 13 - reverse 5
ok 14 - sort numeric
ok 15 - sorter sub name in var 1
ok 16 - sorter sub name in var 2
ok 17 - just sort
ok 18 - grep then sort
ok 19 - map then sort
ok 20 - reverse then sort
ok 21 - CORE::reverse then sort
ok 22
ok 23 - redefine sort sub inside the sort sub
ok 24 - redefining sort subs outside the sort $@=[]
ok 25 - twoface redefinition
ok 26 - redefinition should not take effect during the sort
ok 27 - twoface eval
ok 28 - old skool package
ok 29 - one is not a sub
ok 30 - sortname 1
ok 31 - sortname 2
ok 32 - sortname 3
ok 33 - sortname 4
ok 34 - sortname 5
ok 35 - sortname 6
ok 36 - sortname 7
ok 37 - sortname 8
ok 38 - sortname local 1
ok 39 - sortname local 2
ok 40 - sortname local 3
ok 41 - sortname local 4
ok 42 - sortname local 5
ok 43 - sortname local 6
ok 44 - sortname local 7
ok 45 - sortname local 8
ok 46 - force blockness
ok 47 - a cmp b
ok 48 - b cmp a
ok 49 - integer a <=> b
ok 50 - integer b <=> a
ok 51 - integer a cmp b
ok 52 - integer b cmp a
ok 53 - optimized-away comparison block doesn't take any other arguments away with it
ok 54 - not in main:: 1
ok 55 - not in main:: 2
ok 56 - wantarray 1
ok 57 - wantarray 1
ok 58 - wantarray 1
ok 59 - wantarray 1
ok 60 - wantarray 2
ok 61 - wantarray 2
ok 62 - wantarray 2
ok 63 - reenter 1
ok 64 - reenter 2
ok 65 - bug id 19991001.003 (\#1549)
ok 66 - inplace sort of global
ok 67 - inplace sort of lexical
ok 68 - inplace reversed sort of global
ok 69 - inplace custom sort of global
ok 70 - inplace sort with function of lexical
ok 71 - inplace sort of tied array
ok 72 - inplace sort of tied array with function
ok 73 - un-inplace sort of global
ok 74 - un-inplace sort of global 2
ok 75 - un-inplace sort of lexical
ok 76 - un-inplace sort of lexical 2
ok 77 - un-inplace reversed sort of global
ok 78 - un-inplace reversed sort of global 2
ok 79 - un-inplace custom sort of global
ok 80 - un-inplace custom sort of global 2
ok 81 - un-inplace sort with function of lexical
ok 82 - un-inplace sort with function of lexical 2
ok 83 - in-place sorting segfault
ok 84 - RT 39358 - aa
ok 85 - RT 39358 - copy
ok 86 - RT \#128340
ok 87 - test that EXTEND has not been called prior to initialization
ok 88 - test that EXTEND has not been called during initialization
ok 89 - test that EXTEND was called with an argument of 3 by pp_sort()
ok 90 - test that sorting the tied array worked even though EXTEND is a no-op
ok 91 - Simple stable sort
ok 92 - Simple stable in place sort
ok 93 - stable $a <=> $b sort
ok 94 - stable $a cmp $b sort
ok 95 - stable $a cmp $b in place sort
ok 96 - stable $b cmp $a sort
ok 97 - stable $b cmp $a in place sort
ok 98 - Reversed stable sort
ok 99 - Reversed stable in place sort
ok 100 - Reversed stable sort in scalar context
ok 101 - reversed stable $a cmp $b sort
ok 102 - revesed stable $a cmp $b in place sort
ok 103 - Reversed stable $a cmp $b sort in scalar context
ok 104 - reversed stable $b cmp $a sort
ok 105 - revesed stable $b cmp $a in place sort
ok 106 - Reversed stable $b cmp $a sort in scalar context
ok 107 - reversed stable complex sort
ok 108 - revesed stable complex in place sort
ok 109 - Reversed stable complex sort in scalar context
ok 110 - reversed stable sort return list context
ok 111 - reversed stable sort return scalar context
ok 112 - reversed stable $a cmp $b sort return list context
ok 113 - reversed stable $a cmp $b sort return scalar context
ok 114 - reversed stable $b cmp $a sort return list context
ok 115 - reversed stable $b cmp $a sort return scalar context
ok 116 - reversed stable complex sort return list context
ok 117 - reversed stable complex sort return scalar context
ok 118 - stable $a cmp $b sort
ok 119 - stable $a <=> $b sort
ok 120 - stable $a <=> $b in place sort
ok 121 - stable $b <=> $a sort
ok 122 - stable $b <=> $a in place sort
ok 123 - optimized { <=> } without overloading
ok 124 - inline optimized { <=> } without overloading
ok 125 - Reversed stable sort
ok 126 - Reversed stable in place sort
ok 127 - Reversed stable sort in scalar context
ok 128 - reversed stable $a <=> $b sort
ok 129 - revesed stable $a <=> $b in place sort
ok 130 - reversed stable $a <=> $b sort in scalar context
ok 131 - reversed stable $b <=> $a sort
ok 132 - revesed stable $b <=> $a in place sort
ok 133 - reversed stable $b <=> $a sort in scalar context
ok 134 - reversed stable complex sort
ok 135 - revesed stable complex in place sort
ok 136 - reversed stable complex sort in scalar context
ok 137 - reversed stable $a <=> $b sort return list context
ok 138 - reversed stable $a <=> $b sort return scalar context
ok 139 - reversed stable $b <=> $a sort return list context
ok 140 - reversed stable $b <=> $a sort return scalar context
ok 141 - reversed stable complex sort return list context
ok 142 - reversed stable complex sort return scalar context
ok 143 - reversed sort with trailing argument
ok 144 - reversed sort with leading argument
ok 145 - goto subr outside subr
ok 146 - goto subr from a sort sub
ok 147 - goto out of a pseudo block 1
ok 148 - goto out of a pseudo block 2
ok 149 - undef active subr
ok 150 - sort from active sub
ok 151 - sort from active sub
ok 152 - sort subr called from other package
ok 153 - bug 36430
ok 154 - sort sub refcnt
ok 155 - in-place sort of read-only array
ok 156 - return within loop
ok 157 - return with SVs on stack
ok 158 - return with SVs on stack
ok 159 - comparison result as string
ok 160 - comparison result as string
ok 161 - overload compare called once
ok 162 - overload sort result
ok 163 - overload string called twice
ok 164 - RT \#72334
ok 165 - RT \#72334
ok 166 - None before we start
ok 167 - 2 here
ok 168
ok 169 - sorted!
ok 170 - still the same 2 here
ok 171 - all gone
ok 172 - [perl \#77930] cx_stack reallocation during sort
ok 173 - Match vars do not leak from one plain sort sub to the next
ok 174 - Match vars do not leak from one $$ sort sub to the next
ok 175 - stubborn AUTOLOAD
ok 176 - AUTOLOAD without stub
ok 177 - AUTOLOAD with stubref
ok 178 - (sort) does not die
ok 179 - (sort) returns empty list
ok 180 - sort; does not die
ok 181 - sort; returns empty list
ok 182 - {sort} does not die
ok 183 - {sort} returns empty list
ok 184 - padrange and void context
ok 185 - no panic/crash with fatal warnings when sort sub returns undef
ok 186 - no panic/crash with fatal warnings when sort sub returns string
ok 187 - no panic/crash with fatal warnings when sort sub($$) returns undef
ok 188 - no panic/crash with fatal warnings when sort sub($$) returns string
ok 189 - sort block modifying $a and $b
ok 190 - [perl \#78194] op return values passed to sort
ok 191 - no crash when sort block deletes *a and *b
ok 192 - Ret: null blk
ok 193 - Ret: blk
ok 194 - Ret: blk ret
ok 195 - Ret: f0
ok 196 - Ret: f1
ok 197 - Ret: f2
ok 198 - Ret: f3
ok 199 - No crash when GP deleted out from under us [perl 124097]
ok 200 - *a wasn't localized inadvertantly
ok 201 - check sort order
ok 202
ok 203
[Thread 3252.0x54e8 exited with code 0]
[Thread 3252.0x4250 exited with code 0]
[Thread 3252.0x3ff4 exited with code 0]
[Inferior 1 (process 3252) exited normally]
(gdb)
—
You are receiving this because you modified the open/close state.
Reply to this email directly, view it on GitHub
<#17496?email_source=notifications&email_token=AAAZ5R3U3KTBYOZRQFBM4XTRAR5NNA5CNFSM4KL355LKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEKPY2EY#issuecomment-580881683>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAAZ5R5WDXPYN43C3DZYFHLRAR5NNANCNFSM4KL355LA>
.
--
perl -Mre=debug -e "/just|another|perl|hacker/"
|
@demerphq thats fine. Can you open the other ticket and reference this one pls? |
On Sat, 1 Feb 2020 at 19:17, Todd Rinaldo ***@***.***> wrote:
@demerphq <https://github.com/demerphq> thats fine. Can you open the
other ticket and reference this one pls?
Done with #17521
|
Migrated from rt.cpan.org#39196 (status was 'new')
Requestors:
From [email protected] on 2008-09-12 00:19:06
:
The text was updated successfully, but these errors were encountered: