|
| 1 | +--TEST-- |
| 2 | +At most 16 filters can be chained in one stream |
| 3 | +--EXTENSIONS-- |
| 4 | +filter |
| 5 | +--FILE-- |
| 6 | +<?php |
| 7 | + |
| 8 | +function createFilterChains($n, $resource) { |
| 9 | + $filter = 'string.toupper'; |
| 10 | + $pipes = 'php://filter/' . implode('|', array_fill(0, $n, $filter)) . "/resource=$resource"; |
| 11 | + $slashes = 'php://filter/' . implode('/', array_fill(0, $n, $filter)) . "/resource=$resource"; |
| 12 | + $resources = str_repeat("php://filter/$filter/resource=", $n) . $resource; |
| 13 | + return [$pipes, $slashes, $resources]; |
| 14 | +} |
| 15 | + |
| 16 | +echo "# file_get_contents on 16 filters\n"; |
| 17 | +$allowed_read = createFilterChains(16, 'data:text/plain,sixteen'); |
| 18 | +foreach ($allowed_read as $chain) { |
| 19 | + var_dump(file_get_contents($chain)); |
| 20 | +} |
| 21 | + |
| 22 | +echo "# include on 16 filters\n"; |
| 23 | +$allowed_include = createFilterChains(16, 'php://temp'); |
| 24 | +foreach ($allowed_include as $chain) { |
| 25 | + var_dump(include $chain); |
| 26 | +} |
| 27 | + |
| 28 | +echo "# file_get_contents on 17 filters\n"; |
| 29 | +$blocked_read = createFilterChains(17, 'data:text/plain,seventeen'); |
| 30 | +foreach ($blocked_read as $chain) { |
| 31 | + var_dump(file_get_contents($chain)); |
| 32 | +} |
| 33 | + |
| 34 | +echo "# include on 17 filters\n"; |
| 35 | +$blocked_include = createFilterChains(17, 'php://temp'); |
| 36 | +foreach ($blocked_include as $chain) { |
| 37 | + var_dump(include $chain); |
| 38 | +} |
| 39 | + |
| 40 | +echo "# file_get_contents on 3 filters, max_filter_count=2\n"; |
| 41 | +$ctx = stream_context_create(['filter' => ['max_filter_count' => 2]]); |
| 42 | +$blocked_read = createFilterChains(3, 'data:text/plain,three'); |
| 43 | +foreach ($blocked_read as $chain) { |
| 44 | + var_dump(file_get_contents($chain, false, $ctx)); |
| 45 | +} |
| 46 | + |
| 47 | +echo "# file_get_contents on 19 filters, max_filter_count=20\n"; |
| 48 | +$ctx = stream_context_create(['filter' => ['max_filter_count' => 20]]); |
| 49 | +$allowed_read = createFilterChains(19, 'data:text/plain,nineteen'); |
| 50 | +foreach ($allowed_read as $chain) { |
| 51 | + var_dump(file_get_contents($chain, false, $ctx)); |
| 52 | +} |
| 53 | + |
| 54 | +echo "# warning is only given once, even when we add two filters over the limit\n"; |
| 55 | +$blocked_read = createFilterChains(18, 'data:text/plain,eighteen'); |
| 56 | +foreach ($blocked_read as $chain) { |
| 57 | + var_dump(file_get_contents($chain)); |
| 58 | +} |
| 59 | + |
| 60 | +echo "# warn on too many write filters, even when number of read filters is OK\n"; |
| 61 | +$filter = 'string.toupper'; |
| 62 | +$write_filters = implode('|', array_fill(0, 16, $filter)); |
| 63 | +$fp = fopen("php://filter/write=$write_filters/$filter/resource=php://temp", 'w+'); |
| 64 | +var_dump(is_resource($fp)); |
| 65 | + |
| 66 | +echo "# setting max_filter_count to -1 disables warning\n"; |
| 67 | +$ctx = stream_context_create(['filter' => ['max_filter_count' => -1]]); |
| 68 | +$allowed_read = createFilterChains(20, 'data:text/plain,twenty'); |
| 69 | +foreach ($allowed_read as $chain) { |
| 70 | + var_dump(file_get_contents($chain, false, $ctx)); |
| 71 | +} |
| 72 | + |
| 73 | +echo "# many filters with stream_filter_append still works\n"; |
| 74 | +$fp = fopen('data:text/plain,stream_filter_append', 'r'); |
| 75 | +for ($i = 0; $i < 80; $i++) { |
| 76 | + stream_filter_append($fp, 'string.toupper'); |
| 77 | +} |
| 78 | +var_dump(fread($fp, 30)); |
| 79 | +fclose($fp); |
| 80 | + |
| 81 | +?> |
| 82 | +--EXPECTF-- |
| 83 | +# file_get_contents on 16 filters |
| 84 | +string(7) "SIXTEEN" |
| 85 | +string(7) "SIXTEEN" |
| 86 | +string(7) "SIXTEEN" |
| 87 | +# include on 16 filters |
| 88 | +int(1) |
| 89 | +int(1) |
| 90 | +int(1) |
| 91 | +# file_get_contents on 17 filters |
| 92 | + |
| 93 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 94 | +string(9) "SEVENTEEN" |
| 95 | + |
| 96 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 97 | +string(9) "SEVENTEEN" |
| 98 | + |
| 99 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 100 | +string(9) "SEVENTEEN" |
| 101 | +# include on 17 filters |
| 102 | + |
| 103 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 104 | +int(1) |
| 105 | + |
| 106 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 107 | +int(1) |
| 108 | + |
| 109 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 110 | +int(1) |
| 111 | +# file_get_contents on 3 filters, max_filter_count=2 |
| 112 | + |
| 113 | +Warning: file_get_contents(): Failed to open stream: too many filters in %s on line %d |
| 114 | +bool(false) |
| 115 | + |
| 116 | +Warning: file_get_contents(): Failed to open stream: too many filters in %s on line %d |
| 117 | +bool(false) |
| 118 | + |
| 119 | +Warning: file_get_contents(): Failed to open stream: too many filters in %s on line %d |
| 120 | +bool(false) |
| 121 | +# file_get_contents on 19 filters, max_filter_count=20 |
| 122 | +string(8) "NINETEEN" |
| 123 | +string(8) "NINETEEN" |
| 124 | +string(8) "NINETEEN" |
| 125 | +# warning is only given once, even when we add two filters over the limit |
| 126 | + |
| 127 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 128 | +string(8) "EIGHTEEN" |
| 129 | + |
| 130 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 131 | +string(8) "EIGHTEEN" |
| 132 | + |
| 133 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 134 | +string(8) "EIGHTEEN" |
| 135 | +# warn on too many write filters, even when number of read filters is OK |
| 136 | + |
| 137 | +Deprecated: Using more than 16 filters in a php://filter URL is deprecated, set this limit using the stream context option max_filter_count, or use stream_filter_append in %smax_filter_chain.php on line %d |
| 138 | +bool(true) |
| 139 | +# setting max_filter_count to -1 disables warning |
| 140 | +string(6) "TWENTY" |
| 141 | +string(6) "TWENTY" |
| 142 | +string(6) "TWENTY" |
| 143 | +# many filters with stream_filter_append still works |
| 144 | +string(20) "STREAM_FILTER_APPEND" |
0 commit comments