Need some problemsolving-cgi/xml

L

lievemario

Hello,

I have written the following perl program,
this is what is does:
- it gets input from a form (a person_id)
- then it executes a query
- transform this result to an xml file
- then transform the xml file via xsl file to output in the browser.


Now the following errors appear:
- first of all, I don't know why, but the script is not able to open / write
person.xml anymore
- second, when I have such an xml file, the script is not able to produce
the output,
I get a CGI timeout error.
(Just for info; I call the script via the following line in the form
application:
<form action="person2.cgi?person_id=$person_id" method="POST">
)
I have search a long time, but I can not solve the problem.

- another question I also have;
it is my intention to execute 1 or more queries (depending on the
@details the
user selected in the form). How can I combine all these xml files/xsl to
one output?

Hope I get some solution.

Thanks a lot!!


----------------------------------------------------------------------------
-------
#!/usr/bin/perl

# use strict;
use DBI;
use XML::Generator::DBI;
use XML::Handler::YAWriter;
use XML::parser;
use XML::XSLT;

use CGI qw(param);

my $xslfile = "CGI\\details.xsl";


# create a DBI connection
my $dbh = DBI->connect ("DBI:mysql:rd", "root", "",
{ RaiseError => 1,
PrintError => 0
});

# instantiate a new XML::Handler::YAWriter object
my $out = XML::Handler::YAWriter-> new(
AsFile => "CGI\\person.xml",
Pretty => {PrettyWhiteNewline => 1,
PrettyWhiteIndent => 1,
CatchEmptyElement => 1,
CatchWhiteSpace => 1
},
Encoding => "ISO-8859-1",
);

# instantiate a new XML::Generator::DBI object
my $gen = XML::Generator::DBI->new(
Handler => $out,
dbh => $dbh,
RootElement => 'Description',
RowElement => 'Person'
);


read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$value =~ s/'//g;
$value =~ s/&/and/g;
$value =~ s/\"//g;
$value =~ s/\+//g;
$FORM{$name} = $value;
}

my @details = ("data","team","pubs","other");
foreach $x (@details) {
if ($FORM{$x} == 1) {
if($x eq "data") {
data_query();
}
#print "You picked $x.\n";
}
}

my $xmlparser = new XML::parser(ProtocolEncoding => "ISO-8859-1");
my $input = "CGI\\person.xml";
$xmlparser ->setHandlers(Start => \&start_handler,
End => \&end_handler,
Char => \&char_handler);
$xmlparser ->parsefile($input);

# The handlers for the XML Parser.
sub start_handler
{
my $expat = shift; my $element = shift;
# element is the name of the tag
print $startsub{$element};
# Handle the attributes
while (@_) {
my $att = shift;
my $val = shift;
print "$att=$val ";
}
}

sub end_handler
{
my $expat = shift; my $element = shift;
print $endsub{$element};
}

sub char_handler
{
my ($p, $data) = @_;
#print $data;
}

my $xslparser = XML::XSLT->new($xslfile);
my $result = $xslparser->serve("CGI\\person.xml", http_headers => 0,
xml_version => 0, xml_declaration => 0);
$result = "Content-Type: text/html\n\n" . $result;
print $result;

my $person_id = param("person_id");
print $person_id;

sub data_query {
# define the SQL query
my $query1 = "SELECT p.person_id,
p.name,
p.first_name,
p.phone,
p.fax,
p.email
FROM list_personnel p
WHERE p.person_id = ?;
";
#my $sth1 = $dbh->prepare($query1);
$gen->execute($query1,$person_id);
}
 
G

gnari

[snip]

you have many apparent problems:
you are not using strict
you are useing CGI.pm but still decoding your params yourself.
you did not try to simplify your problem. do you expect us
to install all these modules to debug unrelated things ?
you seem to use a temp file with hardwired location, with no
locking. also you use relative filepaths

gnari
 
T

Tad McClellan

lievemario said:
- it gets input from a form (a person_id)


Then you should have taint checking enabled, see:

perldoc perlsec

Hope I get some solution.


Get it working *from the command line* first, move it to the CGI
environment after it has been debugged.

#!/usr/bin/perl
# use strict;


You lose all of the benefits of use strict if you comment it out.

Ask for all the help you can get:

#!/usr/bin/perl -T
use warnings;
use strict;

(and "perldoc -q CGI" ... "How can I get better error messages
from a CGI program?")

use CGI qw(param);

my $dbh = DBI->connect ("DBI:mysql:rd", "root", "",
^^^^^^ ^^


Please, oh please, tell that this is not your actual code!

It is bad security on many levels!

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buffer);

[snip cargo-cult param "parsing"]

Why are you doing this yourself instead of letting CGI.pm do it for you?

POST data is on STDIN, GET data is in the environment variable.

my @details = ("data","team","pubs","other");


That sure is hard to read:

my @details = qw( data team pubs other );

foreach $x (@details) {


Have you already declared $x somewhere?

my $person_id = param("person_id");


Now you *are* having CGI.pm do the form parsing for you.

Why did you switch?
 
J

James Willmore

On Thu, 25 Nov 2004 07:22:36 +0100, lievemario wrote:

Now the following errors appear:
- first of all, I don't know why, but the script is not able to open / write
person.xml anymore

And your logs say .... what? Did you check the server logs to see what
messages are being issued by the script? Have you tested the script at
the command line first? If so, what happened?
- second, when I have such an xml file, the script is not able to produce
the output,
I get a CGI timeout error.
(Just for info; I call the script via the following line in the form
application:
<form action="person2.cgi?person_id=$person_id" method="POST">
)
I have search a long time, but I can not solve the problem.

And your logs say .... what? Did you check the server logs to see what
messages are being issued by the script? Have you tested the script at
the command line first? If so, what happened? Are you *sure* it's a "CGI
timeout error" and not some other error happening in the background that
results in your script timing out? Logs will tell you lots ... if you let
them :)

- another question I also have;
it is my intention to execute 1 or more queries (depending on the
@details the
user selected in the form). How can I combine all these xml files/xsl to
one output?

To "transform", "process", etc. XML using XSLT, you have a wide variety of
choices (Xalan, Saxon ...). You could even create an XML file (file
system or in memory) and use XPath statements to extract data from the XML
file. Visit CPAN (http://search.cpan.org) and search for xsl or xml or
xpath to find them :)
#!/usr/bin/perl

#!/usr/bin/perl -T
#turn taint checking on
#visit http://www.w3.org/Security/Faq/wwwsf4.html#CGI-Q15
#for more information
# use strict;

use strict;
use warnings;
use DBI;
use XML::Generator::DBI;
use XML::Handler::YAWriter;
use XML::parser;
use XML::XSLT;

#you already found a module for using XSLT
#have you looked at the 'toString' method?
use CGI qw(param);

use CGI qw:)standard :debug);
#load standard CGI routines *and* debugging support
# ... so you can run the script at the command line

# create a DBI connection
my $dbh = DBI->connect ("DBI:mysql:rd", "root", "",
{ RaiseError => 1,
PrintError => 0
});

using 'root' is a *very* bad move for a CGI script ... glad it's not my
box :)

read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); @pairs = split(/&/,
$buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value
=~ s/'//g;
$value =~ s/&/and/g;
$value =~ s/\"//g;
$value =~ s/\+//g;
$FORM{$name} = $value;
}
}

*READ* the CGI documentation ... hell, there's even an *example* at the
very top of the document demonstrating *how* to use the module :)
The above code is, well, pointless, if you're going to use the CGI module.
my @details = ("data","team","pubs","other");
foreach $x (@details) {
if ($FORM{$x} == 1) {
if($x eq "data") {
data_query();
}
#print "You picked $x.\n";
}
}
}

foreach my $x (@Details) {
....
}

You need to declare a variable before using it and using the 'strict'
pragma. The above will do that.

Just FYI, you could also look over ...
http://www.w3.org/Security/Faq/wwwsf4.html#CGI-Q17
on how to untaint variables, and
http://www.cert.org/tech_tips/cgi_metacharacters.html
on hot to remove unsafe characters from the query string.


<snip>

You should really read the documentation for the various modules you're
using. It looks like you cobbled together something from various sources
and, well, this ain't going to work the way you expect it to. Try small
parts of what you're trying to do (for example, do some small XML
transformations first and small do nothing CGI scripts). Test them and see
that they work the way you expect them to. Then put it all together for
the final product.

HTH

Jim
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top