codemod 2010-2016 to 2010-present
[hiphop-php.git] / hphp / zend / zend-string.cpp
blobcc8874b590b06fdf3fa932b51b45887489b1aff1
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 | Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 2.00 of the Zend license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.zend.com/license/2_00.txt. |
12 | If you did not receive a copy of the Zend license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@zend.com so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
18 #include "hphp/zend/zend-string.h"
20 #include <cinttypes>
22 #include "hphp/util/assertions.h"
23 #include "hphp/util/mutex.h"
24 #include "hphp/util/lock.h"
25 #include "hphp/zend/crypt-blowfish.h"
27 #include <folly/portability/Unistd.h>
29 #if defined(_MSC_VER) || defined(__APPLE__)
30 # include "hphp/zend/php-crypt_r.h"
31 # define USE_PHP_CRYPT_R 1
32 #else
33 # include <crypt.h>
34 #endif
36 namespace HPHP {
38 //////////////////////////////////////////////////////////////////////
40 void string_translate(char *str, int len, const char *str_from,
41 const char *str_to, int trlen) {
42 int i;
43 unsigned char xlat[256];
45 if ((trlen < 1) || (len < 1)) {
46 return;
49 for (i = 0; i < 256; xlat[i] = i, i++);
50 for (i = 0; i < trlen; i++) {
51 xlat[(unsigned char) str_from[i]] = str_to[i];
54 for (i = 0; i < len; i++) {
55 str[i] = xlat[(unsigned char) str[i]];
59 char *string_rot13(const char *input, int len) {
60 assert(input);
62 static char rot13_from[] =
63 "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
64 static char rot13_to[] =
65 "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM";
67 if (len == 0) {
68 return nullptr;
70 char *ret = string_duplicate(input, len);
71 string_translate(ret, len, rot13_from, rot13_to, 52);
72 return ret;
75 ///////////////////////////////////////////////////////////////////////////////
76 // crc32
79 * This code implements the AUTODIN II polynomial
80 * The variable corresponding to the macro argument "crc" should
81 * be an unsigned long.
82 * Original code by Spencer Garrett <srg@quick.com>
85 #define CRC32(crc, ch) (crc = (crc >> 8) ^ crc32tab[(crc ^ (ch)) & 0xff])
87 /* generated using the AUTODIN II polynomial
88 * x^32 + x^26 + x^23 + x^22 + x^16 +
89 * x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1
91 static const unsigned int crc32tab[256] = {
92 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
93 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
94 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
95 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
96 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
97 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
98 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
99 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
100 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
101 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
102 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
103 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
104 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
105 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
106 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
107 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
108 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
109 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
110 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
111 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
112 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
113 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
114 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
115 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
116 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
117 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
118 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
119 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
120 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
121 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
122 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
123 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
124 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
125 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
126 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
127 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
128 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
129 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
130 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
131 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
132 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
133 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
134 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
135 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
136 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
137 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
138 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
139 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
140 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
141 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
142 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
143 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
144 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
145 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
146 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
147 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
148 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
149 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
150 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
151 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
152 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
153 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
154 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
155 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
158 int string_crc32(const char *p, int len) {
159 uint32_t crcinit = 0;
160 register int32_t crc = crcinit ^ 0xFFFFFFFF;
161 for (; len--; ++p) {
162 crc = ((crc >> 8) & 0x00FFFFFF) ^ crc32tab[(crc ^ (*p)) & 0xFF];
164 return crc ^ 0xFFFFFFFF;
167 ///////////////////////////////////////////////////////////////////////////////
168 // crypt
170 #ifdef USE_PHP_CRYPT_R
172 char* php_crypt_r(const char* key, const char* salt) {
173 if (salt[0] == '$' && salt[1] == '1' && salt[2] == '$') {
174 char output[MD5_HASH_MAX_LEN], *out;
176 out = php_md5_crypt_r(key, salt, output);
177 return out ? strdup(out) : nullptr;
178 } else if (salt[0] == '$' && salt[1] == '6' && salt[2] == '$') {
179 char output[PHP_MAX_SALT_LEN + 1];
181 char* crypt_res = php_sha512_crypt_r(key, salt, output, PHP_MAX_SALT_LEN);
182 if (!crypt_res) {
183 SECURE_ZERO(output, PHP_MAX_SALT_LEN + 1);
184 return nullptr;
185 } else {
186 char* result = strdup(output);
187 SECURE_ZERO(output, PHP_MAX_SALT_LEN + 1);
188 return result;
190 } else if (salt[0] == '$' && salt[1] == '5' && salt[2] == '$') {
191 char output[PHP_MAX_SALT_LEN + 1];
193 char* crypt_res = php_sha256_crypt_r(key, salt, output, PHP_MAX_SALT_LEN);
194 if (!crypt_res) {
195 SECURE_ZERO(output, PHP_MAX_SALT_LEN + 1);
196 return nullptr;
197 } else {
198 char* result = strdup(output);
199 SECURE_ZERO(output, PHP_MAX_SALT_LEN + 1);
200 return result;
202 } else if (
203 salt[0] == '$' &&
204 salt[1] == '2' &&
205 salt[3] == '$') {
206 char output[PHP_MAX_SALT_LEN + 1];
208 memset(output, 0, PHP_MAX_SALT_LEN + 1);
210 char* crypt_res = php_crypt_blowfish_rn(key, salt, output, sizeof(output));
211 if (!crypt_res) {
212 SECURE_ZERO(output, PHP_MAX_SALT_LEN + 1);
213 return nullptr;
214 } else {
215 char* result = strdup(output);
216 SECURE_ZERO(output, PHP_MAX_SALT_LEN + 1);
217 return result;
219 } else if (salt[0] == '*' && (salt[1] == '0' || salt[1] == '1')) {
220 return nullptr;
221 } else {
222 struct php_crypt_extended_data buffer;
223 /* DES Fallback */
224 memset(&buffer, 0, sizeof(buffer));
225 _crypt_extended_init_r();
227 char* crypt_res = _crypt_extended_r(key, salt, &buffer);
228 if (!crypt_res || (salt[0] == '*' && salt[1] == '0')) {
229 return nullptr;
230 } else {
231 return strdup(crypt_res);
236 #endif
238 static unsigned char itoa64[] =
239 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
240 static void ito64(char *s, long v, int n) {
241 while (--n >= 0) {
242 *s++ = itoa64[v&0x3f];
243 v >>= 6;
247 char *string_crypt(const char *key, const char *salt) {
248 assert(key);
249 assert(salt);
251 char random_salt[12];
252 if (!*salt) {
253 memcpy(random_salt,"$1$",3);
254 ito64(random_salt+3,rand(),8);
255 random_salt[11] = '\0';
256 return string_crypt(key, random_salt);
259 if ((strlen(salt) > sizeof("$2X$00$")) &&
260 (salt[0] == '$') &&
261 (salt[1] == '2') &&
262 (salt[2] >= 'a') && (salt[2] <= 'z') &&
263 (salt[3] == '$') &&
264 (salt[4] >= '0') && (salt[4] <= '3') &&
265 (salt[5] >= '0') && (salt[5] <= '9') &&
266 (salt[6] == '$')) {
267 // Bundled blowfish crypt()
268 char output[61];
269 if (php_crypt_blowfish_rn(key, salt, output, sizeof(output))) {
270 return strdup(output);
273 } else {
274 // System crypt() function
275 #ifdef USE_PHP_CRYPT_R
276 return php_crypt_r(key, salt);
277 #else
278 static Mutex mutex;
279 Lock lock(mutex);
280 char *crypt_res = crypt(key,salt);
282 if (crypt_res) {
283 return strdup(crypt_res);
285 #endif
288 return ((salt[0] == '*') && (salt[1] == '0'))
289 ? strdup("*1") : strdup("*0");
292 //////////////////////////////////////////////////////////////////////
294 char *string_bin2hex(const char *input, int len, char* result) {
295 static char hexconvtab[] = "0123456789abcdef";
297 assert(input);
298 if (len == 0) {
299 return nullptr;
302 int i, j;
303 for (i = j = 0; i < len; i++) {
304 result[j++] = hexconvtab[(unsigned char)input[i] >> 4];
305 result[j++] = hexconvtab[(unsigned char)input[i] & 15];
307 result[j] = '\0';
308 return result;
311 char *string_bin2hex(const char *input, int &len) {
312 if (!len) return nullptr;
313 int inLen = len;
314 int outLen = inLen * 2;
315 char* result = (char*)malloc(outLen + 1);
316 len = outLen;
317 return string_bin2hex(input, inLen, result);
320 //////////////////////////////////////////////////////////////////////