diff options
| author | jvoisin | 2022-03-20 18:20:45 +0100 |
|---|---|---|
| committer | jvoisin | 2022-03-20 18:20:45 +0100 |
| commit | 81dd7f2ef07af306fe83d7755cbac4529aa9fc8d (patch) | |
| tree | 32cc44c6231b30db5ac7b15699297863460784aa /src/sp_php_compat.h | |
| parent | 83b01942dfc80474cc05e09aeef4b44307a7120b (diff) | |
| parent | c38df1077a6c1dfbca1baca049214d053e2e7684 (diff) | |
Merge remote-tracking branch 'sektioneins/master'
Diffstat (limited to 'src/sp_php_compat.h')
| -rw-r--r-- | src/sp_php_compat.h | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/src/sp_php_compat.h b/src/sp_php_compat.h new file mode 100644 index 0000000..04914b4 --- /dev/null +++ b/src/sp_php_compat.h | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | /* code in this file is licensed under its original license | ||
| 2 | The PHP License, version 3.01 (https://www.php.net/license/3_01.txt) | ||
| 3 | which is also included with these sources in the file `PHP_LICENSE` */ | ||
| 4 | |||
| 5 | #if PHP_VERSION_ID < 80000 | ||
| 6 | |||
| 7 | // copied from PHP 8.0.9 sources | ||
| 8 | ZEND_API zend_string *zend_string_concat2( | ||
| 9 | const char *str1, size_t str1_len, | ||
| 10 | const char *str2, size_t str2_len); | ||
| 11 | |||
| 12 | #define ZEND_HASH_REVERSE_FOREACH_KEY_PTR(ht, _h, _key, _ptr) \ | ||
| 13 | ZEND_HASH_REVERSE_FOREACH(ht, 0); \ | ||
| 14 | _h = _p->h; \ | ||
| 15 | _key = _p->key; \ | ||
| 16 | _ptr = Z_PTR_P(_z); | ||
| 17 | |||
| 18 | // zend_result was introduced to replace ZEND_RESULT_CODE with PHP8 | ||
| 19 | typedef ZEND_RESULT_CODE zend_result; | ||
| 20 | |||
| 21 | #endif | ||
| 22 | |||
| 23 | #if PHP_VERSION_ID < 70300 | ||
| 24 | |||
| 25 | // copied from PHP 7.4.22 sources | ||
| 26 | |||
| 27 | static zend_always_inline uint32_t zend_gc_delref(zend_refcounted_h *p) { | ||
| 28 | ZEND_ASSERT(p->refcount > 0); | ||
| 29 | // ZEND_RC_MOD_CHECK(p); | ||
| 30 | return --(p->refcount); | ||
| 31 | } | ||
| 32 | #define GC_DELREF(p) zend_gc_delref(&(p)->gc) | ||
| 33 | |||
| 34 | static zend_always_inline void zend_string_release_ex(zend_string *s, int persistent) | ||
| 35 | { | ||
| 36 | if (!ZSTR_IS_INTERNED(s)) { | ||
| 37 | if (GC_DELREF(s) == 0) { | ||
| 38 | if (persistent) { | ||
| 39 | ZEND_ASSERT(GC_FLAGS(s) & IS_STR_PERSISTENT); | ||
| 40 | free(s); | ||
| 41 | } else { | ||
| 42 | ZEND_ASSERT(!(GC_FLAGS(s) & IS_STR_PERSISTENT)); | ||
| 43 | efree(s); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | static zend_always_inline void zend_string_efree(zend_string *s) | ||
| 50 | { | ||
| 51 | ZEND_ASSERT(!ZSTR_IS_INTERNED(s)); | ||
| 52 | ZEND_ASSERT(GC_REFCOUNT(s) <= 1); | ||
| 53 | ZEND_ASSERT(!(GC_FLAGS(s) & IS_STR_PERSISTENT)); | ||
| 54 | efree(s); | ||
| 55 | } | ||
| 56 | |||
| 57 | #endif | ||
| 58 | |||
| 59 | #if PHP_VERSION_ID < 70200 | ||
| 60 | |||
| 61 | #undef ZEND_HASH_REVERSE_FOREACH | ||
| 62 | |||
| 63 | // copied from PHP 7.4.22 sources | ||
| 64 | |||
| 65 | #define ZEND_HASH_REVERSE_FOREACH(_ht, indirect) do { \ | ||
| 66 | HashTable *__ht = (_ht); \ | ||
| 67 | uint32_t _idx = __ht->nNumUsed; \ | ||
| 68 | Bucket *_p = __ht->arData + _idx; \ | ||
| 69 | zval *_z; \ | ||
| 70 | for (_idx = __ht->nNumUsed; _idx > 0; _idx--) { \ | ||
| 71 | _p--; \ | ||
| 72 | _z = &_p->val; \ | ||
| 73 | if (indirect && Z_TYPE_P(_z) == IS_INDIRECT) { \ | ||
| 74 | _z = Z_INDIRECT_P(_z); \ | ||
| 75 | } \ | ||
| 76 | if (UNEXPECTED(Z_TYPE_P(_z) == IS_UNDEF)) continue; | ||
| 77 | |||
| 78 | |||
| 79 | #define ZEND_HASH_FOREACH_END_DEL() \ | ||
| 80 | __ht->nNumOfElements--; \ | ||
| 81 | do { \ | ||
| 82 | uint32_t j = HT_IDX_TO_HASH(_idx - 1); \ | ||
| 83 | uint32_t nIndex = _p->h | __ht->nTableMask; \ | ||
| 84 | uint32_t i = HT_HASH(__ht, nIndex); \ | ||
| 85 | if (UNEXPECTED(j != i)) { \ | ||
| 86 | Bucket *prev = HT_HASH_TO_BUCKET(__ht, i); \ | ||
| 87 | while (Z_NEXT(prev->val) != j) { \ | ||
| 88 | i = Z_NEXT(prev->val); \ | ||
| 89 | prev = HT_HASH_TO_BUCKET(__ht, i); \ | ||
| 90 | } \ | ||
| 91 | Z_NEXT(prev->val) = Z_NEXT(_p->val); \ | ||
| 92 | } else { \ | ||
| 93 | HT_HASH(__ht, nIndex) = Z_NEXT(_p->val); \ | ||
| 94 | } \ | ||
| 95 | } while (0); \ | ||
| 96 | } \ | ||
| 97 | __ht->nNumUsed = _idx; \ | ||
| 98 | } while (0) | ||
| 99 | |||
| 100 | #endif | ||
| 101 | |||
| 102 | // copied from PHP 8.0.11 sources, ext/hash/hash.c | ||
| 103 | // slightly modified for PHP 8.1 compatibility | ||
| 104 | |||
| 105 | static inline void php_hash_string_xor_char(unsigned char *out, const unsigned char *in, const unsigned char xor_with, const size_t length) { | ||
| 106 | size_t i; | ||
| 107 | for (i=0; i < length; i++) { | ||
| 108 | out[i] = in[i] ^ xor_with; | ||
| 109 | } | ||
| 110 | } | ||
| 111 | |||
| 112 | static inline void php_hash_hmac_prep_key(unsigned char *K, const php_hash_ops *ops, void *context, const unsigned char *key, const size_t key_len) { | ||
| 113 | memset(K, 0, ops->block_size); | ||
| 114 | if (key_len > ops->block_size) { | ||
| 115 | /* Reduce the key first */ | ||
| 116 | #if PHP_VERSION_ID < 80100 | ||
| 117 | ops->hash_init(context); | ||
| 118 | #else | ||
| 119 | ops->hash_init(context, NULL); | ||
| 120 | #endif | ||
| 121 | ops->hash_update(context, key, key_len); | ||
| 122 | ops->hash_final(K, context); | ||
| 123 | } else { | ||
| 124 | memcpy(K, key, key_len); | ||
| 125 | } | ||
| 126 | /* XOR the key with 0x36 to get the ipad) */ | ||
| 127 | php_hash_string_xor_char(K, K, 0x36, ops->block_size); | ||
| 128 | } | ||
| 129 | |||
| 130 | static inline void php_hash_hmac_round(unsigned char *final, const php_hash_ops *ops, void *context, const unsigned char *key, const unsigned char *data, const zend_long data_size) { | ||
| 131 | #if PHP_VERSION_ID < 80100 | ||
| 132 | ops->hash_init(context); | ||
| 133 | #else | ||
| 134 | ops->hash_init(context, NULL); | ||
| 135 | #endif | ||
| 136 | ops->hash_update(context, key, ops->block_size); | ||
| 137 | ops->hash_update(context, data, data_size); | ||
| 138 | ops->hash_final(final, context); | ||
| 139 | } | ||
