CGI/Perl Guide | Learning Center | Forums | Advertise | Login
Site Search: in

  Main Index MAIN
INDEX
Search Posts SEARCH
POSTS
Who's Online WHO'S
ONLINE
Log in LOG
IN

Home: Perl Programming Help: Intermediate:
GREP problem.

 



jm01
New User

Mar 13, 2009, 6:19 AM

Post #1 of 10 (912 views)
GREP problem. Can't Post

I really do not know if this is a Perl issue or a server issue, but here is a description of the problem I have encountered. For several years, I have been using an authentication routine where I require persons who are completing a web form to login with their username and password. When they submit their web form, I write their username to a text file (vote-response7.txt in this case) and use the following code to check for a prior response whenever somebody authenticates and tries to complete the web form:

open(INF,"vote-response$form{'department'}.txt") or &alert2

("Couldn't open voters file for reading.");

@respondents = <INF>;

close(INF);

@results = grep(/$form{'username'}/i,@respondents);



if ($#results >= 0) {

&dienice("<font color='660000'>Our records indicate you have already voted.</font>");

}



sub dienice {

($msg) = @_;

printf("<form>");

printf("<h1><center>$msg</h1>");

printf("</form>");

exit;

}

I have never had any complaints about this form and have never noticed any problems before, but a few days ago somebody claimed they were able to respond once from their work computer and another time from their home computer. When I looked at the file containing responses, they had responded twice and their username was recorded twice in the vote-response7.txt file. Is there something wrong with the above code or is there another explanation for how they could have responded twice?


FishMonger
Veteran / Moderator

Mar 13, 2009, 7:53 AM

Post #2 of 10 (907 views)
Re: [jm01] GREP problem. [In reply to] Can't Post

Off hand I'd say it's because you're doing a case insensitive search and the user changed the case of their username when logging-in.

Can you show use how you're writing the data to vote-response7.txt and a copy/paste of the 2 apparent duplicate entrees?


(This post was edited by FishMonger on Mar 13, 2009, 7:54 AM)


1arryb
User

Mar 13, 2009, 8:02 AM

Post #3 of 10 (904 views)
Re: [jm01] GREP problem. [In reply to] Can't Post

Hi jm01,

Since you haven't provided the code where you actually record responses, we can't really say. However:

1. You don't test the result of the file read, so a momentary filesystem hiccup could result in @respondents being unpopulated or only partially populated.

2. I don't like the 'slurp-mode' file reading much. I have had occasional problems with it returning the number of rows (instead of the rows themselves) even when called in list context. This is why I read whole files in a loop, even though it's not as efficient.

3. This code (also) has the opposite problem than the one you complain of. If 'bobbie' responds after 'bob' she won't be able to get in. You should use /^$form{'username'}$/i in your grep.

Larry


jm01
New User

Mar 13, 2009, 8:11 AM

Post #4 of 10 (902 views)
Re: [FishMonger] GREP problem. [In reply to] Can't Post

Thanks for replying. Here are some of the records in the reply file with df20 being the duplicate:

df20
ds08
rt04
df20
lk04

Here is the code that writes to the file:

open(OUTF,">>vote-response$form{'department'}.txt") or &dienice("Couldn't open file for writing.");

print OUTF "$form{'username'}";

print OUTF "\n";

close(OUTF);

Department is picked up from a previous form where it is stored as a hidden variable using the HTML hidden tag . Username is picked up as a environment variable from a previous form and also stored in a hidden variable. Could reusing the names department and username be causing a problem?

$username = ($ENV{"REMOTE_USER"});

<input type=hidden name='department' value="$form{'department'}">

<input type=hidden name='username' value="$form{'username'}">


1arryb
User

Mar 13, 2009, 9:15 AM

Post #5 of 10 (893 views)
Re: [jm01] GREP problem. [In reply to] Can't Post

Hi jm01,

This is a cgi, right? You could have a concurrency problem:

Quote
Be aware that your CGI script shares machine resources with other programs, including other invocations of your CGI script. So, for example, if your script needs to append to a file, it's quite possible that in between opening the file for append, and actually appending, some other process might append on it's own. This is a race condition. Program defensively. In this case, seek to the end of file before appending, even though that should have been automatic in the open.

http://www.uic.edu/depts/accc/seminars/perliv/security.html#race

Has your site picked up on traffic lately? That may be why you are only now seeing the problem.

Cheers,

Larry


FishMonger
Veteran / Moderator

Mar 13, 2009, 10:26 AM

Post #6 of 10 (887 views)
Re: [1arryb] GREP problem. [In reply to] Can't Post

Humm, a race condition? You really think so, Larry? Not in this case, unless it's a very slooooow server.


Quote
a few days ago somebody claimed they were able to respond once from their work computer and another time from their home computer.


I'd say it's more likely that there is a space character in one of the duplicates which can cause this type of problem.

Using grep in this case is a poor choice. You should test for equality.

Here's one option for an improved method.


Code
open my $INF, '<', "vote-response$form{'department'}.txt" 
or alert2("Couldn't open voters file for reading.");

while ( my $user = <$INF> ) {

chomp $user;
s/^\s*//, s/\s*$// for $user; # strip out possible leading and trailing spaces

if ($form{'username'} eq $user ) {
dienice("<font color='660000'>Our records indicate you have already voted.</font>");
}
}



jm01
New User

Mar 13, 2009, 11:07 AM

Post #7 of 10 (882 views)
Re: [1arryb] GREP problem. [In reply to] Can't Post

This has been very educational. I really appreciate the help. Is there a way to test that @respondents has been fully populated and to reload if it has not? Could you share an example of how to do this and perhaps an example of how to read in a whole file in a loop that you describe in your second point?


jm01
New User

Mar 13, 2009, 11:25 AM

Post #8 of 10 (879 views)
Re: [FishMonger] GREP problem. [In reply to] Can't Post

Thank you, FishMonger. I looked at the text file containing the usernames and did not find any extra spaces or hidden characters. But, I will try your method of preventing duplicate responses if it is more reliable. Generally I use GREP in the form described earlier by Larry, but this particular script is an older one that was set up before I knew any better. Can you tell me what the less-than sign surrounded by apostrophes at the end of this line is doing:

open my $INF, '<',


FishMonger
Veteran / Moderator

Mar 13, 2009, 12:01 PM

Post #9 of 10 (859 views)
Re: [jm01] GREP problem. [In reply to] Can't Post

As your data set grows, grep becomes less and less efficient because needs to loop over the entire data set even if a match occurs in the 1st row. Sometimes that's what you want, sometimes it isn't. You don't want to do that in this situation.

The '<' is the mode for the filehandle.

< read mode
> write mode
>> apend mode


Quote
[root@myserver ~]# perldoc -f open
open FILEHANDLE,EXPR
open FILEHANDLE,MODE,EXPR
....
....
....


I'll leave you to read the perldoc rather than me quoting the entire documenet.


KevinR
Veteran


Mar 13, 2009, 11:46 PM

Post #10 of 10 (848 views)
Re: [jm01] GREP problem. [In reply to] Can't Post


Quote
When they submit their web form, I write their username to a text file (vote-response7.txt in this case) and use the following code to check for a prior response whenever somebody authenticates and tries to complete the web form:


If you write their name to the file first, and then check it to see if the name is already there, a person could vote as many times as they like. You need to check the file with the names first. Maybe you are but your comment quoted above makes it sound like you are doing the opposite.
-------------------------------------------------

 
 


Search for (options) Powered by Gossamer Forum v.1.2.0

Web Applications & Managed Hosting Powered by Gossamer Threads
Visit our Mailing List Archives