Hi,
  I'm submitting a 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 only defined upon request of the corresponding
digest.

The patch was produced against the current CVS version of rfc1867.c
(PHP_4_3 branch, v1.122.2.14).

Cheers,
 David
-- 
 David Santinoli, Milano             +   <[EMAIL PROTECTED]>
 Independent Linux/Unix consultant   +   http://www.santinoli.com
--- main/rfc1867.c.orig 2003-10-27 19:21:26.000000000 +0100
+++ main/rfc1867.c      2003-10-27 19:31:35.000000000 +0100
@@ -31,6 +31,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"
@@ -699,6 +701,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 HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
        int str_len=0;
 #endif
@@ -821,6 +830,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);
@@ -872,6 +885,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)) {
@@ -882,6 +903,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);
@@ -893,6 +921,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);
@@ -1025,6 +1062,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