|
|
|
|
@ -78,8 +78,8 @@ final class use_iol { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
final class safer_io { |
|
|
|
|
private static $JSON_POST_DATA = []; |
|
|
|
|
private static $DATA_INPUTS = []; |
|
|
|
|
private static string $string_of_POST_data = ""; |
|
|
|
|
private static array $DATA_INPUTS = []; |
|
|
|
|
|
|
|
|
|
protected function __construct() { |
|
|
|
|
|
|
|
|
|
@ -96,6 +96,29 @@ final class safer_io { |
|
|
|
|
self::$DATA_INPUTS[$var_name] : null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static function grab_all_post_data( |
|
|
|
|
int $bytes_limit = 650000, |
|
|
|
|
int $max_params = 400 |
|
|
|
|
): void { |
|
|
|
|
if ($stream = fopen("php://input", 'r')) { |
|
|
|
|
if ($bytes_limit === 0) { |
|
|
|
|
$post_data = stream_get_contents($stream); |
|
|
|
|
} else { |
|
|
|
|
$post_data = stream_get_contents($stream, $bytes_limit); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
fclose($stream); |
|
|
|
|
if ($bytes_limit > 0 && strlen($post_data) == $bytes_limit) { |
|
|
|
|
throw new \Exception("Too much input data!"); |
|
|
|
|
} |
|
|
|
|
$count_params = substr_count($post_data, "&"); |
|
|
|
|
if ($max_params > 0 && $count_params > $max_params) { |
|
|
|
|
throw new \Exception("Too many input parameters!"); |
|
|
|
|
} |
|
|
|
|
self::$string_of_POST_data = $post_data; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static function convert_to_utf8(string $in_str): string { |
|
|
|
|
if (! extension_loaded('mbstring')) { |
|
|
|
|
return $in_str; |
|
|
|
|
@ -185,26 +208,49 @@ final class safer_io { |
|
|
|
|
/** |
|
|
|
|
* Purpose: To decode JQuery encoded objects, arrays, strings, int, bool types. |
|
|
|
|
* The content must be of application/json. |
|
|
|
|
* Returns the JSON encoded POST data, if any.... |
|
|
|
|
* @param type $return_as_array (true) -> Array, (false) -> Object |
|
|
|
|
* @retval type Object/Array|null|false |
|
|
|
|
* Note: It will return null if not valid json. false is not application/json |
|
|
|
|
*/ |
|
|
|
|
public static function get_json_post_data(bool $return_as_array = true, int $levels_deep = 512): mixed { |
|
|
|
|
$content_type = self::get_clean_server_var('CONTENT_TYPE'); |
|
|
|
|
if ($content_type === null) { |
|
|
|
|
private static function get_json_post_data( |
|
|
|
|
string $input_field_name, |
|
|
|
|
bool $return_as_array = true, |
|
|
|
|
int $levels_deep = 512 |
|
|
|
|
) { |
|
|
|
|
$ret_json = self::json_decode( |
|
|
|
|
self::$string_of_POST_data, |
|
|
|
|
$return_as_array, |
|
|
|
|
$levels_deep |
|
|
|
|
); |
|
|
|
|
if (self::has_json_error($ret_json)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (str_contains($content_type, "application/json")) { |
|
|
|
|
$post_body = trim(file_get_contents("php://input")); // get raw POST data. |
|
|
|
|
$ret_json = self::json_decode($post_body, $return_as_array, $levels_deep); |
|
|
|
|
if (self::has_json_error($ret_json)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
return $ret_json; |
|
|
|
|
} else { |
|
|
|
|
return false; |
|
|
|
|
if (isset($ret_json[$input_field_name])) { |
|
|
|
|
return $ret_json[$input_field_name]; |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static function get_post_data(): \Generator { |
|
|
|
|
$pairs = explode("&", self::$string_of_POST_data); |
|
|
|
|
while(true) { |
|
|
|
|
$pair = array_pop($pairs); |
|
|
|
|
if ($pair === null) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
$nv = explode("=", $pair); |
|
|
|
|
$n = $nv[0] ?? false; |
|
|
|
|
$v = $nv[1] ?? ""; |
|
|
|
|
unset($nv); |
|
|
|
|
if ($n === false || empty($n)) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
$cmd = (yield urldecode($n) => urldecode($v)); |
|
|
|
|
if ($cmd == "stop") { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
unset($n); |
|
|
|
|
unset($v); |
|
|
|
|
unset($pairs); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static function safer_html(string $input, HTML_FLAG $safety_level = HTML_FLAG::escape): string { |
|
|
|
|
@ -246,6 +292,25 @@ final class safer_io { |
|
|
|
|
return $item; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static function find_post_field(string $input_field_name) { |
|
|
|
|
$content_type = self::get_clean_server_var('CONTENT_TYPE'); |
|
|
|
|
if ($content_type === null) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
if (str_contains($content_type, "application/json")) { |
|
|
|
|
return self::get_json_post_data($input_field_name); |
|
|
|
|
} |
|
|
|
|
if (str_contains($content_type, "application/x-www-form-urlencoded")) { |
|
|
|
|
$post = self::get_post_data(); |
|
|
|
|
foreach($post as $key => $data) { |
|
|
|
|
if ($key === $input_field_name) { |
|
|
|
|
$post->send("stop"); // Break loop in Generator |
|
|
|
|
return $data; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static function get_input_by_type( |
|
|
|
|
string $input_field_name, |
|
|
|
|
@ -258,9 +323,11 @@ final class safer_io { |
|
|
|
|
return self::get_data_input($input_field_name); |
|
|
|
|
} |
|
|
|
|
if ($input_type == INPUTS::debugging) { |
|
|
|
|
if (isset(self::$JSON_POST_DATA[$input_field_name])) { |
|
|
|
|
return self::$JSON_POST_DATA[$input_field_name]; |
|
|
|
|
$rd = self::find_post_field($input_field_name); |
|
|
|
|
if ($rd !== false) { |
|
|
|
|
return $rd; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
$is_set = filter_has_var(INPUT_POST, $input_field_name); |
|
|
|
|
if ($is_set) { |
|
|
|
|
return filter_input(INPUT_POST, $input_field_name); |
|
|
|
|
@ -275,7 +342,11 @@ final class safer_io { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
if ($input_type === INPUTS::json) { |
|
|
|
|
return (isset(self::$JSON_POST_DATA[$input_field_name])) ? self::$JSON_POST_DATA[$input_field_name] : null; |
|
|
|
|
$rd = self::find_post_field($input_field_name); |
|
|
|
|
if ($rd !== false) { |
|
|
|
|
return $rd; |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
$resolve_input = $input_type->resolve(); |
|
|
|
|
$is_set = filter_has_var($resolve_input, $input_field_name); |
|
|
|
|
@ -318,15 +389,6 @@ final class safer_io { |
|
|
|
|
return $data; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Initialize JSON post data into static array, if used.... |
|
|
|
|
* @param int $levels_deep are JSON Levels to use |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
public static function init_json(int $levels_deep = 512): void { |
|
|
|
|
self::$JSON_POST_DATA = self::get_json_post_data(true, $levels_deep); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public static function required_fields_were_NOT_all_submitted(array $data): bool { |
|
|
|
|
$field = $data['name'] ?? false; |
|
|
|
|
$empty = $data['meta'][$field]['empty'] ?? true; |
|
|
|
|
@ -341,6 +403,7 @@ final class safer_io { |
|
|
|
|
FIELD_FILTER $default_filter = FIELD_FILTER::raw_string, |
|
|
|
|
bool $trim = true, |
|
|
|
|
) : array { |
|
|
|
|
|
|
|
|
|
$meta = []; |
|
|
|
|
$meta['missing'] = []; |
|
|
|
|
$safer_data = ""; |
|
|
|
|
|