Hi,
  I'm submitting a patch (previously sent to php-dev as suggested in
the [obsolete?] README.SUBMITTING_PATCH) to perform "on the fly"
MD5/SHA1 digest calculation of a file uploaded via the HTTP POST method.
Since it is not uncommon for applications to require some digest of a
freshly uploaded file, doing the math directly in the buffer where the
file is being read can save some time.

Digest calculation is triggered by setting the special input fields
COMPUTE_MD5 and/or COMPUTE_SHA1 to a non-zero value:

  <input type="hidden" name="COMPUTE_SHA1" value="1">

(note that these assignments must precede the 
<input type="file" name=...> field, as in the MAX_FILE_SIZE case.)

The result is found in the special variables
$_FILES[userfile]["md5"] and $_FILES[userfile]["sha1"].
These variables are defined only upon request of the corresponding
digest.

The patch was produced against rfc1867.c v1.137, but applies to the
current CVS file (v1.141) as well.

Cheers,
 David
-- 
 David Santinoli, Milano             +   <[EMAIL PROTECTED]>
 Independent Linux/Unix consultant   +   http://www.santinoli.com
--- rfc1867.c.cvs       2003-06-25 16:54:28.000000000 +0200
+++ rfc1867.c   2003-06-25 16:58:40.000000000 +0200
@@ -32,6 +32,8 @@
 #include "php_globals.h"
 #include "php_variables.h"
 #include "rfc1867.h"
+#include "ext/standard/md5.h"
+#include "ext/standard/sha1.h"
 
 #if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
 #include "ext/mbstring/mbstring.h"
@@ -697,6 +699,13 @@
        zval *array_ptr = (zval *) arg;
        FILE *fp;
        zend_llist header;
+       int compute_md5=0, compute_sha1=0;
+       PHP_MD5_CTX md5_context;
+       unsigned char md5_digest[16];
+       char md5_string[33];
+       PHP_SHA1_CTX sha1_context;
+       unsigned char sha1_digest[20];
+       char sha1_string[41];
 
        if (SG(request_info).content_length > SG(post_max_size)) {
                sapi_module.sapi_error(E_WARNING, "POST Content-Length of %d bytes 
exceeds the limit of %d bytes", SG(request_info).content_length, SG(post_max_size));
@@ -809,6 +818,10 @@
                                safe_php_register_variable(param, value, array_ptr, 0 
TSRMLS_CC);
                                if (!strcasecmp(param, "MAX_FILE_SIZE")) {
                                        max_file_size = atol(value);
+                               } else if (!strcasecmp(param, "COMPUTE_MD5")) {
+                                       compute_md5 = atol(value);
+                               } else if (!strcasecmp(param, "COMPUTE_SHA1")) {
+                                       compute_sha1 = atol(value);
                                }
 
                                efree(param);
@@ -859,6 +872,14 @@
                                cancel_upload = UPLOAD_ERROR_D;
                        }
 
+                       if (compute_md5) {
+                               PHP_MD5Init(&md5_context);
+                       }
+
+                       if (compute_sha1) {
+                               PHP_SHA1Init(&sha1_context);
+                       }
+
                        while (!cancel_upload && (blen = multipart_buffer_read(mbuff, 
buff, sizeof(buff) TSRMLS_CC)))
                        {
                                if (PG(upload_max_filesize) > 0 && total_bytes > 
PG(upload_max_filesize)) {
@@ -869,6 +890,13 @@
                                        cancel_upload = UPLOAD_ERROR_B;
                                } else if (blen > 0) {
                                        wlen = fwrite(buff, 1, blen, fp);
+
+                                       if (compute_md5) {
+                                               PHP_MD5Update(&md5_context, buff, 
blen);
+                                       }
+                                       if (compute_sha1) {
+                                               PHP_SHA1Update(&sha1_context, buff, 
blen);
+                                       }
                        
                                        if (wlen < blen) {
                                                sapi_module.sapi_error(E_WARNING, 
"Only %d bytes were written, expected to write %ld", wlen, blen);
@@ -880,6 +908,15 @@
                        } 
                        fclose(fp);
 
+                       if (compute_md5) {
+                               PHP_MD5Final(md5_digest, &md5_context);
+                               make_digest(md5_string, md5_digest);
+                       }
+                       if (compute_sha1) {
+                               PHP_SHA1Final(sha1_digest, &sha1_context);
+                               make_digest(sha1_string, sha1_digest);
+                       }
+
 #ifdef DEBUG_FILE_UPLOAD
                        if(strlen(filename) > 0 && total_bytes == 0) {
                                sapi_module.sapi_error(E_WARNING, "Uploaded file size 
0 - file [%s=%s] not saved", param, filename);
@@ -1014,6 +1051,26 @@
                        add_protected_variable(lbuf TSRMLS_CC);
                        register_http_post_files_variable(lbuf, temp_filename, 
http_post_files, 1 TSRMLS_CC);
 
+                       /* Add $foo[md5] */
+                       if (!cancel_upload && compute_md5) {
+                               if (is_arr_upload) {
+                                       sprintf(lbuf, "%s[md5][%s]", abuf, 
array_index);
+                               } else {
+                                       sprintf(lbuf, "%s[md5]", param);
+                               }
+                               register_http_post_files_variable(lbuf, md5_string, 
http_post_files, 0 TSRMLS_CC);
+                       }
+
+                       /* Add $foo[sha1] */
+                       if (!cancel_upload && compute_sha1) {
+                               if (is_arr_upload) {
+                                       sprintf(lbuf, "%s[sha1][%s]", abuf, 
array_index);
+                               } else {
+                                       sprintf(lbuf, "%s[sha1]", param);
+                               }
+                               register_http_post_files_variable(lbuf, sha1_string, 
http_post_files, 0 TSRMLS_CC);
+                       }
+
                        PG(magic_quotes_gpc) = magic_quotes_gpc;
 
                        {

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to