[23147] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 5368 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Aug 15 18:10:40 2003

Date: Fri, 15 Aug 2003 15:10:13 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Fri, 15 Aug 2003     Volume: 10 Number: 5368

Today's topics:
    Re: Question about "eval" security <tzz@lifelogs.com>
    Re: question regarding multiple args to sub  <abc@nowhere.com>
    Re: question regarding multiple args to sub <michael.p.broida@boeing.com>
    Re: question regarding multiple args to sub <spamblock@junkmail.com>
    Re: Regex capture variable scoping <eric-amick@comcast.net>
        Saving entire file (MJS)
    Re: Saving entire file <noreply@gunnar.cc>
    Re: Saving entire file <mikeflan@earthlink.net>
    Re: Saving entire file <noreply@gunnar.cc>
    Re: Saving entire file <bharn_S_ish@te_P_chnologi_A_st._M_com>
    Re: Search Engine help <tzz@lifelogs.com>
        Status counter (brice)
    Re: Status counter <ndronen@io.frii.com>
    Re: Status counter <tore@aursand.no>
    Re:  <bwalton@rochester.rr.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Fri, 15 Aug 2003 11:42:58 -0400
From: Ted Zlatanov <tzz@lifelogs.com>
Subject: Re: Question about "eval" security
Message-Id: <4nlltvlyf1.fsf@lockgroove.bwh.harvard.edu>

On Thu, 14 Aug 2003, hisao@physics.purdue.edu wrote:

> I wish to use "eval" on a user input but want to make sure security
> is not compromised. What I want is just to allow variable
> interpolation but not any executions. Would something like:
> 
> eval qq/"$userinput"/;
> 
> work? As far as I could test it, it seems to do the job (i.e., does
> evaluate any valid variables in $userinput but refuse to execute any
> commands in it.  (If I take the double quotes out, then it would
> execute commands - which is very bad. I want to make sure that this
> is OK as far as security.

I would design a syntax that can be parsed, either with Perl, with a
module like AppConfig, or with a parser like Parse::RecDescent.
AppConfig in particular allows you to interpolate, but the variables
have to be pre-defined for AppConfig usage, or %ENV keys.  So you
can't interpolate just any variable you want.  I consider this a good
thing.

What are your basic operations?  Let's say you need to get/set
scalars; give your users these commands (also see AppConfig's built-in
syntax for ideas on hashes and lists):

(set)
VAR = value  # just set it to a value
VAR1 = $VAR2 # copy the value from another variable

(get)
VAR

And that's all they are allowed to do.  This is the safest route in
terms of security, because you are not allowing your users to do
anything unexpected.  Calling eval() can produce unexpected results if
you don't control the input tightly.  Tight input control can be just
as costly as a custom syntax, if not worse, in terms of security and
development time (primary and bug-fixing when holes are discovered).

Of course, if the user input has to allow very complex Perl operations
and if you trust the input, use eval() as shown by the other replies
to your message.  That doesn't seem to be the case from your post,
though.

Ted


------------------------------

Date: Fri, 15 Aug 2003 20:16:32 GMT
From: ktom <abc@nowhere.com>
Subject: Re: question regarding multiple args to sub 
Message-Id: <Acb%a.190457$xg5.133746@twister.austin.rr.com>

Bob Walton wrote:
> ktom wrote:
> 
>  > I have to subs in which i am attempting to pass multiple args to and i
>  > have managed to get it to work, after spending all afternoon trying to
>  > get my brain around it.  I still don't have my brain around and the
>  > solution seems absurd!!
>  >
>  > below are snippets...
>  >
>  > 1st call:
>  >
>  >         &printVec( \@spline, \@indx, \@port1 );
> 
> ----------^
> 
> Any more (that is, with Perl's less than many years old), you shouldn't 
> use the & in your call unless you actually want the specific 
> functionality it provides.  See:
> 
>    perldoc perlsub
> 
> for details.
> 
> 
>  >          }
>  >
>  > 1st working sub:
>  >
>  > sub printVec {
>  > #our @spline;
>  > #   my (@spline,@indx,@port) = @_ ;
>  > #   print "pre @$spl, @$indx, @$port\n";
>  > #   print "spline @spline\n";
>  >    my ($spl,$indx,$port) = @_ ;
>  >    my @prt = @$port ;
>  >    my @ndx = @$indx ;
>  >    my @spline = @$spl ;
> 
> 
thanks for responding..  and to the others who responded..

the main reason for the copy is to use a
while( @array ){
   ..
   stuff
   ..
   shift @array
   }
to loop through the items.  i am guessing i could have accomplished the 
same thing with a for loop that didn't modify the array.

i don't need to modify the values coming in.

> These latter three statements are OK if you actually want to make a copy 
> of the three arrays in your sub.  It is not necessary, and, if the 
> purpose of your sub is to modify values in the arrays, won't work unless 
> you copy the modified values back to the arrays before you return.  You 
> can instead access elements of the arrays as, for example:
> 
>    $$port[3]='something or other';
>    @$indx[3..6]=(4..7);
>    $val=$$spl[23];
> 
> or you can use notation like:
> 
>    $port->[3]='something or other';
> 
> etc if you prefer a "cleaner" implementation (at least according to some 
> definition of "clean").
> 
> 
>  >
>  >
>  > 2nd call:
>  >
>  >       &printTset( \@indx, $vect, $cmmnt ) ;
>  >       }
>  >
>  > 2nd working sub:
>  >
>  > sub printTset {
>  >    my ( $indx, $vct, $cmt) = @_ ;
>  >    my @ndx = @$indx;
>  >    my $vect = $vct;
>  >    my $cmmnt = $cmt;
> 
> 
> Again, you don't have to make local copies of the data unless that is 
> really what you want to do.  In this case, passing the scalars directly 
> is fine, since they will always have just a single value in @_.
> 
> 
>  >
>  > if i don't use the \ on the passed parameters, it seems to merge them
>  > all into one big array.. blahh.
> 
> 
> Yep.  That's the way Perl's argument calling semantics work.  It's a 
> feature, not a bug or problem :-).
> 
> 
>  >
>  > this seems like a lot of code, seemingly redundant to my wee perl mind,
>  > to pass values to a subroutine.
> 
> 
> Well, it isn't that much overhead when writing the code -- one extra $ 
> or @ for each time you want to reference an item.  Plus don't forget you 
> can also pass hashes, globs, and references (and maybe some other stuff 
> I'm forgetting or don't know about) this way too.  And of course, hashes 
> of arrays of hashes, etc etc.
> 
> 
>  >
>  > what magic am i missing or is this just the way it is???
> 
> 
> Nope, that's the way it is.  Except you shouldn't make local copies 
> unless there is a good reason why.
> 
> 
> ...
> 



------------------------------

Date: Fri, 15 Aug 2003 18:09:33 GMT
From: "Michael P. Broida" <michael.p.broida@boeing.com>
Subject: Re: question regarding multiple args to sub
Message-Id: <3F3D21DD.F1EB42A1@boeing.com>

ktom wrote:
> 
> I have to subs in which i am attempting to pass multiple args to and i
> have managed to get it to work, after spending all afternoon trying to
> get my brain around it.  I still don't have my brain around and the
> solution seems absurd!!
> 
> below are snippets...
> 
> 1st call:
> 
>          &printVec( \@spline, \@indx, \@port1 );
>           }
> 
> 1st working sub:
> 
> sub printVec {
> #our @spline;
> #   my (@spline,@indx,@port) = @_ ;
> #   print "pre @$spl, @$indx, @$port\n";
> #   print "spline @spline\n";
>     my ($spl,$indx,$port) = @_ ;
>     my @prt = @$port ;
>     my @ndx = @$indx ;
>     my @spline = @$spl ;
> 
> 2nd call:
> 
>        &printTset( \@indx, $vect, $cmmnt ) ;
>        }
> 
> 2nd working sub:
> 
> sub printTset {
>     my ( $indx, $vct, $cmt) = @_ ;
>     my @ndx = @$indx;
>     my $vect = $vct;
>     my $cmmnt = $cmt;
> 
> if i don't use the \ on the passed parameters, it seems to merge them
> all into one big array.. blahh.
> 
> this seems like a lot of code, seemingly redundant to my wee perl mind,
> to pass values to a subroutine.
> 
> what magic am i missing or is this just the way it is???

	If you pass an array to a sub, you are actually
	passing a LIST of all the members of the array.

	Inside the sub, the code has no way to determine
	how many of the items in @_ are part of each array.
	If you only need to pass one array and some scalars,
	pass the scalars FIRST, then everything else is part
	of the array.  To pass multiple arrays, you either
	pass references as you did with the \ or you must
	pass some indications so the sub can figure out
	how many items from @_ belong in each array.  I
	think the references are the preferred/simplest
	method.

		Mike


------------------------------

Date: Fri, 15 Aug 2003 11:58:54 -0700
From: "David Oswald" <spamblock@junkmail.com>
Subject: Re: question regarding multiple args to sub
Message-Id: <vjqblmol24he1f@corp.supernews.com>


"Michael P. Broida" <michael.p.broida@boeing.com> wrote in message
news:3F3D21DD.F1EB42A1@boeing.com...


> If you pass an array to a sub, you are actually
> passing a LIST of all the members of the array.
>
> Inside the sub, the code has no way to determine
> how many of the items in @_ are part of each array.
> If you only need to pass one array and some scalars,
> pass the scalars FIRST, then everything else is part
> of the array.  To pass multiple arrays, you either
> pass references as you did with the \ or you must
> pass some indications so the sub can figure out
> how many items from @_ belong in each array.  I
> think the references are the preferred/simplest
> method.

It should be noted that this is considered a feature rather than a bug.
When passing complex data structures you pretty much have to pass a
reference, but that eliminates the duplication of said data structure.
Plus, it enables the function to be redesigned internally without
necessarily breaking the external program, and vice versa.  With the C
style, or Pascal style of passing structs you end up having to remodel the
subroutine's parameter list when minor changes are made to the shape of the
data structure.  I guess what I'm getting at is that the Perl way is
extremely flexible and powerful, and extensable, and adaptable, but perhaps
a little tricky to get used to.

Dave




------------------------------

Date: Fri, 15 Aug 2003 13:37:17 -0400
From: Eric Amick <eric-amick@comcast.net>
Subject: Re: Regex capture variable scoping
Message-Id: <hq5qjvcn7rfgvobkgd6tc9c5svj6bpkrdr@4ax.com>

On 15 Aug 2003 06:36:01 -0700, lbjay@reallywow.com (LBJ) wrote:

>Can someone please help me understand what I'm seeing as a
>contradiction between a statement in the perlre man page and a bug in
>a script that just bit me in the a**?
>
>From perlre: 
>"The numbered variables ($1, $2, $3, etc.) and the related
>punctuation set ($+, $&, $`, and $') are all dynamically
>scoped until the end of the enclosing block or until the
>next successful match, whichever comes first."
>
>And here's the code in question:
>
># looping through a fairly standard apache log
>while (<LOGFILE>)
>{
>	# grab the datestamp and querystring
>	m/\s\[([^\s]+) \-\d+\] "[A-Z]+ [^\?\s]+\?([^\s]+)/;
>
>	my ($date, $querystring) = ($1, $2);
>
>	if ($querystring)
>	{
>		....
>	}
>}
>
>The "bug" here is that $2 seems to not get unset for each iteration of
>the while loop. When the loop gets to a line that doesn't match a
>querystring value, $querystring is getting assigned the value of the
>previous line's $2 capture buffer.

You can get what you want by combining the two statements:

my ($date, $querystring) = 
	m/\s\[([^\s]+) \-\d+\] "[A-Z]+ [^\?\s]+\?([^\s]+)/;

A failed pattern match returns an empty list in list context.

-- 
Eric Amick
Columbia, MD


------------------------------

Date: 15 Aug 2003 12:45:27 -0700
From: tabletdesktop@yahoo.com (MJS)
Subject: Saving entire file
Message-Id: <f0171209.0308151145.5f23af6d@posting.google.com>

Can someone help me with the following code.
It just saves/prints the line in which 'hello' occured. 
why doesn't it save the entire file i.e why don't i get the entire
content of file1 in file2 ?

open(FILEREAD, "file1") or die "Can't open file1: $!\n";

while(<FILEREAD>) {
#searching the string
  if(/hello/) {

      open(FILEWRITE, ">file2") or die "Can't open file2: $!\n";
      select FILEWRITE; # this is not needed.
      print FILEWRITE ;
      close(FILEWRITE);
   }
}
close(FILEREAD);


------------------------------

Date: Fri, 15 Aug 2003 22:09:37 +0200
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: Saving entire file
Message-Id: <bhjemb$8bvc$1@ID-184292.news.uni-berlin.de>

MJS wrote:
> Can someone help me with the following code.
> It just saves/prints the line in which 'hello' occured.
> why doesn't it save the entire file i.e why don't i get the entire 
> content of file1 in file2 ?

Because you didn't tell Perl to do that. :)

> print FILEWRITE ;

That prints the content of $_ to FILEWRITE. Please study
http://www.perldoc.com/perl5.8.0/pod/perlsyn.html

If you replace that line with:

     seek FILEREAD, 0, 0;
     print FILEWRITE join '', <FILEREAD>;

the script should do what you want. You may want to reed about 'seek' 
and 'join' at http://www.perldoc.com/perl5.8.0/pod/perlfunc.html

There are (of course) other available solutions...

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl



------------------------------

Date: Fri, 15 Aug 2003 20:18:56 GMT
From: Mike Flannigan <mikeflan@earthlink.net>
Subject: Re: Saving entire file
Message-Id: <3F3D40C4.4B4A802@earthlink.net>


Gunnar Hjalmarsson wrote:

> MJS wrote:
> > Can someone help me with the following code.
> > It just saves/prints the line in which 'hello' occured.
> > why doesn't it save the entire file i.e why don't i get the entire
> > content of file1 in file2 ?
>
> Because you didn't tell Perl to do that. :)
>
> > print FILEWRITE ;
>
> That prints the content of $_ to FILEWRITE. Please study
> http://www.perldoc.com/perl5.8.0/pod/perlsyn.html
>
> If you replace that line with:
>
>      seek FILEREAD, 0, 0;
>      print FILEWRITE join '', <FILEREAD>;
>
> the script should do what you want. You may want to reed about 'seek'
> and 'join' at http://www.perldoc.com/perl5.8.0/pod/perlfunc.html
>
> There are (of course) other available solutions...

If I'm not mistaken, you also need to open the filewrite for
appending.

open(FILEWRITE, ">>file2") or die "Can't open file2: $!\n";
                                  ^
                                  ^



------------------------------

Date: Fri, 15 Aug 2003 22:24:37 +0200
From: Gunnar Hjalmarsson <noreply@gunnar.cc>
Subject: Re: Saving entire file
Message-Id: <bhjfig$7pkf$1@ID-184292.news.uni-berlin.de>

Mike Flannigan wrote:
> Gunnar Hjalmarsson wrote:
>>MJS wrote:
>>
>>>Can someone help me with the following code.
>>>It just saves/prints the line in which 'hello' occured.
>>>why doesn't it save the entire file i.e why don't i get the entire
>>>content of file1 in file2 ?
>>
>>Because you didn't tell Perl to do that. :)
>>
>>>print FILEWRITE ;
>>
>>That prints the content of $_ to FILEWRITE. Please study
>>http://www.perldoc.com/perl5.8.0/pod/perlsyn.html
>>
>>If you replace that line with:
>>
>>     seek FILEREAD, 0, 0;
>>     print FILEWRITE join '', <FILEREAD>;
>>
>>the script should do what you want. You may want to reed about 'seek'
>>and 'join' at http://www.perldoc.com/perl5.8.0/pod/perlfunc.html
>>
>>There are (of course) other available solutions...
> 
> If I'm not mistaken, you also need to open the filewrite for
> appending.
> 
> open(FILEWRITE, ">>file2") or die "Can't open file2: $!\n";

Only if appending is what OP wants to do. Note that it was opened for 
writing.

But I'd like to correct my solution in another respect. The 'join' 
function is redundant, and the following should do it:

     seek FILEREAD, 0, 0;
     print FILEWRITE <FILEREAD>;

-- 
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl



------------------------------

Date: Fri, 15 Aug 2003 20:58:18 GMT
From: Brian Harnish <bharn_S_ish@te_P_chnologi_A_st._M_com>
Subject: Re: Saving entire file
Message-Id: <pan.2003.08.15.20.58.54.98214@te_P_chnologi_A_st._M_com>

-----BEGIN xxx SIGNED MESSAGE-----
Hash: SHA1

On Fri, 15 Aug 2003 12:45:27 -0700, MJS wrote:

> Can someone help me with the following code.
> It just saves/prints the line in which 'hello' occured. 
> why doesn't it save the entire file i.e why don't i get the entire
> content of file1 in file2 ?
> 
> open(FILEREAD, "file1") or die "Can't open file1: $!\n";
> 
> while(<FILEREAD>) {
> #searching the string
>   if(/hello/) {
> 
>       open(FILEWRITE, ">file2") or die "Can't open file2: $!\n";
>       select FILEWRITE; # this is not needed.
>       print FILEWRITE ;
>       close(FILEWRITE);
>    }
> }
> close(FILEREAD);

Because you only told it to write out that one line. If you wanted all the
lines w/ /hello/ in them, move the open/close outside of the while loop. If
you want lines in addition to the ones that only have /hello/ in them,
remove the if() statement. 

 - Brian
-----BEGIN xxx SIGNATURE-----
Version: GnuPG v1.2.2 (GNU/Linux)
Comment: Seahorse v0.5.0 http://seahorse.sourceforge.net

iD8DBQE/PUlOiK/rA3tCpFYRApD7AKCiMCd7ExyjoT2pimd08ztJxPiRPgCgziDQ
rfm0Fgunb6JpXdRBNGmYpNk=
=MqPC
-----END PGP SIGNATURE-----



------------------------------

Date: Fri, 15 Aug 2003 11:28:01 -0400
From: Ted Zlatanov <tzz@lifelogs.com>
Subject: Re: Search Engine help
Message-Id: <4nptj7lz3y.fsf@lockgroove.bwh.harvard.edu>

On Fri, 15 Aug 2003, no.name@eidosnet.co.uk wrote:

> I am currently constructing a small search facility in perl for a
> website i am creating, and have become quite confused on a couple of
> things.
> 
> the datafile will be something like below;
> 
>     Name|Area|Website|etc...
> 
> My main confusion is when a user does a search and i wish to display
> the results to the user, i take it that i need to create a temporary
> page, so how do i create a temporary page to display the results in
> (when creating the temporary page how do i ensure that another user
> searching doesn't get the same temporary file as another user that
> is currently searching) and clear it up when the user closes his
> browser or leaves the site?
> 
> Hope i explained my self well enough :)

If I understand you correctly, you should consider using a database
table to hold things to be searched (web site areas? HTML pages?
URLs?) and creating indices on the search keys (keywords, names,
areas, etc.).  Then, you can write a very simple Class::DBI script to
do on-the-fly searching without using any intermediate data files.

The key thing is that you have to update the database table when web
site data is updated.  You can do this with scheduled updates, or by
triggering an update every time the web site pages are modified.

I am assuming here that you want to write your own search, and are
not interested in any of the existing solutions; if that's not true
then definitely look at the free searching software out there before
you write your own.  This is a problem that may be easily solved for
you without writing custom code.

Ted


------------------------------

Date: 15 Aug 2003 12:32:59 -0700
From: bricemason@hotmail.com (brice)
Subject: Status counter
Message-Id: <50404b7a.0308151132.2df9ef47@posting.google.com>

Hello,

I have a simple log file parsing program which includes a status
counter. This status counter prints to a new line each time so I get
the following:

Processing line 1
Processing line 2
Processing line 3
 ...
Processing line n

Does anyone know how to create a more dynamic status counter that
would use just one line? In other words, I just want the line number
to be updated on one line. I would think this is a common issue but I
couldn't find this topic anywhere. Any help you can offer is greatly
appreciated.

Thanks,

brice


------------------------------

Date: 15 Aug 2003 20:17:12 GMT
From: Nicholas Dronen <ndronen@io.frii.com>
Subject: Re: Status counter
Message-Id: <3f3d3fc8$0$191$75868355@news.frii.net>

brice <bricemason@hotmail.com> wrote:
b> Hello,

b> I have a simple log file parsing program which includes a status
b> counter. This status counter prints to a new line each time so I get
b> the following:

b> Processing line 1
b> Processing line 2
b> Processing line 3
b> ...
b> Processing line n

b> Does anyone know how to create a more dynamic status counter that
b> would use just one line? In other words, I just want the line number
b> to be updated on one line. I would think this is a common issue but I
b> couldn't find this topic anywhere. Any help you can offer is greatly
b> appreciated.

$ perl -e '$|++; $i=0; while (1) { print $i++; sleep 1; print "\r" }'

-- 
"Why shouldn't I top-post?"    http://www.aglami.com/tpfaq.html
"Meanings are another story."  http://www.ifas.org/wa/glossolalia.html


------------------------------

Date: Fri, 15 Aug 2003 23:11:15 +0200
From: Tore Aursand <tore@aursand.no>
Subject: Re: Status counter
Message-Id: <pan.2003.08.15.21.11.15.639940@aursand.no>

On Fri, 15 Aug 2003 12:32:59 -0700, brice wrote:
> Does anyone know how to create a more dynamic status counter that
> would use just one line?

Take a look at Term::ProgressBar;

  my $bar = Term::ProgressBar->new({name => 'Processing...', count => 10});
  for ( 1 .. 10 ) {
      $bar->update();
  }


-- 
Tore Aursand <tore@aursand.no>


------------------------------

Date: Sat, 19 Jul 2003 01:59:56 GMT
From: Bob Walton <bwalton@rochester.rr.com>
Subject: Re: 
Message-Id: <3F18A600.3040306@rochester.rr.com>

Ron wrote:

> Tried this code get a server 500 error.
> 
> Anyone know what's wrong with it?
> 
> if $DayName eq "Select a Day" or $RouteName eq "Select A Route") {

(---^


>     dienice("Please use the back button on your browser to fill out the Day
> & Route fields.");
> }
 ...
> Ron

 ...
-- 
Bob Walton



------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V10 Issue 5368
***************************************


home help back first fref pref prev next nref lref last post