This file is indexed.

/usr/lib/perl5/Parse/ePerl.pm is in eperl 2.2.14-18.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
##        ____           _ 
##    ___|  _ \ ___ _ __| |
##   / _ \ |_) / _ \ '__| |
##  |  __/  __/  __/ |  | |
##   \___|_|   \___|_|  |_|
## 
##  ePerl -- Embedded Perl 5 Language
##
##  ePerl interprets an ASCII file bristled with Perl 5 program statements
##  by evaluating the Perl 5 code while passing through the plain ASCII
##  data. It can operate both as a standard Unix filter for general file
##  generation tasks and as a powerful Webserver scripting language for
##  dynamic HTML page programming. 
##
##  ======================================================================
##
##  Copyright (c) 1996,1997 Ralf S. Engelschall, All rights reserved.
##
##  This program is free software; it may be redistributed and/or modified
##  only under the terms of either the Artistic License or the GNU General
##  Public License, which may be found in the ePerl source distribution.
##  Look at the files ARTISTIC and COPYING or run ``eperl -l'' to receive
##  a built-in copy of both license files.
##
##  This program is distributed in the hope that it will be useful, but
##  WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See either the
##  Artistic License or the GNU General Public License for more details.
##
##  ======================================================================
##
##  ePerl.pm -- Perl interface to the ePerl parser (Perl part)
##

package Parse::ePerl;


#   requirements and runtime behaviour
require 5.00325;
use strict;
use vars qw($VERSION @ISA @EXPORT $AUTOLOAD);

#   imports
require Exporter;
require DynaLoader;
require AutoLoader;
use Carp;
use Cwd qw(fastcwd);
#use Safe;

#   interface
@ISA    = qw(Exporter DynaLoader);
@EXPORT = qw();

#   private version number
$VERSION = do { my @v=("2.2.14"=~/\d+/g); sprintf "%d."."%02d"x$#v,@v }; 

#   dynaloader bootstrapping
bootstrap Parse::ePerl $VERSION;


#   untainting a variable: for restricted environments like 
#   Apache/mod_perl under which our caller Apache::ePerl could run
sub Untaint {
   my ($var) = @_;

   #   see perlsec(1)
   ${$var} =~ m|^(.*)$|s;
   ${$var} = $1;
}


##
##  Preprocess -- run the ePerl preprocessor over the script
##                which expands #include directives
##

sub Preprocess ($) {
    my ($p) = @_;
    my ($result, $ocwd);

    #   error if no input or no output
    if (   not $p->{Script}
        || not $p->{Result}) {
        return 0;
    }

    #   set defaults
    $p->{INC} ||= [ '.' ];
    $p->{BeginDelimiter}  ||= '<:';
    $p->{EndDelimiter}    ||= ':>';

    #   switch to directory of file
    if ($p->{Cwd}) {
        Untaint(\$p->{Cwd});
        $ocwd = fastcwd();
        chdir($p->{Cwd});
    }

    #   use XS part: PP (preprocessor)
    $result = PP(
        $p->{Script}, 
        $p->{INC},
        $p->{BeginDelimiter},
        $p->{EndDelimiter}
    );

    #   restore Cwd
    chdir($ocwd) if ($p->{Cwd});

    if ($result eq '') {
        return 0;
    }
    else {
        ${$p->{Result}} = $result;
        return 1;
    }
}


##
##  Translate -- translate a plain Perl script from 
##               bristled code to plain Perl code
##

sub Translate ($) {
    my ($p) = @_;
    my ($result);

    #   error if no input or no output
    if (   not $p->{Script}
        || not $p->{Result}) {
        return 0;
    }

    #   set defaults
    $p->{BeginDelimiter}  ||= '<:';
    $p->{EndDelimiter}    ||= ':>';
    $p->{CaseDelimiters}  ||= 0;
    $p->{ConvertEntities} ||= 0;

    #   use XS part: Bristled2Plain
    $result = Bristled2Plain(
        $p->{Script}, 
        $p->{BeginDelimiter},
        $p->{EndDelimiter},
        $p->{CaseDelimiters},
        $p->{ConvertEntities}
    );

    if ($result eq '') {
        return 0;
    }
    else {
        ${$p->{Result}} = $result;
        return 1;
    }
}


##
##  Precompile -- precompile a plain Perl script to 
##                internal Perl code (P-code) by storing
##                the script into a subroutine
##

sub Precompile ($) {
    my ($p) = @_;
    my ($error, $func, $ocwd);

    #   error if no input or no output
    if (   not $p->{Script}
        || not $p->{Result}) {
        return 0;
    }

    #   capture the warning messages which
    #   usually are send to STDERR and
    #   disable the die of the interpreter
    $error = '';
    local $SIG{'__WARN__'} = sub { $error .= $_[0]; };
    local $SIG{'__DIE__'};

    #   switch to directory of file
    if ($p->{Cwd}) {
        Untaint(\$p->{Cwd});
        $ocwd = fastcwd();
        chdir($p->{Cwd});
    }

    #   precompile the source into P-code
    #my $cp = new Safe("Safe::ePerl");
    #$func = $cp->reval('$func = sub {'.$p->{Script}.'};');
    Untaint(\$p->{Script});
    eval("\$func = sub {" . $p->{Script} . "};");
    $error = "$@" if ($@);

    #   restore Cwd
    chdir($ocwd) if ($p->{Cwd});

    #   return the result
    if ($error) {
        $error =~ s|\(eval \d+\)|$p->{Name}| if ($p->{Name});
        ${$p->{Error}} = $error if ($p->{Error});
        $@ = $error;
        return 0;
    }
    else {
        ${$p->{Result}} = $func;
        $@ = '';
        return 1;
    }
}


##
##  Evaluate -- evaluate a script which is either
##              give as a P-code reference or as
##              a plain Perl script

sub Evaluate ($) {
    my ($p) = @_;
    my ($stdout, $stderr, %OENV, $ocwd);
    my ($result, $error);

    #   error if no input or no output
    if (   not $p->{Script}
        || not $p->{Result}) {
        return 0;
    }

    #   capture STDOUT and STDERR
    $stdout = tie(*STDOUT, 'Parse::ePerl');
    $stderr = tie(*STDERR, 'Parse::ePerl');

    #   setup the environment
    if ($p->{ENV}) {
        %OENV = %ENV;
        %ENV  = %{$p->{ENV}};
    }

    #   switch to directory of file
    if ($p->{Cwd}) {
        $ocwd = fastcwd();
        chdir($p->{Cwd});
    }

    #   capture the warning messages which
    #   usually are send to STDERR (and which
    #   cannot be captured by our tie!) plus
    #   disable the die of the interpreter
    $error = '';
    local $SIG{'__WARN__'} = sub { $error .= $_[0]; };
    local $SIG{'__DIE__'}  = sub { $error .= $_[0]; };

    #   now evaluate the script which 
    #   produces content on STDOUT and perhaps
    #   additionally on STDERR
    if (ref($p->{Script})) {
        #   a P-code reference
        &{$p->{Script}};
    }
    else {
        #   a plain code string
        eval $p->{Script};
    }

    #   retrieve captured data from STDOUT
    $result = ${$stdout};

    #   retrieve either the error message 
    #   (on syntax errors) or the generated data 
    #   on STDERR (when generated by the script)
    $error ||= ${$stderr};
    $error =~ s|\(eval \d+\)|$p->{Name}| if (defined($error) && $p->{Name});

    #   restore Cwd
    chdir($ocwd) if ($p->{Cwd});

    #   restore environment
    %ENV = %OENV if ($p->{ENV});

    #   remove capturing mode from STDOUT/STDERR
    undef($stdout);
    undef($stderr);
    untie(*STDOUT);
    untie(*STDERR);

    #   set the result
    ${$p->{Result}} = $result;
    ${$p->{Error}}  = $error if ($p->{Error});

    #   return the result codes
    if ($error) {
        $@ = $error;
        return 0;
    }
    else {
        $@ = '';
        return 1;
    }
}


##
##  Expand -- the steps Translate & Evaluate
##            just combined into one step
##

sub Expand ($) {
    my ($p) = @_;
    my ($rc, $script);

    #   error if no input or no output
    if (   not $p->{Script}
        || not $p->{Result}) {
        return 0;
    }

    if (not Translate($p)) {
        return 0;
    }
    $script = $p->{Script};
    $p->{Script} = ${$p->{Result}};
    $rc = Evaluate($p);
    $p->{Script} = $script;
    return $rc;
}


##
##  Capture -- methods for capturing a filehandle
##             (used by Evaluate) via this class
##

sub TIEHANDLE {
    my ($class, $c) = @_;
    return bless(\$c,$class);
}

sub PRINT {
    my ($self) = shift;
    ${$self} .= join('', @_);
}

sub PRINTF {
    my ($self) = shift;
    my ($fmt) = shift;
    ${$self} .= sprintf($fmt, @_);
}


#   sometimes Perl wants it...
sub DESTROY { };


1;
##EOF##
__END__

=head1 NAME

Parse::ePerl - Perl interface to the ePerl parser

=head1 SYNOPSIS

  use Parse::ePerl;

  $rc = Parse::ePerl::Preprocess($p);
  $rc = Parse::ePerl::Translate($p);
  $rc = Parse::ePerl::Precompile($p);
  $rc = Parse::ePerl::Evaluate($p);
  $rc = Parse::ePerl::Expand($p);

=head1 DESCRIPTION

Parse::ePerl is the Perl 5 interface package to the functionality of the ePerl
parser (see eperl(1) for more details about the stand-alone program). It
directly uses the parser code from ePerl to translate a bristled script into a
plain Perl script and additionally provides functions to precompile such
scripts into P-code and evaluate those scripts to a buffer.

All functions are parameterized via a hash reference C<$p> which provide the
necessary parameters. The result is a return code C<$rc> which indicates
success (1) or failure (0).

=head2 B<PREPROCESSOR: $rc = Parse::ePerl::Preprocess($p)>

This is the ePerl preprocessor which expands C<#include> directives.
See eperl(1) for more details.

Possible parameters for C<$p>:

=over 4

=item I<Script>

Scalar holding the input script in source format.

=item I<Result>

Reference to scalar receiving the resulting script in bristled Perl format.

=item I<BeginDelimiter>

Scalar specifying the begin delimiter.  Default is ``C<E<lt>:>''.

=item I<EndDelimiter>

Scalar specifying the end delimiter.  Default is ``C<:E<gt>>''.

=item I<INC>

A reference to a list specifying include directories. Default is C<\@INC>.

=back

=head2 B<TRANSLATION: $rc = Parse::ePerl::Translate($p)>

This is the actual ePerl parser, i.e. this function converts a bristled
ePerl-style script (provided in C<$p->{Script}> as a scalar) to a plain Perl
script. The resulting script is stored into a buffer provided via a scalar
reference in C<$p->{Result}>. The translation is directly done by the original
C function Bristled2Plain() from ePerl, so the resulting script is exactly the
same as with the stand-alone program F<eperl>.

Possible parameters for C<$p>:

=over 4

=item I<Script>

Scalar holding the input script in bristled format.

=item I<Result>

Reference to scalar receiving the resulting script in plain Perl format.

=item I<BeginDelimiter>

Scalar specifying the begin delimiter.  Default is ``C<E<lt>:>''.

=item I<EndDelimiter>

Scalar specifying the end delimiter.  Default is ``C<:E<gt>>''.

=item I<CaseDelimiters>

Boolean flag indicating if the delimiters are case-sensitive (1=default) or
case-insensitive (0).

=back

Example: The following code 

  $script = <<'EOT';
  foo
  <: print "bar"; :>
  quux
  EOT
  
  Parse::ePerl::Translate({
      Script => $script,
      Result => \$script,
  });

translates the script in C<$script> to the following plain Perl format:

  print "foo\n";
  print "bar"; print "\n";
  print "quux\n";

=head2 B<COMPILATION: $rc = Parse::ePerl::Precompile($p);>

This is an optional step between translation and evaluation where the plain
Perl script is compiled from ASCII representation to P-code (the internal Perl
bytecode). This step is used in rare cases only, for instance from within
Apache::ePerl(3) for caching purposes.

Possible parameters for C<$p>:

=over 4

=item I<Script>

Scalar holding the input script in plain Perl format, usually the result from
a previous Parse::ePerl::Translate(3) call.

=item I<Result>

Reference to scalar receiving the resulting code reference. This code can be
later directly used via the C<&$var> construct or given to the
Parse::ePerl::Evaluate(3) function.

=item I<Error>

Reference to scalar receiving possible error messages from the compilation
(e.g.  syntax errors).

=item I<Cwd>

Directory to switch to while precompiling the script.

=item I<Name>

Name of the script for informal references inside error messages.

=back

Example: The following code 

  Parse::ePerl::Precompile({
      Script => $script,
      Result => \$script,
  });

translates the plain Perl code (see above) in C<$script> to a code reference
and stores the reference again in C<$script>. The code later can be either
directly used via C<&$script> instead of C<eval($script)> or passed to the
Parse::ePerl::Evaluate(3) function.

=head2 B<EVALUATION: $rc = Parse::ePerl::Evaluate($p);>

Beside Parse::ePerl::Translate(3) this is the second main function of this
package. It is intended to evaluate the result of Parse::ePerl::Translate(3)
in a ePerl-like environment, i.e. this function tries to emulate the runtime
environment and behavior of the program F<eperl>. This actually means that it
changes the current working directory and evaluates the script while capturing
data generated on STDOUT/STDERR.

Possible parameters for C<$p>:

=over 4

=item I<Script>

Scalar (standard case) or reference to scalar (compiled case) holding the
input script in plain Perl format or P-code, usually the result from a
previous Parse::ePerl::Translate(3) or Parse::ePerl::Precompile(3) call.

=item I<Result>

Reference to scalar receiving the resulting code reference. 

=item I<Error>

Reference to scalar receiving possible error messages from the evaluation
(e.g. runtime errors).

=item I<ENV>

Hash containing the environment for C<%ENV> which should be used while
evaluating the script.

=item I<Cwd>

Directory to switch to while evaluating the script.

=item I<Name>

Name of the script for informal references inside error messages.

=back

Example: The following code 

  $script = <<'EOT';
  print "foo\n";
  print "bar"; print "\n";
  print "quux\n";
  EOT

  Parse::ePerl::Evaluate({
      Script => $script,
      Result => \$script,
  });

translates the script in C<$script> to the following plain data:

  foo
  bar
  quux

=head2 B<ONE-STEP EXPANSION: $rc = Parse::ePerl::Expand($p);>

This function just combines, Parse::ePerl::Translate(3) and
Parse::ePerl::Evaluate(3) into one step. The parameters in C<$p> are the union
of the possible parameters for both functions. This is intended as a
high-level interface for Parse::ePerl.

=head1 AUTHOR

 Ralf S. Engelschall
 rse@engelschall.com
 www.engelschall.com

=head1 SEE ALSO

eperl(1)

Web-References:

  Perl:  perl(1),  http://www.perl.com/
  ePerl: eperl(1), http://www.engelschall.com/sw/eperl/

=cut

##EOF##