Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi monks:
I am running in to a problem when printing values from a form that has the "&" in their names using the subroutine below: If from my program the name I am submitting in a form has something like;
Father Son Car Company
I will only print the first word, I know why, I just need a working around this to resolve my craze problem.
Here is the code:

sub parse_form { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); if (length($buffer) < 5) { $buffer = $ENV{QUERY_STRING}; } @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; $input{$name} = $value; } } print "$in{'app_name'}";


Thanks

Replies are listed 'Best First'.
Re: Parsing "&" from header.
by halley (Prior) on Mar 26, 2004 at 14:23 UTC
    Values submitted by a form as elements in a URL should be encoded to avoid the reserved characters like &. So if your user enters
    Sanford & Sons
    The URL should be encoded as
    ...&bar=foo&company=Sanford+%26+Sons&foo=bar&...
    Note that the spaces are encoded as plus signs, and the ampersand is encoded with a %26 (the hexadecimal value for ASCII '&').

    The docs of the CGI module discuss how to specify application/x-www-form-urlencoded to your FORM tag, to have your browser encode these elements for you. The CGI module can then do the parsing correctly.

    --
    [ e d @ h a l l e y . c c ]

      It is a strange thing cause it still doesn't do that using
      application/x-www-form-urlencoded

      on the form but nothing, it's a lost issue....
Re: Parsing "&" from header.
by Happy-the-monk (Canon) on Mar 26, 2004 at 13:28 UTC

    That's ugly cargo-cult code. The following does your task nicely, if your perl isn't very outdated:

    use strict; # might be a good idea, too. But the code: use CGI; my $q = CGI::->new; my %input = $q->Vars;

      And without any explanation, you just supplanted his cargo-cult for another cult.

      "Cargo cult" programming means "You have learned that if you do *this* random nonsense, you get the benefits."

      To break the cycle, the original poster must learn that there are no mysteries, that the actions are not random nonsense, and that they can get bigger benefits from understanding.

      Anonymous Monk, the suggestion to use the CGI module is a good one. Please read CGI as the barest of explanation of its capabilities. Many Perl books will suggest CGI over other approaches, too.

      Your original code only barely attempts to handle the parsing of $ENV{QUERY_STRING}, but there are a lot of ways this can go wrong if you're not careful. The CGI module is a predefined library which has been debugged over the past several years to handle all these problems in a consistent way.

      --
      [ e d @ h a l l e y . c c ]

Re: Parsing "&" from header.
by fireartist (Chaplain) on Mar 26, 2004 at 13:38 UTC
    I would normally do this as:
    use CGI::Simple; my $q = CGI::Simple->new; my %input = $q->Vars; print $q->unescapeHTML( $input{'app_name'} );
    The 1st line loads up the CGI::Simple module,
    the 2nd line creates a new CGI::Simple object,
    the 3rd line creates a hash containing all input sent to the CGI script (POST and GET),
    the 4th line passes the $input{app_name'} value to the CGI::Simple's object method unescapeHTML.
    That is necessary because any '&'s sent to your program will already have been HTML-encoded and will no longer be plain '&'s.

    See CGI::Simple for more info.
      Still cuts the results at the "&" or in the case of the first code it is printing the resuls but it is not printing the & back to the browser.
      Like:
      If I am seding Father&Sons
      Comes back
      FatherSons
      Any more sujestions?

        That's strange indeed. How does the <form>-tag look like?
        Maybe you need to write it like this:

        <form ... enctype="application/x-www-form-urlencoded">

Re: Parsing "&" from header.
by fireartist (Chaplain) on Mar 26, 2004 at 16:02 UTC
    If your results aren't what is expected, then you need to start debugging, try...
    use CGI::Simple; use Data::Dumper; my $q = CGI::Simple->new(); my %input = $q->Vars; print $q->header('text/plain'); print Dumper(\%input, \%ENV, \$q);
    Send your form data to this using a browser, it will print out a representation of all the data sent to the script %input, all the environment data %ENV and the CGI::Simple object.

    See if the script is being fed what you expect it to, if that doesn't help, then post the results here to give us all a bit more context.
Re: Parsing "&" from header.
by kutsu (Priest) on Mar 26, 2004 at 15:58 UTC

    halley has already suggested the base CGI docs and others have supplied sample code, I'll just add that you should take a look at Ovid's Cgi course and, esp. since this has the word Company (implying business), The Security Faq.

    "Cogito cogito ergo cogito sum - I think that I think, therefore I think that I am." Ambrose Bierce