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.
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 |
|