summaryrefslogtreecommitdiff
path: root/src/sp_wrapper.c
diff options
context:
space:
mode:
authorxXx-caillou-xXx2018-08-27 13:56:44 +0200
committerjvoisin2018-08-27 11:56:44 +0000
commit096e7faa6a5e21e5416a7c8c484e27acd4636a66 (patch)
tree3dd11a05c4406280238459be917b8f47d22400f7 /src/sp_wrapper.c
parent6abdd9abca50c92390b94fbebb3e7065d5d532da (diff)
Add whitelist support for php's wrappers
Diffstat (limited to 'src/sp_wrapper.c')
-rw-r--r--src/sp_wrapper.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/sp_wrapper.c b/src/sp_wrapper.c
new file mode 100644
index 0000000..d9cd296
--- /dev/null
+++ b/src/sp_wrapper.c
@@ -0,0 +1,70 @@
1#include "php_snuffleupagus.h"
2#include "sp_config.h"
3
4ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus)
5
6static bool wrapper_is_whitelisted(const zend_string *zs) {
7 const sp_list_node *list = SNUFFLEUPAGUS_G(config).config_wrapper->whitelist;
8
9 if (!zs) {
10 return false;
11 }
12
13 while (list) {
14 if (zend_string_equals_ci(zs, (const zend_string*)list->data)) {
15 return true;
16 }
17 list = list->next;
18 }
19 return false;
20}
21
22void sp_disable_wrapper() {
23 HashTable *orig = php_stream_get_url_stream_wrappers_hash();
24 HashTable *orig_complete = pemalloc(sizeof(*orig_complete), 1);
25 zval *zv;
26 zend_string *zs;
27
28 // Copy the original hashtable into a temporary one, as I'm not sure about
29 // the behaviour of ZEND_HASH_FOREACH when element are removed from the
30 // hashtable used in the loop.
31 zend_hash_init(orig_complete, zend_hash_num_elements(orig), NULL, NULL, 1);
32 zend_hash_copy(orig_complete, orig, NULL);
33 zend_hash_clean(orig);
34
35 ZEND_HASH_FOREACH_STR_KEY_VAL(orig_complete, zs, zv) {
36 if (wrapper_is_whitelisted(zs)) {
37 zend_hash_add(orig, zs, zv);
38 }
39 }
40 ZEND_HASH_FOREACH_END();
41
42 zend_hash_destroy(orig_complete);
43 pefree(orig_complete, 1);
44 SNUFFLEUPAGUS_G(config).config_wrapper->num_wrapper = zend_hash_num_elements(orig);
45}
46
47PHP_FUNCTION(sp_stream_wrapper_register) {
48 void (*orig_handler)(INTERNAL_FUNCTION_PARAMETERS);
49 zend_string *protocol_name = NULL;
50
51 ZEND_PARSE_PARAMETERS_START_EX(ZEND_PARSE_PARAMS_QUIET, 2, EX_NUM_ARGS());
52 Z_PARAM_STR(protocol_name);
53 ZEND_PARSE_PARAMETERS_END_EX((void)0);
54
55 if (wrapper_is_whitelisted(protocol_name)) {
56 orig_handler = zend_hash_str_find_ptr(
57 SNUFFLEUPAGUS_G(sp_internal_functions_hook),
58 "stream_wrapper_register", sizeof("stream_wrapper_register") - 1);
59 orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU);
60 }
61}
62
63int hook_stream_wrappers() {
64 TSRMLS_FETCH();
65
66 HOOK_FUNCTION("stream_wrapper_register", sp_internal_functions_hook,
67 PHP_FN(sp_stream_wrapper_register));
68
69 return SUCCESS;
70}