Errata

CGI Programming with Perl

Errata for CGI Programming with Perl

Submit your own errata for this product.

The errata list is a list of errors and their corrections that were found after the product was released.

The following errata were submitted by our customers and have not yet been approved or disproved by the author or editor. They solely represent the opinion of the customer.

Color Key: Serious technical mistake Minor technical mistake Language or formatting error Typo Question Note Update

Version Location Description Submitted by Date submitted
Printed Page 20
URI Encoding (line 32 from the top)

My question is about the sentence below:

The following characters: - _ . ! ~ * ' ( )

In the book, tilde "~" is said to be an exception for URL encoding, but
according to RFC1738 (Uniform Resource Locators) section 2.2, tilde should be
encoded.

Anonymous   
Printed Page 21
both code fragments

The s///; command in both of the code fragments on this page should include a
/g option.

Anonymous   
Printed Page 29
Table 2-2

The header named "Authentication" in the table should actually read
"Authorization". This is according to both the text (see the bottom of page
29) and RFC 2616.

Anonymous   
Printed Page 32
paragraph 2

"A example" should be "An example"; "protocol are" should be "protocol is".

Anonymous   
Printed Page 35
paragraph 1

"differs for the Web than" should be "are different for the Web than".
(However the phrase "different than" is almost never correct. "Different from" should be used.)

Anonymous   
Printed Page 50
1st paragraph

It says, "The first foreach loop iterates over %ENV to add any additional
environment variables defined by the current web server. Then the foreach
loop iterates through the combined list and displays the name, description,
and value of each environment variable."

This is confusing... the 2nd sentence should specify that it is the
_second_ foreach loop.

Anonymous   
Printed Page 60
Example 3-4

(last line on this page) spurious ";" between"`binmode" and "STDOUT;"

Anonymous   
Printed Page 63
Example 3-5

spurious ";" between "binmode" and "STDOUT;"

Anonymous   
Printed Page 64
Second paragraph, I guess - I'm reading from an html book

When the author says:

"If you are especially paranoid (and do not mind the extra traffic it causes), then
you could also output a Pragma: no-cache header for the real images too."

He is considering the example script 3-5 wasn't printing the mentioned pragma for the
real images, but, actually, the script does output the pragma for the real images too
- this happens because the "display_image()" subroutine prints that pragma for any
image file it prints out.

So, this paragraph doesn't make sense.

Anonymous   
Printed Page 95

... to change CGI.pm's behavior ro allow access to all
parameters via param...

I think "ro" should become "to."

Anonymous   
Printed Page 95
2nd paragraph

Missing period/full stop at end of paragraph

Anonymous   
Printed Page 96
after the 6th paragraph

The book indicates that "If you wish to print the value of someone's input,
you can use an intermediate variable:"

The code that follows is incorrect:

my $name = $q->param( 'user' );
print "Hi, $user!";

The proper code should read:

my $name = $q->param( 'user' );
print "Hi, $name!";

The code as written gives you this error:

Global symbol "$user" requires explicit package name

Anonymous   
Printed Page 98
next-to-last line:

my $fh = $q->upload( $file );

On Win32 systems (I'm not sure about Unix) it appears that the "upload" method
should be passed the name of the "upload field" from the HTML form (which in
this case is "file") rather than the path and name of the file itself ($file).

From the CGI documentation:

--------------------------------------------------------------------
When the form is processed, you can retrieve the entered filename by
calling param():

$filename = $query->param('uploaded_file');

... (some stuff snipped out) ...

To be safe, use the *upload()* function (new in version 2.47). When
called with the name of an upload field, *upload()* returns a
filehandle, or undef if the parameter is not a valid filehandle.

$fh = $query->upload('uploaded_file');
while (<$fh>) {
print;
}

Anonymous   
Printed Page 98
(minor, because it still kind of works as is)

middle of page 98, HTML snippet that begins...
<FORM ACTION="/cgi/upload.cgi....
.(2)
.(3)
.(4)
.(5)
</FORM>

to be consistent with the previous HTML sample on page 97, it would seem
that after line 5, before "</FORM>", you should include:
<INPUT TYPE="SUBMIT">
which will create a submit button for this form. A submit button does not
show up when the HTML snippet is used as is (but by pressing return on the
keyboard, one can get the form submitted).

Anonymous   
Printed Page 98,99
Last line on 98; next to last line on 99

On both 98 and 99,

my $fh = $q->upload( $file );

should be

my $fh = $q->upload( "file" );

In the first paragraph on 99:

"Be sure that you pass upload the name of the
file according to param, and not a different name..."

would be more clear as:

"Be sure the name that you pass upload is the same name
you would pass to param, and not a different name..."

As it is, it makes it sound like you are passing the name returned from
param, which is wrong (but it matches the code samples, which makes it even
more confusing.

Anonymous   
Printed Page 98-99
Bottom

Comfirmation that on Unix, Mac OS X and Mac OS that the argument to upload should
be the name of the param not the name of the file.

Anonymous   
Printed Page 99
Example 5-2 4th line of text

the line
use constant UPLOAD_DIR => "/usr/local/apache/data/uploads";
needs a trailing slash for it to work.

At least on Mac OS X, the example given does not let the process get through to a directory.

Anonymous   
Printed Page 99
bottom of page

Perl example 5-2: upload.cgi

the 2nd to last line reads:
my $fh = $q->upload( $file );

When typed in as written, the example did not work on my computer. So I
looked through the CGI.pm file, and came across a section which seemed to
suggest that the line should in fact read:

my $fh = $q->upload( "file" );

Anonymous   
Printed Page 100
middle of page

Perl example 5-2: upload.cgi
The section that begins...
# Open output file, making sure the name is unique
until ( sysopen... {
..
..
}

I'm not a Perl expert, so I don't know why that section didn't work, but I
had to comment that out and replace it with a simpler snippet:

#### OPEN OUTPUT FILE
open (OUTPUT, ">" . UPLOAD_DIR . "/" . $filename)
or print "Hey...can't open file UPLOAD_DIR/$filename: $!
";

Those two changes finally enabled the perl script to run without errors (on
my computer at least).

Anonymous   
Printed Page 100
example 5.2, upload.cgi

The regular expression to open a unique output file only works if the
user-supplied filename contains an extension separated by a period. If
this is not the case, the regex fails, a large amount of garbage is
printed to the error log, and the connection eventually times out.

The solution is to fix the regex on line 31 of the program so that it
validates the filename correctly, and adds an extension if one is
necessary. For example:

if ( $filename =~ /^(w[w-]*)(.[w.-]+)?/ ) {
$filename = $1 . ($2 || '.err');
}

Text description:

From the start of the line, ensure that there is a string that starts
with a word character and is continued by word characters or hyphens.

This may, but need not be, followed by a period, followed by one or more
characters that can be either word characters, periods, or hyphens (to
accommodate things like foo.tar.gz).

The filename is the part before the extension concatenated either with the
part after the extension (if present) or the string '.err' (if not
present).
<<

The user errata at the book web site indicate that others have had
problems with this, but the proposed solution is to delete the code and
replace it with a much simpler file check that does not have nearly as
much error handling. The above solution preserves this error handling and
should be universally applicable (it even works if the filename ends in a
period).

Anonymous   
Printed Page 101
near end of code example 5-2

'procesed' should be 'processed'

'occured' should be 'occurred'

These spelling mistakes are also present in the downloadable source code.

Anonymous   
Printed Page 105
start_html <BODY> tag

This would seem to preclude the use of frames with CGI.pm start_html because
FRAMESET is allergic to BODY tags. It must be possible since at the bottom of
p 104 the -target argument is discussed.

Is it possible for CGI.pm to redraw just one frame? My current cgi redraws
all the frames even though only one changes.

Anonymous   
Printed Page 110
line 15

-name => "curtain"
should be:
-name => "look_behind"
because lines 21 - 23 have: NAME="look_behind"

Anonymous   
Printed Page 119
1st paragraph

"name of module" should be "name of the module"

Anonymous   
Printed Page 134
Table 6-4;

The last attribute in the table is listed as:

NAME="/file/path"

It should be:

NAME="/path/file"

Anonymous   
Printed Page 140
3rd paragraph

"the model ... often end up" should be "the model ... often ends up"

Anonymous   
Printed Page 141
paragraph 1

"this works similar" should be "this works similarly".

Anonymous   
Printed Page 142
embpcgi.pl

you can also use the embpcgi.pl CGI script that is
distributed with Embperl.

"embpcgi.pl" is no longer included in the current Embperl distributions (1.3.x
and later) on CPAN. I believe the last version that it can be found in is
1.2.1.

Anonymous   
Printed Page 150-161
all of the embperl news page examples

In your example of EMBPerl, there appears to be an issue with the edit
function. Although it will work fine if run form the embpcgi.pl, editing a
story will not work at all while running in mod_perl, as it is currently
written. When the story is read, a shared lock is placed on the file, as
mod_perl does not terminate, like the cgi script, this lock is maintained and
will not allow you to write to the file. This results in no editability unless
the cgi is used...Obviously, a poor choice if mod_perl is an option. The
approach I would take is to add a cleanup sub to unlock the file for editing,
run every time the page is compleatly loaded...or at least from talking to
people this would seam to be the solution (mod_perl EMBPerl newsgroup).

Oh, just in case I am wrong...The reason that the lock came to mind was I
reset apache (and subsiquently mod_perl) and then saved after going to the
edit_article.epl?, and then it worked.

Anonymous   
Printed Page 158
code above HTML header

The code for the if-then statement should be swapped:

if ( $fdat{story} ) {
( $fdat{headline}, $fdat{article} ) =
News::get_story( $fdat{story} );
}
elsif ( $fdat{save} ) {
News::save_story( $fdat{story}, $fdat{headline},
$fdat{article} );
$http_headers_out{Location} = "edit_news.epl";
exit;
}

should be:

if ( $fdat{save} ) {
News::save_story( $fdat{story}, $fdat{headline},
$fdat{article} );
$http_headers_out{Location} = "edit_news.epl";
exit;
}
elsif ( $fdat{story} ) {
( $fdat{headline}, $fdat{article} ) =
News::get_story( $fdat{story} );
}

The way it is now, "$fdat{story}" will always match, even after you've pressed
the "submit" button. The check for "$fdat{save}" should come first because
that will only match if you click the "submit" button. As it is, you never
get redirected back to the "edit_news.epl" page.

Anonymous   
Printed Page 172
Function requireValues

The requireValues function names its two arguments "form" and "requiredValues"
in the definition. However, the second line of the function reads:

element = requiredText[i];

It should be:

element = requiredValues[i];

Either that or the "requiredValues" argument should have been named
"requiredText."

Anonymous   
Printed Page 172
paragraph 4

"may be supported" should be "may not be supported".

Anonymous   
Printed Page 175
3rd paragraph, line 9

It says, "As we mentioned earlier, JavaScript may be supported by the
user's browser or it may be turned off."

It should say, "As we mentioned earlier, JavaScript may not be supported by
the user's browser..."

Anonymous   
Printed Page 176
2nd line

It says, "...because the it doesn't know..."

"the" should be removed

Anonymous   
Printed Page 176
3rd line from bottom

"makes" should be "makers".

Anonymous   
Printed Page 184
4th paragraph, after code

It says, "...the value of the concert field is added it to the concertList
select list."

"it" should be removed.

Anonymous   
Printed Page 185
2nd paragraph, line 3

period missing at end of sentence: "...value of the filename field If no
song..."

Anonymous   
Printed Page 188
paragraph 3

"convert to this to" should be "convert this to".

Anonymous   
Printed Page 189
last paragraph, 2nd to last line

"...which users you are willing to loose."

"loose" should be "lose"

Anonymous   
Printed Page 190
4th from last line

$q->textarea(........... -value => $comment ),

should be:

$q->textarea(........... -default => $comment ),

because textarea has no value property (per pg. 79).

Anonymous   
Printed Page 201
2nd paragraph in "Trusting the Browser", 2nd-3rd line

it says, "...each page calls the same CGI script to processes the transaction."

"processes" should be "process"

Anonymous   
Printed Page 201
second line

a dollar sign is missing: FIGLET is a bareword,
should be the scalar variable $FIGLET

Anonymous   
Printed Page 202
last paragraph, line 3

"Hypertext Transport Protocol"

the chapter was changed to "Hypertext Transfer Protocol"

Anonymous   
Printed Page 204
1st paragraph under "Encryption", line 4

It says, "A secure https connections using SSL..."

"connections" should be "connection"

Anonymous   
Printed Page 207
1st paragraph after code, line 3

It says, "Because our examples this chapter intentionally showed..."

It should say, "Because our examples in this chapter..."

Anonymous   
Printed Page 207
2nd paragraph, 1st sentence

It says, "The purpose of taint mode is to not allow any data from outside
your application from affecting anything else external to your application."

It should say, "The purpose of taint mode is to not allow any data from
outside your application to affect anything else external to your
application."

**OR** "The purpose of taint mode is to keep any data from outside your
application from affecting anything else external to your application."

Anonymous   
Printed Page 216
paragraph 1

"None of us like spam" should be "None of us likes spam".

Anonymous   
Printed Page 222
paragraph 1

"sender to be that" doesn't make sense.

Anonymous   
Printed Page 223
Example 9.1

The instruction that starts

$q->p( "The email address ou entered .....");

should read

$q->p( "The email address ou entered ....."),

so the next instruction can be printed ($q->end_html).

Anonymous   
Printed Page 225
paragraph 3

"... the web server runs as has ..." doesn't make sense.

Anonymous   
Printed Page 226
two lines of Perl code in "mailx and mail" section

The code appears exactly as printed in the next 2 lines:
open MAIL "|-" or exec( "/bin/mail", $email ) or
die "Cannot exec mail $!";

First, there should be a common between MAIL and "|-"

More importantly, although the text states that this code
uses the "fork and exec" trick, there is no explicit call
to fork (although the OPEN does implicitly call fork)

The exec will only take place if the open fails!

Anonymous   
Printed Page 227
3rd paragraph (code)

close $mailer

should be:

$mailer->close;

Anonymous   
Printed Page 240
example 10-3. line 17

if ( exists $dbm_hash{$username} ) {
$email = $q->a( { href => "mailto:$dbm_hash{$username}" },
$dbm_hash{$user_name} );

"$user_name" should be "$username"

Anonymous   
Printed Page 243
code:

$mary{email} = 'mary..'; #...

should read

$mary->{email} = 'mary..'; #...

Anonymous   
Printed Page 248
connect statement at bottom of page

According to the accompanying text, the name of the driver
in the connect() call should be DBD:CSV, not DBI:CSV

Anonymous   
Printed Page 256
The getQueryResults subroutine at the end of page 256 to page 257

The query's don't actually return anything. I am unable to figure this out as I am
using the book to teach myself CGI programming. If you do a query without filling in
the fields of the query screen, it returns every entry in the database. If you put
anything in the fields, including exact matches, it returns nothing. I typed the
entire script from the book and when this problem occurred I downloaded the script
from your website (Under Chapter 10 9781565924192_examples.tar.gz) and it behaves the same
way. I compared the downloaded version to your book and it is the same.

Anonymous   
Printed Page 257
half way down page in else of $where_clause

You are using the "like" predicate in the where clause, but you should be
using the "clike" to do case-insensitive matching.

like does case-sensitive matching (at least in the latest SQL::Statement perl
module).

Anonymous   
Printed Page 259-260
map functions

The use of map(... " = ""
... """
on pg 259, and twice on pg 260 do not work for SQL code.

You should be using single quotes around where logic literals, as it was done on pg
258 in the doAdd subroutine, using

"push(@value_array, "'" . $value . "'");

Anonymous   
Printed Page 264
1st paragraph, 1st line

"Chapter 2, The Hypertext Transport Protocol, ..."

"Transport" was changed to "Transfer" in chapter name.

Anonymous   
Printed Page 294
Example 12-1, 15th line

my $DOCUMENT_ROOT = $ENV{DOCUMENT_ROOT};

should be changed to:

my( $DOCUMENT_ROOT ) = $ENV{DOCUMENT_ROOT} =~ /^([w:/\-]+)$/
or die "Unsafe document root!";

There is a syntax error in the reg expression. It should be something like:

m|^([w:/\-]+)$|

Otherwise the / in the middle closes the reg exp.

Anonymous   
Printed Page 298
near the top and in middle of page

In this script, you mentioned that the declaration of the file in your errata
should go right before the foreach() loop. Unfortunately, that doesn't work
when using script. To fix this, just add:

my $file;
my $full_path;

right after declaring the variables for DOCUMENT_ROOT and VIRTUAL_PATH.

Anonymous   
Printed Page 298
bottom of the page, same script as above

Every time I check the syntax of the problem, I get this read back to me:

Can't use global @_ in "my" at grep_search2.cgi at line 83.

This is referring to the declaration:

my( $text ) = @_;

Anonymous   
Printed Page 303
11 lines down in the code

The errata says to change the current regex in the book from:

s/<.+?>//gs;

to

s/<(?:[^>'"]*|(['"]).*?1)*>//gs;

But with regex, the following error occurs at runtime:

/<(?:[^>'"]*|(['"]).*?1)*>/: regexp *+ operand could be empty at
indexer.pl line 91.

Anonymous   
Printed Page 309
5th line of code - Specifically the sort code

The sort is coded to sort the number of matches from lowest to highest. Search
engines usually show highest number of matches first. To allow this, the sort
should be coded as follows (swapping $a->[0] and $b->[0]):

sort { $matches{$b->[0]} <=> $matches{$a->[0]} ||
$a->[1] <=> $b->[1] }

Anonymous   
Printed Page 313
first paragraph after bulleted list

The uri http://www.cdrom.com/pub/png/pngintro.html is outdated and lists
http://www.libpng.org/pub/png/pngintro.html as the correct location. I,
however, have not been able to verify that this uri works, as
www.libpng.org appears to be down right now.

Anonymous   
Printed Page 408

The URL that reads:

http://www.activestate.com/PPM

should be changed to:

to http://www.activestate.com/ASPN/Downloads/ActivePerl/PPM.

Anonymous