tags:

views:

106

answers:

2

The user enters a product code, price and name using a form. The script then either adds it to the database or deletes it from the database. If the user is trying to delete a product that is not in the database they get a error message. Upon successful adding or deleting they also get a message. However, when I test it I just get a blank page. Perl doesnt come up with any warnings, syntax errors or anything; says everything is fine, but I still just get a blank page.

The script:

    #!/usr/bin/perl
#c09ex5.cgi - saves data to and removes data from a database
print "Content-type: text/html\n\n";
use CGI qw(:standard);
use SDBM_File;
use Fcntl;
use strict;

#declare variables
my ($code, $name, $price, $button, $codes, $names, $prices);


#assign values to variables
$code = param('Code');
$name = param('Name');
$price = param('Price');
$button = param('Button');

($code, $name, $price) = format_input();
($codes, $names, $prices) = ($code, $name, $price);

if ($button eq "Save") {
      add();
}
elsif ($button eq "Delete") {
      remove();
}
exit;


sub format_input {
         $codes =~ s/^ +//;
         $codes =~ s/ +$//;
         $codes =~ tr/a-z/A-Z/;
         $codes =~ tr/ //d;
         $names =~ s/^ +//;
         $names =~ s/ +$//;
         $names =~ tr/ //d;
         $names = uc($names);
         $prices =~ s/^ +//;
         $prices =~ s/ +$//;    
         $prices =~ tr/ //d;
         $prices =~ tr/$//d;
    }


sub add {
   #declare variable
   my %candles;

 #open database, format and add record, close database
     tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
          or die "Error opening candlelist. $!, stopped";

     format_vars();
     $candles{$codes} = "$names,$prices";
     untie(%candles);

 #create web page      
      print "<HTML>\n";
      print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
      print "<BODY>\n";
      print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n";
      print "Candle: $codes $names $prices</FONT>\n";
      print "</BODY></HTML>\n";
      } #end add


sub remove {
   #declare variables
   my (%candles, $msg);

 tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
          or die "Error opening candlelist. $!, stopped";

     format_vars();

     #determine if the product is listed
     if (exists($candles{$codes})) {
          delete($candles{$codes});
          $msg = "The candle $codes $names $prices has been removed.";
        }
     else {
     $msg = "The product you entered is not in the database";
     }
     #close database
     untie(%candles);

#create web page
print "<HTML>\n";
print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
print "<BODY>\n";
print "<H1>Candles Unlimited</H1>\n";
print "$msg\n";
print "</BODY></HTML>\n";
}
+1  A: 

Running it at the command line with:

perl something.cgi Button=Save

...gives me an error:

Undefined subroutine &main::format_vars called at something.pl line 55.

If I change both references of format_vars() to "format_input()", I get what I think is the proper output.

SqlACID
Fixed that, but I still just get a blank page.
Jason
Try adding a print "$button\n"; after getting the params, line 19 or so. Make sure you are getting the input you expect. Remember the eq check is case sensitive, so if button = "save" it won't work. Do a view source on the output, how far is it getting? Can you run it via the command line?
SqlACID
If I add the print button line, it comes up Save, as it should. Other then that though it is still just a blank page, page source doesnt even show anything, just blank, no code at all.
Jason
Well, I finally got it to work when run from the command line but it still gives me nothing when done the way it's supposed to using the form. I have no idea why, neither does anyone here, and neither does my teacher so.. I give up! Thanks for your help though!
Jason
@Jason: Well, if you're going to give up... Take another look at my answer. I've gotten your code to run successfully here and provided a brief code review while I was at it.
Dave Sherohman
+1  A: 

You're not printing any output aside from the Content-Type header unless add or remove gets called. The problem is just that you forgot to display a form (presumably one containing the buttons) if no button has been clicked.

Edit: Copying your posted code and doing a little cleanup, then calling it at the URL http://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Save or http://localhost/~me/foo.cgi?Code=1;Name=2;Price=3;Button=Delete, I do get proper HTML output. The cleaned up version of the code used for this is:

#!/usr/bin/perl

use strict;
use warnings;

print "Content-type: text/html\n\n";
use CGI qw(:standard);
use SDBM_File;
use Fcntl;
use strict;

#declare variables
my ($code, $name, $price, $button, $codes, $names, $prices);


#assign values to variables
$code = param('Code');
$name = param('Name');
$price = param('Price');
$button = param('Button');

($code, $name, $price) = format_input();
($codes, $names, $prices) = ($code, $name, $price);

if ($button eq "Save") {
  add();
}
elsif ($button eq "Delete") {
  remove();
}
exit;


sub format_input {
  $codes =~ s/^ +//;
  $codes =~ s/ +$//;
  $codes =~ tr/a-z/A-Z/;
  $codes =~ tr/ //d;
  $names =~ s/^ +//;
  $names =~ s/ +$//;
  $names =~ tr/ //d;
  $names = uc($names);
  $prices =~ s/^ +//;
  $prices =~ s/ +$//;
  $prices =~ tr/ //d;
  $prices =~ tr/$//d;
  }

sub add {
#   #declare variable
#   my %candles;
#
# #open database, format and add record, close database
#     tie(%candles, "SDBM_File", "candlelist", O_CREAT|O_RDWR, 0666)
#          or die "Error opening candlelist. $!, stopped";
#
#     format_vars();
#     $candles{$codes} = "$names,$prices";
#     untie(%candles);

 #create web page      
 print "<HTML>\n";
 print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
 print "<BODY>\n";
 print "<FONT SIZE=4>Thank you, the following product has been added.<BR>\n";
 print "Candle: $codes $names $prices</FONT>\n";
 print "</BODY></HTML>\n";
 } #end add


sub remove {
#   #declare variables
#   my (%candles, $msg);
#
# tie(%candles, "SDBM_File", "candlelist", O_RDWR, 0)
#          or die "Error opening candlelist. $!, stopped";
#
#     format_vars();
#
#     #determine if the product is listed
#     if (exists($candles{$codes})) {
#          delete($candles{$codes});
#          $msg = "The candle $codes $names $prices has been removed.";
#        }
#     else {
#     $msg = "The product you entered is not in the database";
#     }
#     #close database
#     untie(%candles);

  #create web page
  print "<HTML>\n";
  print "<HEAD><TITLE>Candles Unlimited</TITLE></HEAD>\n";
  print "<BODY>\n";
  print "<H1>Candles Unlimited</H1>\n";
#  print "$msg\n";
  print "<p>Called remove</p>";
  print "</BODY></HTML>\n";
  }

Note that, with warnings enabled, this spews a lot of "uninitialized value" warnings because you're getting $code vs $codes, $name vs $names, and $price vs $prices confused with each other in bad ways. (Hint: You assign ($code, $name, $price) = format_input();, but format_input doesn't return three values.)

I suspect that, as suggested in an earlier comment, you're having case-sensitivity issues again/still. My first attempt at testing this failed because I used "button=Save" instead of "Button=Save" in the URL. HTTP request parameter names are generally all-lowercase by convention, and for good reason, as it helps to avoid problems of that sort.

Other random comments:

  • You can declare your variables at the same time as you first assign them, e.g., my $code = param('Code');. This is generally considered to be the better/preferred practice, as making your declaration as late as possible helps to minimize the variable's scope.

  • In format_input, it's redundant to both s/^ +//; s/ +$//; and tr/ //d;, as the tr will also remove leading and trailing spaces.

  • When getting values of your parameters, you should either supply default values for if the parameter is empty/missing or check for empty/missing and display an error to the user.

  • You should also have a final else clause after the elsif ($button eq "Delete") to display an error if $button is missing or invalid. Yes, I know this script is intended to be called from a specific form, so it should "always" have a valid $button, but it's trivial to bypass the form and submit any set of values (valid or not) to the script directly, so you still need to verify and validate everything on the server side because you don't know where it will actually be coming from or whether the client validated it properly.

Dave Sherohman
That doesn't make any sense. I can add a print button line and verify the button value is getting passed, which means add or remove IS getting called and I still get a blank page. The form calls the script once the button has been pressed, not the other way around.
Jason