Commit:    6bb3865a235d437d91df1940b0caad6995b69d4c
Author:    Anthony Ferrara <ircmax...@gmail.com>         Thu, 28 Jun 2012 
14:44:04 -0400
Parents:   0dd2f16b148f4054d65645b9cf971fe08824d78d
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=6bb3865a235d437d91df1940b0caad6995b69d4c

Log:
Refactor crypt to use an external working function

Changed paths:
  M  ext/standard/crypt.c
  M  ext/standard/php_crypt.h


Diff:
diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c
index 9a1fcf1..a592a4b 100644
--- a/ext/standard/crypt.c
+++ b/ext/standard/crypt.c
@@ -145,44 +145,9 @@ static void php_to64(char *s, long v, int n) /* {{{ */
 }
 /* }}} */
 
-/* {{{ proto string crypt(string str [, string salt])
-   Hash a string */
-PHP_FUNCTION(crypt)
+PHPAPI int crypt_execute(const char *password, const int pass_len, const char 
*salt, int salt_len, char **result)
 {
-       char salt[PHP_MAX_SALT_LEN + 1];
-       char *str, *salt_in = NULL;
-       int str_len, salt_in_len = 0;
        char *crypt_res;
-       salt[0] = salt[PHP_MAX_SALT_LEN] = '\0';
-
-       /* This will produce suitable results if people depend on DES-encryption
-        * available (passing always 2-character salt). At least for glibc6.1 */
-       memset(&salt[1], '$', PHP_MAX_SALT_LEN - 1);
-
-       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, 
&str_len, &salt_in, &salt_in_len) == FAILURE) {
-               return;
-       }
-
-       if (salt_in) {
-               memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len));
-       }
-
-       /* The automatic salt generation covers standard DES, md5-crypt and 
Blowfish (simple) */
-       if (!*salt) {
-#if PHP_MD5_CRYPT
-               strncpy(salt, "$1$", PHP_MAX_SALT_LEN);
-               php_to64(&salt[3], PHP_CRYPT_RAND, 4);
-               php_to64(&salt[7], PHP_CRYPT_RAND, 4);
-               strncpy(&salt[11], "$", PHP_MAX_SALT_LEN - 11);
-#elif PHP_STD_DES_CRYPT
-               php_to64(&salt[0], PHP_CRYPT_RAND, 2);
-               salt[2] = '\0';
-#endif
-               salt_in_len = strlen(salt);
-       } else {
-               salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len);
-       }
-
 /* Windows (win32/crypt) has a stripped down version of libxcrypt and 
        a CryptoApi md5_crypt implementation */
 #if PHP_USE_PHP_CRYPT_R
@@ -190,55 +155,52 @@ PHP_FUNCTION(crypt)
                struct php_crypt_extended_data buffer;
 
                if (salt[0]=='$' && salt[1]=='1' && salt[2]=='$') {
-                       char output[MD5_HASH_MAX_LEN];
-
-                       RETURN_STRING(php_md5_crypt_r(str, salt, output), 1);
+                       char output[MD5_HASH_MAX_LEN], *out;
+
+                       out = php_md5_crypt_r(password, salt, output);
+                       if (out) {
+                               *result = (char *) emalloc(MD5_HASH_MAX_LEN + 
1);
+                               memcpy(*result, out, MD5_HASH_MAX_LEN);
+                               *result[MD5_HASH_MAX_LEN] = 0;
+                               return SUCCESS;
+                       }
+                       return FAILURE;
                } else if (salt[0]=='$' && salt[1]=='6' && salt[2]=='$') {
                        const char sha512_salt_prefix[] = "$6$";
                        const char sha512_rounds_prefix[] = "rounds=";
                        char *output;
                        int needed = (sizeof(sha512_salt_prefix) - 1
                                                + sizeof(sha512_rounds_prefix) 
+ 9 + 1
-                                               + strlen(salt) + 1 + 43 + 1);
+                                               + PHP_MAX_SALT_LEN + 43 + 1);
                        output = emalloc(needed);
-                       salt[salt_in_len] = '\0';
 
-                       crypt_res = php_sha512_crypt_r(str, salt, output, 
needed);
+                       crypt_res = php_sha512_crypt_r(password, salt, output, 
needed);
                        if (!crypt_res) {
-                               if (salt[0]=='*' && salt[1]=='0') {
-                                       RETVAL_STRING("*1", 1);
-                               } else {
-                                       RETVAL_STRING("*0", 1);
-                               }
+                               memset(output, 0, needed);
+                               efree(output);
+                               return FAILURE;
                        } else {
-                               RETVAL_STRING(output, 1);
+                               *result = output;
+                               return SUCCESS;
                        }
-
-                       memset(output, 0, PHP_MAX_SALT_LEN + 1);
-                       efree(output);
                } else if (salt[0]=='$' && salt[1]=='5' && salt[2]=='$') {
                        const char sha256_salt_prefix[] = "$5$";
                        const char sha256_rounds_prefix[] = "rounds=";
                        char *output;
                        int needed = (sizeof(sha256_salt_prefix) - 1
                                                + sizeof(sha256_rounds_prefix) 
+ 9 + 1
-                                               + strlen(salt) + 1 + 43 + 1);
+                                               + PHP_MAX_SALT_LEN + 43 + 1);
                        output = emalloc(needed);
-                       salt[salt_in_len] = '\0';
 
-                       crypt_res = php_sha256_crypt_r(str, salt, output, 
needed);
+                       crypt_res = php_sha256_crypt_r(password, salt, output, 
needed);
                        if (!crypt_res) {
-                               if (salt[0]=='*' && salt[1]=='0') {
-                                       RETVAL_STRING("*1", 1);
-                               } else {
-                                       RETVAL_STRING("*0", 1);
-                               }
+                               memset(output, 0, needed);
+                               efree(output);
+                               return FAILURE;
                        } else {
-                               RETVAL_STRING(output, 1);
+                               *result = output;
+                               return SUCCESS;
                        }
-
-                       memset(output, 0, PHP_MAX_SALT_LEN + 1);
-                       efree(output);
                } else if (
                                salt[0] == '$' &&
                                salt[1] == '2' &&
@@ -251,31 +213,33 @@ PHP_FUNCTION(crypt)
 
                        memset(output, 0, PHP_MAX_SALT_LEN + 1);
 
-                       crypt_res = php_crypt_blowfish_rn(str, salt, output, 
sizeof(output));
+                       crypt_res = php_crypt_blowfish_rn(password, salt, 
output, sizeof(output));
                        if (!crypt_res) {
-                               if (salt[0]=='*' && salt[1]=='0') {
-                                       RETVAL_STRING("*1", 1);
-                               } else {
-                                       RETVAL_STRING("*0", 1);
-                               }
+                               memset(output, 0, PHP_MAX_SALT_LEN + 1);
+                               return FAILURE;
                        } else {
-                               RETVAL_STRING(output, 1);
+                               int result_len;
+                               result_len = strlen(output);
+                               *result = emalloc(result_len + 1);
+                               memcpy(*result, output, result_len);
+                               (*result)[result_len] = 0;
+                               memset(output, 0, PHP_MAX_SALT_LEN + 1);
+                               return SUCCESS;
                        }
-
-                       memset(output, 0, PHP_MAX_SALT_LEN + 1);
                } else {
                        memset(&buffer, 0, sizeof(buffer));
                        _crypt_extended_init_r();
 
-                       crypt_res = _crypt_extended_r(str, salt, &buffer);
+                       crypt_res = _crypt_extended_r(password, salt, &buffer);
                        if (!crypt_res) {
-                               if (salt[0]=='*' && salt[1]=='0') {
-                                       RETURN_STRING("*1", 1);
-                               } else {
-                                       RETURN_STRING("*0", 1);
-                               }
+                               return FAILURE;
                        } else {
-                               RETURN_STRING(crypt_res, 1);
+                               int result_len;
+                               result_len = strlen(crypt_res);
+                               *result = emalloc(result_len + 1);
+                               memcpy(*result, crypt_res, result_len);
+                               (*result)[result_len] = 0;
+                               return SUCCESS;
                        }
                }
        }
@@ -291,21 +255,73 @@ PHP_FUNCTION(crypt)
 #  else
 #    error Data struct used by crypt_r() is unknown. Please report.
 #  endif
-               crypt_res = crypt_r(str, salt, &buffer);
+               crypt_res = crypt_r(password, salt, &buffer);
                if (!crypt_res) {
-                               if (salt[0]=='*' && salt[1]=='0') {
-                                       RETURN_STRING("*1", 1);
-                               } else {
-                                       RETURN_STRING("*0", 1);
-                               }
+                       return FAILURE;
                } else {
-                       RETURN_STRING(crypt_res, 1);
+                       int result_len;
+                       result_len = strlen(crypt_res);
+                       *result = emalloc(result_len + 1);
+                       memcpy(*result, crypt_res, result_len);
+                       (*result)[result_len] = '\0';
+                       return SUCCESS;
                }
        }
 # endif
 #endif
 }
 /* }}} */
+
+
+/* {{{ proto string crypt(string str [, string salt])
+   Hash a string */
+PHP_FUNCTION(crypt)
+{
+       char salt[PHP_MAX_SALT_LEN + 1];
+       char *str, *salt_in = NULL, *result = NULL;
+       int str_len, salt_in_len = 0;
+       salt[0] = salt[PHP_MAX_SALT_LEN] = '\0';
+
+       /* This will produce suitable results if people depend on DES-encryption
+        * available (passing always 2-character salt). At least for glibc6.1 */
+       memset(&salt[1], '$', PHP_MAX_SALT_LEN - 1);
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &str, 
&str_len, &salt_in, &salt_in_len) == FAILURE) {
+               return;
+       }
+
+       if (salt_in) {
+               memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len));
+       }
+
+       /* The automatic salt generation covers standard DES, md5-crypt and 
Blowfish (simple) */
+       if (!*salt) {
+#if PHP_MD5_CRYPT
+               strncpy(salt, "$1$", PHP_MAX_SALT_LEN);
+               php_to64(&salt[3], PHP_CRYPT_RAND, 4);
+               php_to64(&salt[7], PHP_CRYPT_RAND, 4);
+               strncpy(&salt[11], "$", PHP_MAX_SALT_LEN - 11);
+#elif PHP_STD_DES_CRYPT
+               php_to64(&salt[0], PHP_CRYPT_RAND, 2);
+               salt[2] = '\0';
+#endif
+               salt_in_len = strlen(salt);
+       } else {
+               salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len);
+       }
+       salt[salt_in_len] = '\0';
+
+       if (crypt_execute(str, str_len, salt, salt_in_len, &result) == FAILURE) 
{
+               if (salt[0] == '*' && salt[1] == '0') {
+                       RETURN_STRING("*1", 1);
+               } else {
+                       RETURN_STRING("*0", 1);
+               }
+       }
+       RETVAL_STRING(result, 1);
+       efree(result);
+}
+/* }}} */
 #endif
 
 /*
diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h
index 93b2328..1dffb0b 100644
--- a/ext/standard/php_crypt.h
+++ b/ext/standard/php_crypt.h
@@ -23,6 +23,7 @@
 #ifndef PHP_CRYPT_H
 #define PHP_CRYPT_H
 
+PHPAPI int crypt_execute(const char *password, const int pass_len, const char 
*salt, int salt_len, char **result);
 PHP_FUNCTION(crypt);
 #if HAVE_CRYPT
 PHP_MINIT_FUNCTION(crypt);


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to