Navigation Menu

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

Error assigning to hashref slice when running debug/taint #2127

Closed
p5pRT opened this issue Jun 24, 2000 · 4 comments
Closed

Error assigning to hashref slice when running debug/taint #2127

p5pRT opened this issue Jun 24, 2000 · 4 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 24, 2000

Migrated from rt.perl.org#3420 (status was 'resolved')

Searchable as RT3420$

@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2000

From tuck@whistlingfish.net

Created by tuck@whistlingfish.net

The following code generates an error when running in debug or taint
checking mode​:

  my $foo = {};
  @​{%$foo}{qw(foo bar)} = qw(foo bar);

The error is​:

  Bizarre copy of HASH in leave at /home/tuck/projects/try line 9.

When running without -T or -d enabled, it works fine.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.6.0:

Configured by pixel at Fri Mar 31 16:32:49 CEST 2000.

Summary of my perl5 (revision 5.0 version 6 subversion 0) configuration:
  Platform:
    osname=linux, osvers=2.2.15-0.16mdksmp, archname=i386-linux
    uname='linux kenobi.mandrakesoft.com 2.2.15-0.16mdksmp #1 smp mon mar 13 16:40:10 cet 2000 i686 unknown '
    config_args='-des -Dprefix=/usr -Darchname=i386-linux -Dd_dosuid -Dd_semctl_semun -Di_db -Di_ndbm -Di_gdbm -Ud_csh -Dman3dir=/usr/lib/perl5/man/man3 -Doptimize=-O3 -fomit-frame-pointer -fno-exceptions -fno-rtti -pipe -s -mpentium -mcpu=pentium -march=pentium -ffast-math -fexpensive-optimizations'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=undef d_sfio=undef uselargefiles=define 
    use64bitint=undef use64bitall=undef uselongdouble=undef usesocks=undef
  Compiler:
    cc='cc', optimize='-O3 -fomit-frame-pointer -fno-exceptions -fno-rtti -pipe -s -mpentium -mcpu=pentium -march=pentium -ffast-math -fexpensive-optimizations', gccversion=2.95.3 19991030 (prerelease)
    cppflags='-fno-strict-aliasing'
    ccflags ='-fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
    stdchar='char', d_stdstdio=define, usevfork=false
    intsize=4, longsize=4, ptrsize=4, doublesize=8
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, usemymalloc=n, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lnsl -ldl -lm -lc -lposix -lcrypt
    libc=/lib/libc-2.1.3.so, so=so, useshrplib=false, libperl=libperl.a
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
    cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'

Locally applied patches:
    


@INC for perl v5.6.0:
    /home/tuck/lib
    /usr/lib/perl5/5.6.0/i386-linux
    /usr/lib/perl5/5.6.0
    /usr/lib/perl5/site_perl/5.6.0/i386-linux
    /usr/lib/perl5/site_perl/5.6.0
    /usr/lib/perl5/site_perl/5.005/i386-linux
    /usr/lib/perl5/site_perl/5.005
    /usr/lib/perl5/site_perl
    .


Environment for perl v5.6.0:
    HOME=/home/tuck
    LANG=en
    LANGUAGE=en_US:en
    LC_COLLATE=en
    LC_CTYPE=en
    LC_MESSAGES=en
    LC_MONETARY=en
    LC_NUMERIC=en
    LC_TIME=en
    LD_LIBRARY_PATH=/home/tuck/lib
    LOGDIR (unset)
    PATH=/sbin:/usr/sbin:/usr/local/sbin:/sbin:/usr/sbin:/usr/local/sbin:/usr/bin:/bin:/usr/X11R6/bin:/usr/local/bin:/opt/bin:/usr/X11R6/bin:/usr/games:/home/tuck/bin:/usr/X11R6/bin:/usr/games:/usr/X11R6/bin:/usr/games:/home/tuck/bin
    PERL5LIB=/home/tuck/lib
    PERL_BADLANG (unset)
    SHELL=/bin/bash


@p5pRT
Copy link
Author

p5pRT commented Jun 24, 2000

From @mjdominus

my $foo = \{\};
@​\{%$foo\}\{qw\(foo bar\)\} = qw\(foo bar\);

Bizarre copy of HASH in leave at /home/tuck/projects/try line 9\.

Thanks. Although Perl shouldn't generate that error, and it is
actually a bug, your code is also incorrect. I suspect you meant to
say

  @​{$foo}{qw(foo bar)} = qw(foo bar);

instead.

@p5pRT
Copy link
Author

p5pRT commented Jun 27, 2000

From [Unknown Contact. See original ticket]

-- Mark-Jason Dominus <mjd@​plover.com> spake thusly​:

my $foo = \{\};
@&#8203;\{%$foo\}\{qw\(foo bar\)\} = qw\(foo bar\);

Bizarre copy of HASH in leave at /home/tuck/projects/try line 9\.

Thanks. Although Perl shouldn't generate that error, and it is
actually a bug, your code is also incorrect. I suspect you meant to
say

    @&#8203;\{$foo\}\{qw\(foo bar\)\} = qw\(foo bar\);

instead.

Interesting. When I was trying to figure out how to do the equivalent
of @​foo{qw(foo bar)} when dealing with hashrefs, I came up with that
syntax. Since it works (except, obviously, in taint/debug mode) it
never occurred to me that it might not be correct.

Thanks for setting me straight.

- Matt

@p5pRT
Copy link
Author

p5pRT commented May 5, 2003

From @iabyn

(Just reviewing ancient bugs).

This bug report can be reduced to​:

$ perl -T -e '@​{%h}{x}'
Bizarre copy of HASH in leave at -e line 1.

and is still current in bleedperl@​19374.

The problem is best explained by comparison to

$ perl -T -e '@​{%h}'

which works okay. In this latter case, the enter/leave block that
evaluates {%h} 'collapses' %h into the usual "2/8" type scalar, ie the
code evaluates as @​{"2/8"}. In the former case, %h isn't flattened,
and when leave tries to make a mortal copy of what's on the stack (in case
things get freed during the leave), you get the "Bizarre copy" error.

This difference is due to the fact that the rv2hv op that pushes %h on the
stack, has the OPf_REF flag set in the buggy case, and so doesn't collapse
the hash.

The flag is set because @​{%h}{'x'} is initially parsed as @​{%h}, but when
the parser sees the second '{', it calls oopsHV() to convert the rv2av op
into an rv2hv and hsplice ops​:

term​: ary '{' expr ';' '}' /* @​hash{@​keys} */
  { $$ = prepend_elem(OP_HSLICE,
  newOP(OP_PUSHMARK, 0),
  newLISTOP(OP_HSLICE, 0,
  list($3),
  ref(oopsHV($1), OP_HSLICE)));

Since oopsHV both calls and is called by Perl_ref(), this causes the
last rv2hv op in the inner block to get its OPf_REF flag set.

The bug only appears in taint mode (or with -d), since otherwise the
enter/leave op is replaced with a scope op, which doesn't feel the need
to make mortal copies.

No, I don't know how to fix this.

Dave.

--
"But Sidley Park is already a picture, and a most amiable picture too.
The slopes are green and gentle. The trees are companionably grouped at
intervals that show them to advantage. The rill is a serpentine ribbon
unwound from the lake peaceably contained by meadows on which the right
amount of sheep are tastefully arranged." Lady Croom - Arcadia

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

No branches or pull requests

1 participant