Skip to content
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

Dumpvalue's dumpValue and dumpValues do not behave the same way #17155

Closed
p5pRT opened this issue Sep 19, 2019 · 11 comments
Closed

Dumpvalue's dumpValue and dumpValues do not behave the same way #17155

p5pRT opened this issue Sep 19, 2019 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Sep 19, 2019

Migrated from rt.perl.org#134441 (status was 'pending release')

Searchable as RT134441$

@p5pRT
Copy link
Author

p5pRT commented Sep 19, 2019

From henrik.pauli@comnica.com

This is a bug report for perl from henrik.pauli@​comnica.com,
generated with the help of perlbug 1.41 running under perl 5.28.2.

Contrary to what the manual claims, the singular and the plural form
don't behave the same when `undef` is involved​:

```perl
use v5.10;
use Dumpvalue;

my $dv = Dumpvalue->new();
my ($x, $y) = (undef, "something");

say "x = " . ($x // "<UNDEF>");
say "y = " . ($y // "<UNDEF>");
say "dumpValues(x, y)​:";
$dv->dumpValues($x, $y);
say "dumpValue([x, y])​:";
$dv->dumpValue([$x, $y]);
```

Output​:
```
x = <UNDEF>
y = something
dumpValues(x, y)​:
undef
dumpValue([x, y])​:
0  undef
1  'something'
```

Expected output​:

Both should say
```
0  undef
1  'something'
```


Flags​:
    category=library
    severity=low
    module=Dumpvalue


This perlbug was built using Perl 5.28.2 - Thu Aug 22 12​:32​:10 UTC 2019
It is being executed now by  Perl 5.28.2 - Thu Aug 22 12​:27​:54 UTC 2019.

Site configuration information for perl 5.28.2​:

Configured by Red Hat, Inc. at Thu Aug 22 12​:27​:54 UTC 2019.

Summary of my perl5 (revision 5 version 28 subversion 2) configuration​:

  Platform​:
    osname=linux
    osvers=5.0.6-200.fc29.x86_64
    archname=x86_64-linux-thread-multi
    uname='linux buildvm-10.phx2.fedoraproject.org
5.0.6-200.fc29.x86_64 #1 smp wed apr 3 15​:09​:51 utc 2019 x86_64 x86_64
x86_64 gnulinux '
    config_args='-des -Doptimize=none -Dccflags=-O2 -g -pipe -Wall
-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2
-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong
-grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
-Dldflags=-Wl,-z,relro        -Wl,-z,now
-specs=/usr/lib/rpm/redhat/redhat-hardened-ld
-Dccdlflags=-Wl,--enable-new-dtags -Wl,-z,relro   -Wl,-z,now
-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Dlddlflags=-shared
-Wl,-z,relro   -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld
-Dshrpdir=/usr/lib64 -DDEBUGGING=-g -Dversion=5.28.2
-Dmyhostname=localhost -Dperladmin=root@​localhost -Dcc=gcc -Dcf_by=Red
Hat, Inc. -Dprefix=/usr -Dvendorprefix=/usr -Dsiteprefix=/usr/local
-Dsitelib=/usr/local/share/perl5
-Dsitearch=/usr/local/lib64/perl5 -Dprivlib=/usr/share/perl5
-Dvendorlib=/usr/share/perl5/vendor_perl -Darchlib=/usr/lib64/perl5
-Dvendorarch=/usr/lib64/perl5/vendor_perl
-Darchname=x86_64-linux-thread-multi -Dlibpth=/usr/local/lib64 /lib64
/usr/lib64 -Duseshrplib -Dusethreads -Duseithreads
-Dusedtrace=/usr/bin/dtrace -Duselargefiles -Dd_semctl_semun -Di_db
-Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio
-Dinstallusrbinperl=n -Ubincompat5005 -Uversiononly
-Dpager=/usr/bin/less -isr -Dd_gethostent_r_proto -Ud_endhostent_r_proto
-Ud_sethostent_r_proto -Ud_endprotoent_r_proto -Ud_setprotoent_r_proto
-Ud_endservent_r_proto -Ud_setservent_r_proto -Dscriptdir=/usr/bin
-Dusesitecustomize -Duse64bitint'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler​:
    cc='gcc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall
-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2
-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong
-grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
-fwrapv -fno-strict-aliasing -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64'
    optimize='  -g'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -O2 -g -pipe -Wall
-Werror=format-security -Wp,-D_FORTIFY_SOURCE=2
-Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong
-grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1
-specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic
-fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection
-fwrapv -fno-strict-aliasing -I/usr/local/include'
    ccversion=''
    gccversion='8.3.1 20190223 (Red Hat 8.3.1-2)'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    ivtype='long'
    ivsize=8
    nvtype='double'
    nvsize=8
    Off_t='off_t'
    lseeksize=8
    alignbytes=8
    prototype=define
  Linker and Libraries​:
    ld='gcc'
    ldflags ='-Wl,-z,relro -Wl,-z,now
-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -fstack-protector-strong
-L/usr/local/lib'
    libpth=/usr/local/lib64 /lib64 /usr/lib64 /usr/local/lib /usr/lib
/lib/../lib64 /usr/lib/../lib64 /lib
    libs=-lpthread -lresolv -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc
-lgdbm_compat
    perllibs=-lpthread -lresolv -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.28.so
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.28'
  Dynamic Linking​:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,--enable-new-dtags -Wl,-z,relro -Wl,-z,now
-specs=/usr/lib/rpm/redhat/redhat-hardened-ld'
    cccdlflags='-fPIC'
    lddlflags='-lpthread -shared -Wl,-z,relro -Wl,-z,now
-specs=/usr/lib/rpm/redhat/redhat-hardened-ld -L/usr/local/lib
-fstack-protector-strong'

Locally applied patches​:
    Fedora Patch1​: Removes date check, Fedora/RHEL specific
    Fedora Patch2​: support for libdir64
    Fedora Patch3​: use libresolv instead of libbind
    Fedora Patch4​: USE_MM_LD_RUN_PATH
    Fedora Patch5​: Provide MM​::maybe_command independently (bug #1129443)
    Fedora Patch6​: Dont run one io test due to random builder failures
    Fedora Patch8​: Define SONAME for libperl.so
    Fedora Patch9​: Install libperl.so to -Dshrpdir value
    Fedora Patch10​: Document Math​::BigInt​::CalcEmu requires
Math​::BigInt (CPAN RT#85015)
    Fedora Patch11​: Make *DBM_File desctructors thread-safe (RT#61912)
    Fedora Patch12​: Replace EU​::MakeMaker dependency with EU​::MM​::Utils
in IPC​::Cmd (bug #1129443)
    Fedora Patch13​: Fix executing arybase​::_tie_it() in Safe
compartement (RT#131588)
    Fedora Patch14​: Link XS modules to pthread library to fix linking
with -z defs
    Fedora Patch17​: Fix printing a warning about a wide character when
matching a regular expression while ISO-8859-1 locale is in effect
    Fedora Patch18​: Fix invoking a check for wide characters while
ISO-8859-1 locale is in effect
    Fedora Patch20​: Fix build conditions in locale.c
    Fedora Patch21​: Fix a file descriptor leak in in-place edits
(RT#133314)
    Fedora Patch23​: Fix a buffer overrun in deprecated S_is_utf8_common()
    Fedora Patch24​: Fix a time race in Time-HiRes/t/itimer.t test
    Fedora Patch26​: Fix Time​::Piece to handle objects in overloaded
methods correctly
    Fedora Patch27​: Fix an assignment to a lexical variable in
multiconcatenation expressions (RT#133441)
    Fedora Patch28​: Fix a spurious warning about uninitialized value in
warn (RT#132683)
    Fedora Patch30​: Pass the correct CFLAGS to dtrace
    Fedora Patch33​: Fix PathTools tests to cope with ESTALE error
(RT#133534)
    Fedora Patch34​: Fix an undefined behaviour in S_hv_delete_common()
    Fedora Patch38​: Fix compiling regular expressions that contain both
compile- and run-time compiled code blocks (RT#133687)
    Fedora Patch39​: Adjust tests to gdbm-1.15 (RT#133295)
    Fedora Patch44​: Fix reporting a line number for non-terminated
prototypes (RT#133524)
    Fedora Patch45​: Fix first eof() return value (RT#133721)
    Fedora Patch49​: Prevent long jumps from clobbering local variables
(RT#133575)
    Fedora Patch50​: Fix a mismatch with a case-insesitive regular
expression on a text with ligatures (RT#133756)
    Fedora Patch53​: Fix setting magic when changing $^R (RT#133782)
    Fedora Patch54​: Fix a race when loading XS modules
    Fedora Patch56​: Fix a leak when compiling a typed hash dereference
    Fedora Patch58​: Fix a buffer overread when handling a scope error
in qr/\(?{/ (RT#133879)
    Fedora Patch59​: Fix a buffer overread when parsing a regular
expression with an unknown character name (RT#133880)
    Fedora Patch60​: Fix mbstate_t initialization in POSIX​::mblen
(RT#133928)
    Fedora Patch61​: Fix a memory leak when cloning a regular expression
    Fedora Patch62​: Fix a memory leak when spawning threads in a BEGIN
phase
    Fedora Patch63​: Fix a memory leak when assigning a regular
expression to a non-copy-on-write string
    Fedora Patch64​: Fix a memory leak when assignig to a localized
${^WARNING_BITS}
    Fedora Patch65​: Fix a memory leak when parsing misindented
here-documents
    Fedora Patch66​: Fix a memory leak in package name lookup (RT#133977)
    Fedora Patch68​: Fix a memory leak when deletion in a tied hash dies
    Fedora Patch69​: Fix a crash when matching case insensitively
(RT#133892)
    Fedora Patch70​: Fix a memory leak when warning about malformed
UTF-8 string
    Fedora Patch71​: Do not panic when evaluating non-ASCII bare words
(RT#134061)
    Fedora Patch72​: Do not panic when evaluating non-ASCII bare words
(RT#134061)
    Fedora Patch73​: Fix a crash in SIGALARM handler when waiting on a
child process to be closed (RT#122112)
    Fedora Patch74​: Fix a crash in SIGALARM handler when waiting on a
child process to be closed (RT#122112)
    Fedora Patch75​: Fix a crash in SIGALARM handler when waiting on a
child process to be closed (RT#122112)
    Fedora Patch76​: Fix a crash with a negative precision in sprintf
function (RT#134008)
    Fedora Patch77​: Fix a crash with a negative precision in sprintf
function (RT#134008)
    Fedora Patch78​: Prevent from wrapping a width in a numeric format
string (RT#133913)
    Fedora Patch79​: Fix subroutine protypes to track reference aliases
(RT#134072)
    Fedora Patch80​: Improve retrieving a scalar value of a variable
modified in a signal handler (RT#134035)
    Fedora Patch81​: Fix changing packet destination sent from a UDP
IO​::Socket object (RT#133936)
    Fedora Patch82​: Fix changing packet destination sent from a UDP
IO​::Socket object (RT#133936)
    Fedora Patch83​: Fix changing packet destination sent from a UDP
IO​::Socket object (RT#133936)
    Fedora Patch84​: Fix a stack underflow in readline() if passed an
empty array as an argument (#RT133989)
    Fedora Patch85​: Fix %{^CAPTURE_ALL} to be an alias for %- variable
(RT#131867)
    Fedora Patch86​: Fix %{^CAPTURE} value when used after @​{^CAPTURE}
(RT#134193)
    Fedora Patch87​: Fix %{^CAPTURE} value when used after @​{^CAPTURE}
(RT#134193)
    Fedora Patch88​: Fix a test for a crash in SIGALARM handler when
waiting on a child process to be closed (RT#122112)
    Fedora Patch89​: Fix a crash on an uninitialized warning when
processing a multideref node (RT#134275)
    Fedora Patch90​: Preserve append mode when opening anonymous files
(RT#134221)
    Fedora Patch91​: Preserve append mode when opening anonymous files
(RT#134221)
    Fedora Patch92​: Preserve append mode when opening anonymous files
(RT#134221)
    Fedora Patch93​: Fix propagating non-string variables in an
exception value (RT#134291)
    Fedora Patch94​: Include trailing zero in scalars holding trie data
(RT#134207)
    Fedora Patch95​: Fix a use after free in /(?{...})/ (RT#134208)
    Fedora Patch96​: Fix a use after free in debugging output of a collation
    Fedora Patch97​: Fix a NULL pointer dereference in PerlIOVia_pushed()
    Fedora Patch98​: Fix a crash when setting $@​ on unwinding a call
stack (RT#134266)
    Fedora Patch99​: Fix a documentation about a future API change
    Fedora Patch200​: Link XS modules to libperl.so with EU​::CBuilder on
Linux
    Fedora Patch201​: Link XS modules to libperl.so with EU​::MM on Linux


@​INC for perl 5.28.2​:
    /usr/local/lib64/perl5
    /usr/local/share/perl5
    /usr/lib64/perl5/vendor_perl
    /usr/share/perl5/vendor_perl
    /usr/lib64/perl5
    /usr/share/perl5


Environment for perl 5.28.2​:
    HOME=/home/henrik
    LANG=en_GB.utf8
    LANGUAGE=
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
PATH=/usr/lib64/qt-3.3/bin​:/home/henrik/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/local/sbin​:/usr/sbin
    PERL_BADLANG (unset)
    SHELL=/bin/zsh

@p5pRT
Copy link
Author

p5pRT commented Sep 20, 2019

From @jkeenan

On Thu, 19 Sep 2019 13​:06​:49 GMT, henrik.pauli@​comnica.com wrote​:

This is a bug report for perl from henrik.pauli@​comnica.com,
generated with the help of perlbug 1.41 running under perl 5.28.2.

Contrary to what the manual claims, the singular and the plural form
don't behave the same when `undef` is involved​:

```perl
use v5.10;
use Dumpvalue;

my $dv = Dumpvalue->new();
my ($x, $y) = (undef, "something");

say "x = " . ($x // "<UNDEF>");
say "y = " . ($y // "<UNDEF>");
say "dumpValues(x, y)​:";
$dv->dumpValues($x, $y);
say "dumpValue([x, y])​:";
$dv->dumpValue([$x, $y]);
```

Output​:
```
x = <UNDEF>
y = something
dumpValues(x, y)​:
undef
dumpValue([x, y])​:
0  undef
1  'something'
```

Expected output​:

Both should say
```
0  undef
1  'something'
```

I believe that the patch attached confirms the bug. It appears that the methods cannot properly handle undefined values in the array passed to the dumpValues() method or to the arrayref passed to the dumpValue() method. These cases were not previously tested.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Sep 20, 2019

From @jkeenan

0001-Test-previously-untested-cases.patch
From 1bd3f4b050f460a6bf5c2ada695abc5a5a92e21b Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Thu, 19 Sep 2019 23:02:54 -0400
Subject: [PATCH] Test previously untested cases

These tests demonstrate the problem reported in RT 134441.  It appears
that neither '$d->dumpValues(@array)' nor '$d->dumpValue([@array])'
properly handles undefined values, at least where @array > 1.
---
 dist/Dumpvalue/t/Dumpvalue.t | 45 +++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/dist/Dumpvalue/t/Dumpvalue.t b/dist/Dumpvalue/t/Dumpvalue.t
index 7063dd984c..f04b854014 100644
--- a/dist/Dumpvalue/t/Dumpvalue.t
+++ b/dist/Dumpvalue/t/Dumpvalue.t
@@ -16,7 +16,7 @@ BEGIN {
 
 our ( $foo, @bar, %baz );
 
-use Test::More tests => 88;
+use Test::More qw(no_plan); # tests => 88;
 
 use_ok( 'Dumpvalue' );
 
@@ -270,6 +270,49 @@ is( $out->read, "'two'\n", 'dumpValue worked on array' );
 $d->dumpValue(\$foo);
 is( $out->read, "-> 'one'\n", 'dumpValue worked on scalar ref' );
 
+# RT 134441
+@foobar = ('foo', 'bar');
+$d->dumpValue([@foobar]);
+$x = $out->read;
+is( $x, "0..1  'foo' 'bar'\n", 'dumpValue worked on array ref' );
+$d->dumpValues(@foobar);
+$y = $out->read;
+is( $y, "0..1  'foo' 'bar'\n", 'dumpValues worked on array' );
+is( $y, $x,
+    "dumpValues called on array returns same as dumpValue on array ref");
+
+@foobar = (undef, 'bar');
+$d->dumpValue([@foobar]);
+is( $out->read, "0..1  undef 'bar'\n",
+    'dumpValue worked on array ref, first element undefined' );
+$d->dumpValues(@foobar);
+is( $out->read, "0..1  undef 'bar'\n",
+    'dumpValues worked on array, first element undefined' );
+
+@foobar = ('bar', undef);
+$d->dumpValue([@foobar]);
+is( $out->read, "0..1  'bar' undef\n",
+    'dumpValue worked on array ref, last element undefined' );
+$d->dumpValues(@foobar);
+is( $out->read, "0..1  'bar' undef'bar'\n",
+    'dumpValues worked on array, last element undefined' );
+
+@foobar = ('', 'bar');
+$d->dumpValue([@foobar]);
+is( $out->read, "0..1  '' 'bar'\n",
+    'dumpValue worked on array ref, first element empty string' );
+$d->dumpValues(@foobar);
+is( $out->read, "0..1  '' 'bar'\n",
+    'dumpValues worked on array, first element empty string' );
+
+@foobar = ('bar', '');
+$d->dumpValue([@foobar]);
+is( $out->read, "0..1  'bar' ''\n",
+    'dumpValue worked on array ref, last element empty string' );
+$d->dumpValues(@foobar);
+is( $out->read, "0..1  'bar' ''\n",
+    'dumpValues worked on array, last element empty string' );
+
 # dumpValues (the rest of these should be caught by unwrap)
 $d->dumpValues(undef);
 is( $out->read, "undef\n", 'dumpValues caught undef value fine' );
-- 
2.17.1

@p5pRT
Copy link
Author

p5pRT commented Sep 20, 2019

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

From @jkeenan

On Fri, 20 Sep 2019 03​:09​:32 GMT, jkeenan wrote​:

On Thu, 19 Sep 2019 13​:06​:49 GMT, henrik.pauli@​comnica.com wrote​:

This is a bug report for perl from henrik.pauli@​comnica.com,
generated with the help of perlbug 1.41 running under perl 5.28.2.

Contrary to what the manual claims, the singular and the plural form
don't behave the same when `undef` is involved​:

```perl
use v5.10;
use Dumpvalue;

my $dv = Dumpvalue->new();
my ($x, $y) = (undef, "something");

say "x = " . ($x // "<UNDEF>");
say "y = " . ($y // "<UNDEF>");
say "dumpValues(x, y)​:";
$dv->dumpValues($x, $y);
say "dumpValue([x, y])​:";
$dv->dumpValue([$x, $y]);
```

Output​:
```
x = <UNDEF>
y = something
dumpValues(x, y)​:
undef
dumpValue([x, y])​:
0  undef
1  'something'
```

Expected output​:

Both should say
```
0  undef
1  'something'
```

I believe that the patch attached confirms the bug. It appears that
the methods cannot properly handle undefined values in the array
passed to the dumpValues() method or to the arrayref passed to the
dumpValue() method. These cases were not previously tested.

What the patch produces for test output (attached).

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Oct 6, 2019

From @jkeenan

[perl] 572 $ cd t;./perl harness -v ../dist/Dumpvalue/t/Dumpvalue.t; cd -
../dist/Dumpvalue/t/Dumpvalue.t ..
ok 1 - use Dumpvalue;
ok 2 - create a new Dumpvalue object
...
ok 83 - dumpValue worked
ok 84 - dumpValue worked on array
ok 85 - dumpValue worked on scalar ref
ok 86 - dumpValue worked on array ref
ok 87 - dumpValues worked on array
ok 88 - dumpValues called on array returns same as dumpValue on array ref
not ok 89 - dumpValue worked on array ref, first element undefined

# Failed test 'dumpValue worked on array ref, first element undefined'
# at t/Dumpvalue.t line 286.
# got​: '0..1 '' 'bar'
# '
# expected​: '0..1 undef 'bar'
# '
not ok 90 - dumpValues worked on array, first element undefined

# Failed test 'dumpValues worked on array, first element undefined'
# at t/Dumpvalue.t line 289.
# got​: 'undef
# '
# expected​: '0..1 undef 'bar'
# '
not ok 91 - dumpValue worked on array ref, last element undefined

# Failed test 'dumpValue worked on array ref, last element undefined'
# at t/Dumpvalue.t line 294.
# got​: '0..1 'bar' ''
# '
# expected​: '0..1 'bar' undef
# '
not ok 92 - dumpValues worked on array, last element undefined

# Failed test 'dumpValues worked on array, last element undefined'
# at t/Dumpvalue.t line 297.
# got​: '0..1 'bar' ''
# '
# expected​: '0..1 'bar' undef'bar'
# '
ok 93 - dumpValue worked on array ref, first element empty string
ok 94 - dumpValues worked on array, first element empty string
ok 95 - dumpValue worked on array ref, last element empty string
ok 96 - dumpValues worked on array, last element empty string
ok 97 - dumpValues caught undef value fine
ok 98 - dumpValues worked on array ref
ok 99 - dumpValues worked on multiple values
1..99
# Looks like you failed 4 tests of 99.
Dubious, test returned 4 (wstat 1024, 0x400)
Failed 4/99 subtests

Test Summary Report


../dist/Dumpvalue/t/Dumpvalue.t (Wstat​: 1024 Tests​: 99 Failed​: 4)
  Failed tests​: 89-92
  Non-zero exit status​: 4
Files=1, Tests=99, 0 wallclock secs ( 0.01 usr 0.00 sys + 0.06 cusr 0.01 csys = 0.08 CPU)
Result​: FAIL

@p5pRT
Copy link
Author

p5pRT commented Oct 7, 2019

From @jkeenan

On Sun, 06 Oct 2019 02​:28​:46 GMT, jkeenan wrote​:

On Fri, 20 Sep 2019 03​:09​:32 GMT, jkeenan wrote​:

On Thu, 19 Sep 2019 13​:06​:49 GMT, henrik.pauli@​comnica.com wrote​:

This is a bug report for perl from henrik.pauli@​comnica.com,
generated with the help of perlbug 1.41 running under perl 5.28.2.

Contrary to what the manual claims, the singular and the plural form
don't behave the same when `undef` is involved​:

```perl
use v5.10;
use Dumpvalue;

my $dv = Dumpvalue->new();
my ($x, $y) = (undef, "something");

say "x = " . ($x // "<UNDEF>");
say "y = " . ($y // "<UNDEF>");
say "dumpValues(x, y)​:";
$dv->dumpValues($x, $y);
say "dumpValue([x, y])​:";
$dv->dumpValue([$x, $y]);
```

Output​:
```
x = <UNDEF>
y = something
dumpValues(x, y)​:
undef
dumpValue([x, y])​:
0  undef
1  'something'
```

Expected output​:

Both should say
```
0  undef
1  'something'
```

I believe that the patch attached confirms the bug. It appears that
the methods cannot properly handle undefined values in the array
passed to the dumpValues() method or to the arrayref passed to the
dumpValue() method. These cases were not previously tested.

What the patch produces for test output (attached).

Please review patch attached. I believe I have fixed the bug which generated the original report. This patch is smoking in this branch​:

smoke-me/jkeenan/134441-Dumpvalue

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Oct 7, 2019

From @jkeenan

134441-0001-Handle-undefined-values-correctly.patch
From db372bbb70bf14081d7d17c033c8f9af7c86ebfb Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Thu, 19 Sep 2019 23:02:54 -0400
Subject: [PATCH] Handle undefined values correctly

As reported by Henrik Pauli in RT 134441, the documentation's claim that

        $dv->dumpValue([$x, $y]);

and

        $dv->dumpValues($x, $y);

was not being sustained in the case where one of the elements in the
array (or array ref) was undefined.  This was due to an insufficiently
precise specification within the dumpValues() method for determining
when the value "undef\n" should be printed.

Tests for previously untested cases have been provided in
t/rt-134441-dumpvalue.t.  They were not appended to t/Dumpvalue.t (as
would normally have been the case) because the tests in that file have
accreted over the years in a sub-optimal manner:  changes in attributes
of the Dumpvalue object are tested but those changes are not zeroed-out
(by, e.g., use of 'local $self->{attribute} = undef')
before additional attributes are modified and tested.  As a consequence,
it's difficult to determine the state of the Dumpvalue object at any
particular point and interactions between attributes cannot be ruled
out.

Package TieOut, used to capture STDOUT during testing, has been
extracted to its own file so that it can be used by all test files.
---
 MANIFEST                               |  2 +
 dist/Dumpvalue/lib/Dumpvalue.pm        |  4 +-
 dist/Dumpvalue/t/Dumpvalue.t           | 20 +-----
 dist/Dumpvalue/t/lib/TieOut.pm         | 20 ++++++
 dist/Dumpvalue/t/rt-134441-dumpvalue.t | 86 ++++++++++++++++++++++++++
 5 files changed, 112 insertions(+), 20 deletions(-)
 create mode 100644 dist/Dumpvalue/t/lib/TieOut.pm
 create mode 100644 dist/Dumpvalue/t/rt-134441-dumpvalue.t

diff --git a/MANIFEST b/MANIFEST
index 7bf62d8479..8159ac8cc1 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -3455,6 +3455,8 @@ dist/Devel-SelfStubber/lib/Devel/SelfStubber.pm	Generate stubs for SelfLoader.pm
 dist/Devel-SelfStubber/t/Devel-SelfStubber.t	See if Devel::SelfStubber works
 dist/Dumpvalue/lib/Dumpvalue.pm	Screen dump of perl values
 dist/Dumpvalue/t/Dumpvalue.t	See if Dumpvalue works
+dist/Dumpvalue/t/lib/TieOut.pm	Helper module for Dumpvalue tests
+dist/Dumpvalue/t/rt-134441-dumpvalue.t	See if Dumpvalue works
 dist/encoding-warnings/lib/encoding/warnings.pm	warn on implicit encoding conversions
 dist/encoding-warnings/t/1-warning.t	tests for encoding::warnings
 dist/encoding-warnings/t/2-fatal.t	tests for encoding::warnings
diff --git a/dist/Dumpvalue/lib/Dumpvalue.pm b/dist/Dumpvalue/lib/Dumpvalue.pm
index eef9b27157..3faf829538 100644
--- a/dist/Dumpvalue/lib/Dumpvalue.pm
+++ b/dist/Dumpvalue/lib/Dumpvalue.pm
@@ -1,7 +1,7 @@
 use 5.006_001;			# for (defined ref) and $#$v and our
 package Dumpvalue;
 use strict;
-our $VERSION = '1.18';
+our $VERSION = '1.19';
 our(%address, $stab, @stab, %stab, %subs);
 
 sub ASCII { return ord('A') == 65; }
@@ -79,7 +79,7 @@ sub dumpValues {
   my $self = shift;
   local %address;
   local $^W=0;
-  (print "undef\n"), return unless defined $_[0];
+  (print "undef\n"), return if (@_ == 1 and not defined $_[0]);
   $self->unwrap(\@_,0);
 }
 
diff --git a/dist/Dumpvalue/t/Dumpvalue.t b/dist/Dumpvalue/t/Dumpvalue.t
index 7063dd984c..ba8775126e 100644
--- a/dist/Dumpvalue/t/Dumpvalue.t
+++ b/dist/Dumpvalue/t/Dumpvalue.t
@@ -16,6 +16,8 @@ BEGIN {
 
 our ( $foo, @bar, %baz );
 
+use lib ("./t/lib");
+use TieOut;
 use Test::More tests => 88;
 
 use_ok( 'Dumpvalue' );
@@ -278,21 +280,3 @@ is( $out->read, "0  0..0  'two'\n", 'dumpValues worked on array ref' );
 $d->dumpValues('one', 'two');
 is( $out->read, "0..1  'one' 'two'\n", 'dumpValues worked on multiple values' );
 
-
-package TieOut;
-use overload '"' => sub { "overloaded!" };
-
-sub TIEHANDLE {
-	my $class = shift;
-	bless(\( my $ref), $class);
-}
-
-sub PRINT {
-	my $self = shift;
-	$$self .= join('', @_);
-}
-
-sub read {
-	my $self = shift;
-	return substr($$self, 0, length($$self), '');
-}
diff --git a/dist/Dumpvalue/t/lib/TieOut.pm b/dist/Dumpvalue/t/lib/TieOut.pm
new file mode 100644
index 0000000000..568caedf9c
--- /dev/null
+++ b/dist/Dumpvalue/t/lib/TieOut.pm
@@ -0,0 +1,20 @@
+package TieOut;
+use overload '"' => sub { "overloaded!" };
+
+sub TIEHANDLE {
+	my $class = shift;
+	bless(\( my $ref), $class);
+}
+
+sub PRINT {
+	my $self = shift;
+	$$self .= join('', @_);
+}
+
+sub read {
+	my $self = shift;
+	return substr($$self, 0, length($$self), '');
+}
+
+1;
+
diff --git a/dist/Dumpvalue/t/rt-134441-dumpvalue.t b/dist/Dumpvalue/t/rt-134441-dumpvalue.t
new file mode 100644
index 0000000000..cc9f270f5a
--- /dev/null
+++ b/dist/Dumpvalue/t/rt-134441-dumpvalue.t
@@ -0,0 +1,86 @@
+BEGIN {
+	require Config;
+	if (($Config::Config{'extensions'} !~ m!\bList/Util\b!) ){
+	    print "1..0 # Skip -- Perl configured without List::Util module\n";
+	    exit 0;
+	}
+
+	# `make test` in the CPAN version of this module runs us with -w, but
+	# Dumpvalue.pm relies on all sorts of things that can cause warnings. I
+	# don't think that's worth fixing, so we just turn off all warnings
+	# during testing.
+	$^W = 0;
+}
+
+use lib ("./t/lib");
+use TieOut;
+use Test::More tests => 17;
+
+use_ok( 'Dumpvalue' );
+
+my $d;
+ok( $d = Dumpvalue->new(), 'create a new Dumpvalue object' );
+
+my $out = tie *OUT, 'TieOut';
+select(OUT);
+
+my (@foobar, $x, $y);
+
+@foobar = ('foo', 'bar');
+$d->dumpValue([@foobar]);
+$x = $out->read;
+is( $x, "0  'foo'\n1  'bar'\n", 'dumpValue worked on array ref' );
+$d->dumpValues(@foobar);
+$y = $out->read;
+is( $y, "0  'foo'\n1  'bar'\n", 'dumpValues worked on array' );
+is( $y, $x,
+    "dumpValues called on array returns same as dumpValue on array ref");
+
+@foobar = (undef, 'bar');
+$d->dumpValue([@foobar]);
+$x = $out->read;
+is( $x, "0  undef\n1  'bar'\n",
+    'dumpValue worked on array ref, first element undefined' );
+$d->dumpValues(@foobar);
+$y = $out->read;
+is( $y, "0  undef\n1  'bar'\n",
+    'dumpValues worked on array, first element undefined' );
+is( $y, $x,
+    "dumpValues called on array returns same as dumpValue on array ref, first element undefined");
+
+@foobar = ('bar', undef);
+$d->dumpValue([@foobar]);
+$x = $out->read;
+is( $x, "0  'bar'\n1  undef\n",
+    'dumpValue worked on array ref, last element undefined' );
+$d->dumpValues(@foobar);
+$y = $out->read;
+is( $y, "0  'bar'\n1  undef\n",
+    'dumpValues worked on array, last element undefined' );
+is( $y, $x,
+    "dumpValues called on array returns same as dumpValue on array ref, last element undefined");
+
+@foobar = ('', 'bar');
+$d->dumpValue([@foobar]);
+$x = $out->read;
+is( $x, "0  ''\n1  'bar'\n",
+    'dumpValue worked on array ref, first element empty string' );
+$d->dumpValues(@foobar);
+$y = $out->read;
+is( $y, "0  ''\n1  'bar'\n",
+    'dumpValues worked on array, first element empty string' );
+is( $y, $x,
+    "dumpValues called on array returns same as dumpValue on array ref, first element empty string");
+
+@foobar = ('bar', '');
+$d->dumpValue([@foobar]);
+$x = $out->read;
+is( $x, "0  'bar'\n1  ''\n",
+    'dumpValue worked on array ref, last element empty string' );
+$d->dumpValues(@foobar);
+$y = $out->read;
+is( $y, "0  'bar'\n1  ''\n",
+    'dumpValues worked on array, last element empty string' );
+is( $y, $x,
+    "dumpValues called on array returns same as dumpValue on array ref, last element empty string");
+
-- 
2.17.1

@p5pRT
Copy link
Author

p5pRT commented Oct 9, 2019

From @jkeenan

On Mon, 07 Oct 2019 01​:19​:50 GMT, jkeenan wrote​:

On Sun, 06 Oct 2019 02​:28​:46 GMT, jkeenan wrote​:

On Fri, 20 Sep 2019 03​:09​:32 GMT, jkeenan wrote​:

On Thu, 19 Sep 2019 13​:06​:49 GMT, henrik.pauli@​comnica.com wrote​:

This is a bug report for perl from henrik.pauli@​comnica.com,
generated with the help of perlbug 1.41 running under perl
5.28.2.

Contrary to what the manual claims, the singular and the plural
form
don't behave the same when `undef` is involved​:

```perl
use v5.10;
use Dumpvalue;

my $dv = Dumpvalue->new();
my ($x, $y) = (undef, "something");

say "x = " . ($x // "<UNDEF>");
say "y = " . ($y // "<UNDEF>");
say "dumpValues(x, y)​:";
$dv->dumpValues($x, $y);
say "dumpValue([x, y])​:";
$dv->dumpValue([$x, $y]);
```

Output​:
```
x = <UNDEF>
y = something
dumpValues(x, y)​:
undef
dumpValue([x, y])​:
0  undef
1  'something'
```

Expected output​:

Both should say
```
0  undef
1  'something'
```

I believe that the patch attached confirms the bug. It appears
that
the methods cannot properly handle undefined values in the array
passed to the dumpValues() method or to the arrayref passed to the
dumpValue() method. These cases were not previously tested.

What the patch produces for test output (attached).

Please review patch attached. I believe I have fixed the bug which
generated the original report. This patch is smoking in this branch​:

smoke-me/jkeenan/134441-Dumpvalue

Thank you very much.

Having heard no objection, I merged this branch to blead in commit 01aed38.

I've discovered other problems with Dumpvalue which I'll be reporting in new tickets or on the list. We'll proceed from the commit above.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Oct 11, 2019

@jkeenan - Status changed from 'open' to 'resolved'

@p5pRT
Copy link
Author

p5pRT commented Oct 12, 2019

@jkeenan - Status changed from 'resolved' to 'pending release'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant