Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.96k stars 555 forks source link

Possible bug in logical OR #8854

Closed p5pRT closed 17 years ago

p5pRT commented 17 years ago

Migrated from rt.perl.org#42168 (status was 'rejected')

Searchable as RT42168$

p5pRT commented 17 years ago

From karl-boyken@uiowa.edu

This is a bug report for perl from karl-boyken@​uiowa.edu\, generated with the help of perlbug 1.35 running under perl v5.8.5.

The logical or operators '||' and 'or' do not behave identically when used between an assignment statement and the 'last' operator. In the example program\, below\, the following lines do not behave identically when 'or' is changed to '||'​:

  my($resp) = $results->control( LDAP_CONTROL_PAGED ) or last;   $cookie = $resp->cookie or last;

When 'or' is used\, the program functions as expected\, with no errors or warnings. When '||' is used\, the program terminates with the following error message​:

Can't call method "cookie" without a package or object reference at ./foo4 line 62\, \ line 403.

I the assignment to $resp is wrapped in parantheses\, the program behaves correctly​:

  (my($resp) = $results->control( LDAP_CONTROL_PAGED )) || last;   $cookie = $resp->cookie or last;

I've appended the example program. I've tried the program on the following platforms\, with identical results​:

  Perl 5.8.8\, built from source on RedHat Linux AS release 4   Perl 5.8.3\, built from source on HP-UX 11.23

Karl Boyken\, system administrator Department of Computer Science\, The University of Iowa Iowa City\, IA 52242 karl-boyken@​uiowa.edu 319-335-2730

Example program​:

#!/local/pkg/perl/=/bin/perl -w

use strict;

use English; use Net​::LDAP; use Net​::LDAP​::Control​::Paged; use Net​::LDAP​::Constant qw( LDAP_CONTROL_PAGED );

my($ad) = Net​::LDAP->new(   '**********************'\,   port => 389\,   version => 3   ); my($connect_error) = $EVAL_ERROR; if ($connect_error || (! defined($ad))) {   die "new failed​: " . $connect_error . "\n"; }

my($mesg) = $ad->start_tls(   verify => 'require'\,   sslversion => 'tlsv1'\,   cafile => '/etc/openldap/cacerts/csgadcert.pem'   ); if ($mesg->code()) {   die "start_tls failed​: " . $mesg->code() . "\n"; }

$mesg = $ad->bind(   'CN=*********\,CN=users\,DC=divms\,DC=uiowa\,DC=edu'\,   password =>'********';   ); if ( $mesg->code) {   die("ADS is_user​: bind failed\n"); }

my($searchbase) = "OU=people\,DC=divms\,DC=uiowa\,DC=edu"; my($filter) = "sAMAccountname=*"; my($attrs) = 'sAMAccountname';

my($page) = Net​::LDAP​::Control​::Paged->new( size => 400 ); my($cookie) = ""; my($sam) = ""; my($attr) = ""; my($entry) = "";

while (1) {   my($results) = $ad->search(   base => $searchbase\,   filter => $filter\,   attrs => [$attrs]\,   control => $page\,   );   foreach $entry ($results->all_entries()) {   foreach $attr ($entry->attributes()) {   $sam = $entry->get_value($attr);   print "$sam\n";   }   } # my($resp) = $results->control( LDAP_CONTROL_PAGED ) or last;   my($resp) = $results->control( LDAP_CONTROL_PAGED ) || last;   $cookie = $resp->cookie or last;   $page->cookie($cookie); }

if ($cookie) {   $page->cookie($cookie);   $page->size(0);   my($mesg) = $ad->search(   base => $searchbase\,   filter => $filter\,   attrs => [$attrs]\,   control => $page\,   );   foreach $entry ($mesg->all_entries()) {   foreach $attr ($entry->attributes()) {   $sam = $entry->get_value($attr);   print "$sam\n";   }   } }


Flags​:   category=core   severity=low


This perlbug was built using Perl v5.8.5 in the Red Hat build system. It is being executed now by Perl v5.8.5 - Mon Jul 24 18​:27​:33 EDT 2006.

Site configuration information for perl v5.8.5​:

Configured by Red Hat\, Inc. at Mon Jul 24 18​:27​:33 EDT 2006.

Summary of my perl5 (revision 5 version 8 subversion 5) configuration​:   Platform​:   osname=linux\, osvers=2.6.9-22.18.bz155725.elsmp\, archname=x86_64-linux-thread-multi   uname='linux hs20-bc1-3.build.redhat.com 2.6.9-22.18.bz155725.elsmp #1 smp thu nov 17 15​:34​:08 est 2005 x86_64 x86_64 x86_64 gnulinux '   config_args='-des -Doptimize=-O2 -g -pipe -m64 -Dversion=5.8.5 -Dmyhostname=localhost -Dperladmin=root@​localhost -Dcc=gcc -Dcf_by=Red Hat\, Inc. -Dinstallprefix=/usr -Dprefix=/usr -Dlibpth=/usr/local/lib64 /lib64 /usr/lib64 -Dprivlib=/usr/lib/perl5/5.8.5 -Dsitelib=/usr/lib/perl5/site_perl/5.8.5 -Dvendorlib=/usr/lib/perl5/vendor_perl/5.8.5 -Darchlib=/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi -Dsitearch=/usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi -Dvendorarch=/usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi -Darchname=x86_64-linux -Dvendorprefix=/usr -Dsiteprefix=/usr -Duseshrplib -Dusethreads -Duseithreads -Duselargefiles -Dd_dosuid -Dd_semctl_semun -Di_db -Ui_ndbm -Di_gdbm -Di_shadow -Di_syslog -Dman3ext=3pm -Duseperlio -Dinstallusrbinperl -Ubincompat5005 -Uversiononly -Dpager=/usr/bin/less -isr -Dinc_version_list=5.8.4 5.8.3 5.8.2 5.8.1 5.8.0'   hint=recommended\, useposix=true\, d_sigaction=define   usethreads=define use5005threads=undef useithreads=define usemultiplicity=define   useperlio=define d_sfio=undef uselargefiles=define usesocks=undef   use64bitint=define use64bitall=define uselongdouble=undef   usemymalloc=n\, bincompat5005=undef   Compiler​:   cc='gcc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm'\,   optimize='-O2 -g -pipe -m64'\,   cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -I/usr/local/include -I/usr/include/gdbm'   ccversion=''\, gccversion='3.4.6 20060404 (Red Hat 3.4.6-2)'\, gccosandvers=''   intsize=4\, longsize=8\, ptrsize=8\, doublesize=8\, byteorder=12345678   d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=16   ivtype='long'\, ivsize=8\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8   alignbytes=8\, prototype=define   Linker and Libraries​:   ld='gcc'\, ldflags =''   libpth=/usr/local/lib64 /lib64 /usr/lib64   libs=-lresolv -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc   perllibs=-lresolv -lnsl -ldl -lm -lcrypt -lutil -lpthread -lc   libc=/lib/libc-2.3.3.so\, so=so\, useshrplib=true\, libperl=libperl.so   gnulibc_version='2.3.4'   Dynamic Linking​:   dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E -Wl\,-rpath\,/usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi/CORE'   cccdlflags='-fPIC'\, lddlflags='-shared'

Locally applied patches​:  


@​INC for perl v5.8.5​:   /usr/lib64/perl5/5.8.5/x86_64-linux-thread-multi   /usr/lib/perl5/5.8.5   /usr/lib64/perl5/site_perl/5.8.5/x86_64-linux-thread-multi   /usr/lib64/perl5/site_perl/5.8.4/x86_64-linux-thread-multi   /usr/lib64/perl5/site_perl/5.8.3/x86_64-linux-thread-multi   /usr/lib64/perl5/site_perl/5.8.2/x86_64-linux-thread-multi   /usr/lib64/perl5/site_perl/5.8.1/x86_64-linux-thread-multi   /usr/lib64/perl5/site_perl/5.8.0/x86_64-linux-thread-multi   /usr/lib/perl5/site_perl/5.8.5   /usr/lib/perl5/site_perl/5.8.4   /usr/lib/perl5/site_perl/5.8.3   /usr/lib/perl5/site_perl/5.8.2   /usr/lib/perl5/site_perl/5.8.1   /usr/lib/perl5/site_perl/5.8.0   /usr/lib/perl5/site_perl   /usr/lib64/perl5/vendor_perl/5.8.5/x86_64-linux-thread-multi   /usr/lib64/perl5/vendor_perl/5.8.4/x86_64-linux-thread-multi   /usr/lib64/perl5/vendor_perl/5.8.3/x86_64-linux-thread-multi   /usr/lib64/perl5/vendor_perl/5.8.2/x86_64-linux-thread-multi   /usr/lib64/perl5/vendor_perl/5.8.1/x86_64-linux-thread-multi   /usr/lib64/perl5/vendor_perl/5.8.0/x86_64-linux-thread-multi   /usr/lib/perl5/vendor_perl/5.8.5   /usr/lib/perl5/vendor_perl/5.8.4   /usr/lib/perl5/vendor_perl/5.8.3   /usr/lib/perl5/vendor_perl/5.8.2   /usr/lib/perl5/vendor_perl/5.8.1   /usr/lib/perl5/vendor_perl/5.8.0   /usr/lib/perl5/vendor_perl   .


Environment for perl v5.8.5​:   HOME=/space/boyken   LANG=en_US.UTF-8   LANGUAGE (unset)   LD_LIBRARY_PATH=/space/boyken/lib/Linux​:/opt/intel_fc_x86_64/lib   LOGDIR (unset)   PATH=/space/boyken/script​:/space/boyken/script​:/usr/kerberos/bin​:/usr/local/bin​:/usr/bin​:/bin​:/usr/X11R6/bin​:/usr/divms/bin​:/opt/intel_cc_x86_64/bin​:/opt/intel_fc_x86_64/bin​:/opt/intel_idb_x86_64/bin​:/space/boyken/bin/Linux​:/usr/sbin​:/opt/intel_cc_x86_64/bin​:/opt/intel_fc_x86_64/bin​:/opt/intel_idb_x86_64/bin​:/space/boyken/bin/Linux​:/usr/sbin   PERL_BADLANG (unset)   SHELL=/bin/tcsh

p5pRT commented 17 years ago

From boyken@divms.uiowa.edu

Never mind; I re-read the Perl book. Sorry to bother you. Please trashcan my report.

Karl Boyken

-- Karl Boyken\, system administrator karl-boyken@​uiowa.edu 303A MLH\, Dept. of Comp. Sci. http​://www.cs.uiowa.edu/~boyken/ The U. of Iowa\, Iowa City\, IA 52242 319-335-2730 (voice) 319-335-3668 (fax)

p5pRT commented 17 years ago

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

p5pRT commented 17 years ago

@rgs - Status changed from 'open' to 'rejected'

p5pRT commented 17 years ago

From @demerphq

On 3/29/07\, via RT karl-boyken @​ uiowa. edu \perlbug\-followup@​perl\.org wrote​:

# New Ticket Created by karl-boyken@​uiowa.edu # Please include the string​: [perl #42168] # in the subject line of all future correspondence about this issue. # \<URL​: http​://rt.perl.org/rt3/Ticket/Display.html?id=42168 >

This is a bug report for perl from karl-boyken@​uiowa.edu\, generated with the help of perlbug 1.35 running under perl v5.8.5.

The logical or operators '||' and 'or' do not behave identically when used between an assignment statement and the 'last' operator. In the example program\, below\, the following lines do not behave identically when 'or' is changed to '||'​:

my($resp) = $results->control( LDAP_CONTROL_PAGED ) or last; $cookie = $resp->cookie or last;

When 'or' is used\, the program functions as expected\, with no errors or warnings. When '||' is used\, the program terminates with the following error message​:

Can't call method "cookie" without a package or object reference at ./foo4 line 62\, \ line 403.

I the assignment to $resp is wrapped in parantheses\, the program behaves correctly​:

(my($resp) = $results->control( LDAP_CONTROL_PAGED )) || last; $cookie = $resp->cookie or last;

Which should have suggested a precedence issue is at work and that this isnt a bug.

'||' has higher precedence than '=' but 'or' does not. In fact by design 'or' has the lowest precedence of all operators. Therefore

  a = b || c;

is equivelent to

  a = ( b || c);

but

  a = b or c;

is equivelent to

  ( a = b ) or c;

Incidentally the low precedence is intentional as it allows 'or' to be used as a control flow keyword in situations like​:

  $res = func($arg)   or die "Bad response from func($arg)";

Cheers Yves ps​: I recommend that you double check any issues like this that you have on www.perlmonks.org before filing a bug report. The people there are generally very friendly and helpful and most importantly quite fast in replying to questions. Certainly you would have got to the bottom of this one in much less time than filing a bug report.

-- perl -Mre=debug -e "/just|another|perl|hacker/"