Re: Apparent bugs in various things

Spider Boardman (spider@web.zk3.dec.com)
Fri, 21 Mar 1997 11:30:51 -0500


>>>>> On 21 Mar 1997 10:01:01 +0100, Gisle Aas <aas@bergen.sn.no> said:

Gisle> Spider Boardman <spider@web.zk3.dec.com> writes:
> The problem with having it barf on the LVALUE ref is caused by
> passing a constant SV as a subroutine argument.  *That*, at least,
> can be fixed by the following:
> 
> --- HTTP/Message.pm.~1~	Mon Nov 25 10:00:52 1996
> +++ HTTP/Message.pm	Fri Mar 21 02:26:01 1997
> @@ -42,7 +42,7 @@
>      } else {
>  	$header = new HTTP::Headers;
>      }
> -    $content = '' unless defined $content;
> +    $content ||= '';

Gisle> This would also change "0" into "" which is bad.  Can you
Gisle> try to explain once more what the problem is?

Sigh.  That's what I get for posting at such an hour of the
night.  The "unless defined $content" was supposed to stay on the
changed line.  Anyway, the problem is that the line as it's
distributed assigns a value with SvREADONLY true if the incoming
content was undefined.  This means that when it's later passed
around, in order to avoid "Can't modify read-only value" errors,
it gets passed with a type of SVt_PVLV, which makes a ref to it
have a "ref" of "LVALUE".  It's done that way so that when it's
assigned to the previous (readonly) SV can be dropped, and a new
one used for the assignment.  Basically, this is a form of lazy
evaluation with respect to the need to copy the constant PV which
was assigned.

It would also be possible to "fix" the observed failure by the
following (but see below):

--- LWP/Protocol/ftp.pm.~1~	Thu Jan 23 16:39:00 1997
+++ LWP/Protocol/ftp.pm	Fri Mar 21 11:04:37 1997
@@ -228,7 +228,7 @@
 	    my $content = $request->content;
 	    my $bytes = 0;
 	    if (defined $content) {
-		if (ref($content) eq 'SCALAR') {
+		if (ref($content) eq 'SCALAR' or ref($content) eq 'LVALUE') {
 		    $bytes = $data->write($$content, length($$content));
 		} elsif (ref($content) eq 'CODE') {
 		    my($buf, $n);
--- LWP/Protocol/http.pm.~1~	Wed Jan 29 08:05:48 1997
+++ LWP/Protocol/http.pm	Fri Mar 21 11:03:54 1997
@@ -88,7 +88,7 @@
     my $contRef;
     if (defined $content){
 	$contRef = ref($content) ? $content : \$content;
-	if (ref($contRef) eq 'SCALAR') {
+	if (ref($contRef) eq 'SCALAR' or ref($contRef) eq 'LVALUE') {
 	    $request->header('Content-Length', length $$contRef)
 	      if length $$contRef;
 	} elsif (ref($contRef) eq 'CODE') {
--- LWP/Protocol/mailto.pm.~1~	Mon Nov 25 10:01:01 1996
+++ LWP/Protocol/mailto.pm	Fri Mar 21 11:05:14 1997
@@ -64,7 +64,7 @@
     my $content = $request->content;
     if (defined $content) {
 	my $contRef = ref($content) ? $content : \$content;
-	if (ref($contRef) eq 'SCALAR') {
+	if (ref($contRef) eq 'SCALAR' or ref($contRef) eq 'LVALUE') {
 	    print SENDMAIL $$contRef;
 	} elsif (ref($contRef) eq 'CODE') {
 	    # Callback provides data


The problem with the above is that there's no guarantee that the
lvalue is for a string.  That's how it tends to work these days,
but it's not guaranteed.  In particular, an XSUB could be using
it for almost any kind of assignable magic.  Still, we're not
assigning to it, we're only reading from it, so this _should_ be
OK.  I'm probably just being paranoid again.

-- 
Spider Boardman, ZKO3-3/U14			IP: spider@zk3.dec.com
110 Spit Brook Road
Nashua NH 03062-2642	USA