stas        2003/08/29 19:33:26

  Modified:    lib/Apache compat.pm
               lib/ModPerl WrapXS.pm
               src/modules/perl modperl_util.c modperl_util.h
               xs/Apache/RequestUtil Apache__RequestUtil.h
               xs/maps  modperl_functions.map
               xs/tables/current/ModPerl FunctionTable.pm
               .        Changes
  Added:       t/api    slurp_filename.t
               t/response/TestAPI slurp_filename.pm
               t/htdocs/api slurp.pl
  Log:
  $r->slurp_filename is now implemented in C
  
  Revision  Changes    Path
  1.88      +0 -9      modperl-2.0/lib/Apache/compat.pm
  
  Index: compat.pm
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/lib/Apache/compat.pm,v
  retrieving revision 1.87
  retrieving revision 1.88
  diff -u -u -r1.87 -r1.88
  --- compat.pm 5 Aug 2003 16:00:24 -0000       1.87
  +++ compat.pm 30 Aug 2003 02:33:26 -0000      1.88
  @@ -345,15 +345,6 @@
   
   *log_reason = \&log_error;
   
  -sub slurp_filename {
  -    my $r = shift;
  -    open my $fh, $r->filename;
  -    local $/;
  -    my $data = <$fh>;
  -    close $fh;
  -    return \$data;
  -}
  -
   #XXX: would like to have a proper implementation
   #that reads line-by-line as defined by $/
   #the best way will probably be to use perlio in 5.8.0
  
  
  
  1.61      +0 -2      modperl-2.0/lib/ModPerl/WrapXS.pm
  
  Index: WrapXS.pm
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/lib/ModPerl/WrapXS.pm,v
  retrieving revision 1.60
  retrieving revision 1.61
  diff -u -u -r1.60 -r1.61
  --- WrapXS.pm 8 Aug 2003 20:35:44 -0000       1.60
  +++ WrapXS.pm 30 Aug 2003 02:33:26 -0000      1.61
  @@ -726,8 +726,6 @@
                             'not in the Apache 2.0 API'],
       log_reason        => ['log_error',
                             'not in the Apache 2.0 API'],
  -    slurp_filename    => [undef,
  -                          'not in the mod_perl 2.0 API'],
       READLINE          => [undef, # XXX: to be resolved
                             ''],
       send_fd_length    => [undef,
  
  
  
  1.52      +51 -0     modperl-2.0/src/modules/perl/modperl_util.c
  
  Index: modperl_util.c
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_util.c,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -u -r1.51 -r1.52
  --- modperl_util.c    4 Mar 2003 09:42:42 -0000       1.51
  +++ modperl_util.c    30 Aug 2003 02:33:26 -0000      1.52
  @@ -668,3 +668,54 @@
           }
       }
   }
  +
  +#define SLURP_SUCCESS(action) \
  +    if (rc != APR_SUCCESS) { \
  +        SvREFCNT_dec(sv); \
  +        Perl_croak(aTHX_ "Error " action " '%s': %s ", r->filename, \
  +                   modperl_apr_strerror(rc)); \
  +    }
  +
  +MP_INLINE SV *modperl_slurp_filename(pTHX_ request_rec *r, int tainted)
  +{
  +    SV *sv;
  +    apr_status_t rc;
  +    apr_size_t size;
  +    apr_file_t *file;
  +    
  +    size = r->finfo.size;
  +    sv = newSV(size);
  +    file = r->finfo.filehand;
  +    if (!file) {
  +        rc = apr_file_open(&file, r->filename, APR_READ|APR_BINARY,
  +                           APR_OS_DEFAULT, r->pool);
  +        SLURP_SUCCESS("opening");
  +    }
  +
  +    rc = apr_file_read(file, SvPVX(sv), &size);
  +    SLURP_SUCCESS("reading");
  +
  +    MP_TRACE_o(MP_FUNC, "read %d bytes from '%s'\n", size, r->filename);
  +    
  +    if (r->finfo.size != size) {
  +        SvREFCNT_dec(sv); 
  +        Perl_croak(aTHX_ "Error: read %d bytes, expected %d ('%s')",
  +                   size, r->finfo.size, r->filename);
  +    }
  +
  +    rc = apr_file_close(file);
  +    SLURP_SUCCESS("closing");
  +    
  +    SvPVX(sv)[size] = '\0';
  +    SvCUR_set(sv, size);
  +    SvPOK_on(sv);
  +
  +    if (tainted) {
  +        SvTAINTED_on(sv);
  +    }
  +    else {
  +        SvTAINTED_off(sv);
  +    }
  +    
  +    return newRV_noinc(sv);
  +}
  
  
  
  1.46      +8 -0      modperl-2.0/src/modules/perl/modperl_util.h
  
  Index: modperl_util.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_util.h,v
  retrieving revision 1.45
  retrieving revision 1.46
  diff -u -u -r1.45 -r1.46
  --- modperl_util.h    20 Aug 2003 23:11:23 -0000      1.45
  +++ modperl_util.h    30 Aug 2003 02:33:26 -0000      1.46
  @@ -141,6 +141,14 @@
   
   MP_INLINE int modperl_perl_module_loaded(pTHX_ const char *name);
   
  +/**
  + * slurp the contents of r->filename and return them as a scalar
  + * @param r       request record
  + * @param tainted whether the SV should be marked tainted or not
  + * @return a PV scalar with the contents of the file
  + */
  +SV *modperl_slurp_filename(pTHX_ request_rec *r, int tainted);
  +
   SV *modperl_perl_gensym(pTHX_ char *pack);
   
   void modperl_clear_symtab(pTHX_ HV *symtab);
  
  
  
  1.18      +3 -0      modperl-2.0/xs/Apache/RequestUtil/Apache__RequestUtil.h
  
  Index: Apache__RequestUtil.h
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/xs/Apache/RequestUtil/Apache__RequestUtil.h,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -u -r1.17 -r1.18
  --- Apache__RequestUtil.h     31 Jan 2003 04:20:20 -0000      1.17
  +++ Apache__RequestUtil.h     30 Aug 2003 02:33:26 -0000      1.18
  @@ -197,6 +197,9 @@
   #define mpxs_Apache__RequestRec_dir_config(r, key, sv_val) \
       modperl_dir_config(aTHX_ r, r->server, key, sv_val)
   
  +#define mpxs_Apache__RequestRec_slurp_filename(r, tainted) \
  +    modperl_slurp_filename(aTHX_ r, tainted)
  +
   static MP_INLINE
   char *mpxs_Apache__RequestRec_location(request_rec *r)
   {
  
  
  
  1.58      +2 -0      modperl-2.0/xs/maps/modperl_functions.map
  
  Index: modperl_functions.map
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/xs/maps/modperl_functions.map,v
  retrieving revision 1.57
  retrieving revision 1.58
  diff -u -u -r1.57 -r1.58
  --- modperl_functions.map     30 May 2003 12:55:14 -0000      1.57
  +++ modperl_functions.map     30 Aug 2003 02:33:26 -0000      1.58
  @@ -33,6 +33,8 @@
   PACKAGE=Apache::RequestRec
    mpxs_Apache__RequestRec_new | | classname, c, base_pool=NULL
    SV *:DEFINE_dir_config | | request_rec *:r, char *:key=NULL, SV *:sv_val=Nullsv
  + SV *:DEFINE_slurp_filename | | request_rec *:r, int:tainted=1
  +
   PACKAGE=Apache
    mpxs_Apache_request | | classname, svr=Nullsv
   
  
  
  
  1.121     +21 -0     modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm
  
  Index: FunctionTable.pm
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/xs/tables/current/ModPerl/FunctionTable.pm,v
  retrieving revision 1.120
  retrieving revision 1.121
  diff -u -u -r1.120 -r1.121
  --- FunctionTable.pm  28 Aug 2003 18:33:32 -0000      1.120
  +++ FunctionTable.pm  30 Aug 2003 02:33:26 -0000      1.121
  @@ -1569,6 +1569,27 @@
       ]
     },
     {
  +    'return_type' => 'SV *',
  +    'name' => 'modperl_slurp_filename',
  +    'attr' => [
  +      '__inline__'
  +    ],
  +    'args' => [
  +      {
  +        'type' => 'PerlInterpreter *',
  +        'name' => 'my_perl'
  +      },
  +      {
  +        'type' => 'request_rec *',
  +        'name' => 'r'
  +      },
  +      {
  +        'type' => 'int',
  +        'name' => 'tainted'
  +      },
  +    ]
  +  },
  +  {
       'return_type' => 'void',
       'name' => 'modperl_env_clear',
       'args' => [
  
  
  
  1.213     +2 -0      modperl-2.0/Changes
  
  Index: Changes
  ===================================================================
  RCS file: /home/cvs/modperl-2.0/Changes,v
  retrieving revision 1.212
  retrieving revision 1.213
  diff -u -u -r1.212 -r1.213
  --- Changes   22 Aug 2003 19:18:03 -0000      1.212
  +++ Changes   30 Aug 2003 02:33:26 -0000      1.213
  @@ -12,6 +12,8 @@
   
   =item 1.99_10-dev
   
  +$r->slurp_filename is now implemented in C. [Stas]
  +
   remove support for httpd 2.0.45/apr 0.9.3 and lower.
   httpd 2.0.46 is now the minimum supported version.
   [Geoffrey Young]
  
  
  
  1.1                  modperl-2.0/t/api/slurp_filename.t
  
  Index: slurp_filename.t
  ===================================================================
  use Apache::TestRequest 'GET_BODY_ASSERT';
  
  # we want r->filename to be "/slurp/slurp.pl", even though the
  # response handler is TestAPI::slurp_filename
  
  print GET_BODY_ASSERT "/slurp/slurp.pl";
  
  
  
  1.1                  modperl-2.0/t/response/TestAPI/slurp_filename.pm
  
  Index: slurp_filename.pm
  ===================================================================
  package TestAPI::slurp_filename;
  
  # test slurp_filename()'s taintness options and the that it works properly with utf8 
data
  
  use strict;
  use warnings FATAL => 'all';
  no warnings 'redefine';
  
  use diagnostics;
  
  use Apache::Test;
  use Apache::TestUtil;
  
  use Apache::RequestUtil ();
  use ModPerl::Util;
  
  use Apache::Const -compile => 'OK';
  
  my $expected = <<EOI;
  English: Internet
  Hebrew : \x{05D0}\x{05D9}\x{05E0}\x{05D8}\x{05E8}\x{05E0}\x{05D8}
  EOI
  
  sub handler {
      my $r = shift;
  
      plan $r, tests => 5;
  
      {
          my $data = $r->slurp_filename(0); # untainted
          my $received = eval $$data;
          ok t_cmp($expected, $received, "slurp filename untainted");
      }
  
      {
          my $data = $r->slurp_filename; # tainted
          my $received;
          eval { $received = eval $$data };
          ok t_cmp(qr/Insecure dependency in eval/, $@, "slurp filename tainted");
  
          ModPerl::Util::untaint($$data);
          $received = eval $$data;
          ok t_cmp($expected, $received, "slurp filename untainted");
      }
  
      {
          # just in case we will encounter some probs in the future,
          # here is pure perl function for comparison
          my $data = slurp_filename_perl($r); # tainted
          my $received;
          eval { $received = eval $$data };
          ok t_cmp(qr/Insecure dependency in eval/, $@, "slurp filename (perl) 
tainted");
  
          ModPerl::Util::untaint($$data);
          $received = eval $$data;
          ok t_cmp($expected, $received, "slurp filename (perl) untainted");
      }
  
      Apache::OK;
  }
  
  sub slurp_filename_perl {
      my $r = shift;
      open my $fh, $r->filename;
      local $/;
      my $data = <$fh>;
      close $fh;
      return \$data;
  }
  
  1;
  __END__
  <NoAutoConfig>
      Alias /slurp/ @DocumentRoot@/api/
      <Location /slurp/>
          SetHandler modperl
          PerlResponseHandler TestAPI::slurp_filename
      </Location>
  </NoAutoConfig>
  
  
  
  1.1                  modperl-2.0/t/htdocs/api/slurp.pl
  
  Index: slurp.pl
  ===================================================================
  my $z = <<EOI;
  English: Internet
  Hebrew : \x{05D0}\x{05D9}\x{05E0}\x{05D8}\x{05E8}\x{05E0}\x{05D8}
  EOI
  $z;
  
  
  

Reply via email to