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;