Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

somethign wrong with the sumbit

by Nik (Initiate)
on Dec 29, 2007 at 11:36 UTC ( [id://659466]=perlquestion: print w/replies, xml ) Need Help??

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

print header( -charset=>'utf-8' ); my $passage = param('select') || "Αρχική + Σελίδα!"; my @files = glob "$ENV{'DOCUMENT_ROOT'}/data/text/*.txt"; my @display_files = map m{([^/]+)\.txt}, @files; Encode::from_to($_, 'ISO-8859-7', 'utf8') for @display_files; if ( param('select') ) { #If User selected an item from the drop do +wn menu unless ( grep { $_ eq param('select') } @display_files ) #If User + Selection doesn't match one of the passages then its a Fraud! { if ( param('select') =~ /\0/ ) { $passage = "*Null Byte Injection* attempted & logged!"; print br() x 2, h1( {class=>'big'}, $passage ); } else { $passage = "*Backwards Directory Traversal* attempted & logge +d!"; print br() x 2, h1( {class=>'big'}, $passage ); } $select = $db->prepare( "UPDATE guestlog SET passage=?, date=?, +counter=counter+1 WHERE host=?" ); $select->execute( $passage, $date, $host ); exit; }
Even if the user selects something valid from the drop down menu he is getting the backward error.....on every selection he makes. Any idea why the script reaches that specific error code block?

i noticed on the url that when i submit my selection it looks like this: http://nikos.no-ip.org/cgi-bin/index.pl?select=item_from_drop_down_menu&ok=ok

You can try it too and you will notice that the submit variable (ok is its name) is showing up twice!

Replies are listed 'Best First'.
Re: somethign wrong with the sumbit
by graff (Chancellor) on Dec 29, 2007 at 17:31 UTC
    my @files = glob "$ENV{'DOCUMENT_ROOT'}/data/text/*.txt"; my @display_files = map m{([^/]+)\.txt}, @files; Encode::from_to($_, 'ISO-8859-7', 'utf8') for @display_files; if ( param('select') ) { #If User selected an item from the drop do +wn menu unless ( grep { $_ eq param('select') } @display_files ) #If User Selection doesn't match one of the passages then its a F +raud! { ...
    Even if the user selects something valid from the drop down menu he is getting the backward error.....on every selection he makes.

    In order to get into the error-report block, it must be the case that the string coming from the drop-down menu does not match any of the file name strings you have extracted from your "data/text" directory.

    You didn't show us the code that creates the drop-down menu, and it looks like you haven't tried yet to look at the actual string value that is coming in via the "select" param. You need to see what sort of value is coming in, and then figure out why the values in the drop-down menu don't match the file names in that directory.

    You should be using exactly one array to populate the options in the drop-down menu and to check the value of param('select'). Create that list only once, and use the one list for both building the form and checking the submission.

    (updated to fix grammar in last paragraph)

    Another update: if I understand this part correctly:

    i noticed on the url that when i submit my selection it looks like this:
    http://nikos.no-ip.org/cgi-bin/index.pl?select=item_from_drop_down_menu&ok=ok

    I'm guessing the code that creates the drop-down menu is doing something very wrong. But you haven't shown that part of the code, so it's just a guess.

      The part of the code that created the drop down menu is some lines below the code that i originally posted, here is is:
      print start_form( action=>'/cgi-bin/index.pl' ); print h1( {class=>'lime'}, "Επέλεξ& +#949; το κείμενο π& +#959;υ σε ενδιαφέ&# +961;ει => ", popup_menu( -name=>'select', -values=> +\@display_files ), submit('ok')); print end_form;
      Also i have checked and verified that the returned string values coming back to index.pl when i user makes a valid item selection from the drop down menu is in 100% correct.

      That means that each time i select something form the list i get a proper string value back that corresponds to an existing filename which is an item of @display_files

      So we know for usre know the the param('select') holds a valid string value.

        Ah. Well, it looks like maybe you need to tell perl explicitly that the value of "params('select')" must be treated as a utf8 string -- either that or else the string comparison in your grep statement needs to be done with explicitly declared byte semantics.

        In other words, either do this (flag the param value as utf8):

        use Encode; # add this if you don't have it already if ( param('select') ) { #If User selected an item from the drop do +wn menu my $selected_file = decode('utf8', param('select')); unless ( grep { $_ eq $selected_file } @display_files ) #If User Selection doesn't match one of the passages then its a +Fraud! { ...
        (updated to fix spelling of "selected_file")

        Or else this (do the grep with byte semantics):

        if ( param('select')) { use bytes; unless ( grep {$_ eq param('select') } @display_files ) #If User Selection doesn't match one of the passages then its a +Fraud! { ...
        Note that the "use bytes" pragma is lexically scoped: it applies within the block where you put it.

        Hope that helps...

        I'll try one last time (update: because I missed a relevant clue in one your replies, and this might make a difference for you -- see the "last update" at the bottom of this post). I will repeat the advice I have given 3 times already in this thread. I do so with some reluctance, because I suspect that once you do try this, you'll discover (or create) some other bone-headed mistake in your code, and will start another lengthy sub-dialog... oh well, here it goes anyway.

        Let's go back to the code at the very beginning of this train-wreck -- I'll add some commentary, and make the changes that should get you over the particular hump that started it all:

        my @files = glob "$ENV{'DOCUMENT_ROOT'}/data/text/*.txt"; my @display_files = map m{([^/]+)\.txt}, @files; Encode::from_to($_, 'ISO-8859-7', 'utf8') for @display_files; # SO FAR, SO GOOD. The same @display_files array is used later to cre +ate # the popup menu, which shows up correctly/as intended in the browser, # so this use of Encode::from_to() is correct and necessary. if ( param('select') ) { #If User selected an item from the drop do +wn menu my $selected_file = decode('utf8', param('select')); ## ADD THIS +LINE ### UPDATED 3 days after initial post: it wa +s originally ### "encode" which, as Nik points out below, + was wrong unless ( grep /^\Q$selected_file\E$/, @display_files ) #If User Selection doesn't match one of the passages then its a +Fraud! { ## REPORT AN INVALID SUBMISSION (you don't need to worry abou +t saying ## what properties it has that make it invalid -- it doesn't +match any ## known file name, and that is all that matters. ## ... but before exiting, send some kind of error page back + to the browser exit; } ## IF YOU GET HERE, YOU HAVE A VALID MATCH ## so you can see where your next coding mistake is...
        The first time I suggested using the "decode()" function on the "select" param value, you said:
        i beleive there is no need to explicitly tell perl to handle param('select') as utf8 it must do this by default i think.

        I was able to prove (to my own satisfaction, at least) that your belief here was wrong. So try the suggestion and see what happens. I gather that you don't read documentation much at all, but if you could do that, and spend some time looking at the man page for Encode, you might be able to learn this important concept:

        There is a difference between a "perl-internal utf8 string" and a "raw string containing utf8". The first thing is a byte sequence that stores valid utf8 characters and is flagged in perl's internal storage as being a utf8 string; in contrast, that latter thing is a byte sequence that happens to come from some external source of utf8 data, but has not been flagged as a perl-internal utf8 string. As explained in the Encode man page, a "perl-internal utf8 string" and a "raw string" will never match, even if the actual byte sequences in the two strings are identical. The "utf8 flag" being different (set vs. not set) makes the strings different, regardless of anything else.

        That is why the "decode('utf8', ...)" function is used on the parameter value -- if it really came from your cgi web form, then it really is a byte sequence for a valid utf8 string, but perl won't consider it to be the same as a "perl-internal utf8 string", even when the actual sequence of bytes is identical. The utf8 flag must be set on both strings, or not set on both strings (in addition to the bytes being the same), for a match to succeed, and setting the utf8 flag is one of the things that the "decode()" function does.

        (Nit-picky details:) In complementary fashion, doing "encode( 'utf8'. ...)" on a perl-internal utf8 string will produce a "raw" string (the utf8 flag is turned off). But the "difference" between "perl-internal utf8" and "raw" only applies when "wide" characters are involved -- i.e. those that lie outside the 7-bit ascii range -- note the following command lines using different versions of a one-line script:

        perl -MEncode -le '$a="\x{0341}"; $b=encode("utf8",$a); print "a:b ", +(($a eq $b) ? "same":"different")' # prints "different" -- $a is perl-internal utf8, $b is raw perl -MEncode -le '$a="foo"; $b=encode("utf8",$a); print "a:b ", (($a +eq $b) ? "same":"different")' # prints "same" perl -MEncode -le '$a="foo"; $b=decode("utf8",$a); print "a:b ", (($a +eq $b) ? "same":"different")' # also prints "same" perl -MEncode -le '$a=decode("utf8","foo"); $b=encode("utf8","foo"); p +rint "a:b ", (($a eq $b) ? "same":"different")' # still prints "same
        Regarding the last example: note that running "decode('utf8',$a)" would be an error if $a were already flagged as a perl-internal utf8 value and contained wide characters. If all this confuses you, get over it. That's the reality.

        (updated to fix a typo and add clarification in the last paragraph)

        LAST UPDATE: Okay, I know that you have tried adding the "decode()" line before, and you reported the error message you got as a result, which was "Cannot decode string with wide characters at ... line 182" I didn't make the connection until after I updated that last paragraph above. The point is, at line 182 (wherever that was in your script -- you didn't make that clear) you are running "decode()" on a string that already has the utf8 flag set, and contains a wide character.

        If line 182 is the decode line that I told you to add, then I'm really puzzled, because it would mean that this cgi parameter string is already flagged as utf8 (though I can't imagine how), and if that's true, and the string came from the popup menu, then it should match. (In this case, try opening a separate text file for output -- make sure to set the mode to ">:utf8" -- and print the parameter and @display_files strings to that file, so you can inspect them manually, with a hex-dump tool if need be.)

        But if line 182 is somewhere else, it's probably just the next bone-headed programming error in your script, and you had not seen it before because the script had never gotten that far before. It's really frustrating when you leave out relevant details like this. Even after I told you days ago that you should have shown us that line, you didn't do it. It's tiresome.

        Think harder before you post again -- read what you write before you hit the "create" button, and try to imagine that you are someone else, and think what questions this other person would ask about the information in the post. Then add the answers to those questions. Better yet, try to imagine what advice this other person would give you, and try it out before posting. Take your time, don't rush it. Only create the node when you have included a clear description of what you have tried (code, inputs and outputs).

Re: somethign wrong with the sumbit
by Anonymous Monk on Dec 29, 2007 at 12:12 UTC
    You are asking why param('select') =~ /\0/ is always false
      I don't understand what you try to tell me

      I believe iam asking if the submitted user selection from the drop down list contains the null string....and if yes iam printing a custom error message.

      That can happen because sometimes people instead of making a selection from the drop down menu they pass values to variable $select from the url like this: http://nikos.no-ip.org/cgi-bin/index.pl?select=../somefilename.ext or attach a null string to attempt to hack the page.

        and ELSE you get the backwards error... you need rest
Re: somethign wrong with the sumbit
by syphilis (Archbishop) on Dec 29, 2007 at 14:50 UTC
    Hi Nik,

    Please be consistent with your lisping:
    "thumb thign wong with the thumb bit"
    Heh ... you possibly don't understand ... and others probably think I'm just trying to be a smartarse ... but I really *do* think your typos are the best !!

    Cheers,
    Rob
      Well...thank you! :)

      When i try to type fast very very often i type like this: thign instead of thing, hwat instead of what and so on :)

        This is why you get to preview posts before submitting them. You have been here for many years now, why not take the time to post messages properly so that people can understand what you trying to ask? Once again, read (and understand) the PerlMonks FAQ, How do I post a question effectively? and What shortcuts can I use for linking to other information?. Your devshed posts only confirm that your continued lack of effort to properly explain yourself in English, and your disregard for use of correct formatting/linking of information can only lead to further confusion/inconvenience.

        Martin

        I am sympathetic to the problem of fast typing, especially because I am slightly dyslexic. Even proof reading for errors is difficult for me because my eyes skim past the mistakes and don't see them. This is, I presume, because my brain is so used to correcting for my misreadings it doesn't always realize that the weird thing I read was actually on the page and not just a side effect of the funky way my eyes read.

        All the same.... marto has a point. Posting is about communication. Taking the time to slow down, review what you write and catch the errors you can, is much appreciated by all and is likely to give you a better response.

        Please do try just a bit harder.

        Oops! :-) Didn't check the date and realize this is ancient history.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://659466]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (None)
    As of 2024-04-25 00:55 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      No recent polls found