json/raw post data handle

main
Robert 3 years ago
parent 0167391dad
commit be16a39949
  1. 5
      src/bootstrap/requires.php
  2. 121
      src/bootstrap/safer_io.php
  3. 21
      src/bootstrap/site_helper.php
  4. 6
      src/classes/services/cache/file.php

@ -20,6 +20,9 @@ final class requires {
}
public static function is_dangerous(string $file): bool {
// Remove non-visible characters
$file = preg_replace('/[\x00-\x1F\x7F]/u', '', $file);
if (strpos($file, "..") !== false) {
return true; // .. Too dangerious, up path attack
}
@ -68,7 +71,7 @@ final class requires {
}
$dir = str_replace('_DS_', '/', $dir);
$dir = self::filter_dir_path($dir);
$dir = escapeshellcmd($dir);
$dir = escapeshellcmd(realpath($dir));
return (file_exists($dir)) ? $dir : false;
}

@ -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 = "";

@ -235,14 +235,15 @@ final class site_helper {
}
private static function set_params(): void {
// Get query string
$request = explode('?', self::$REQUEST_URI);
$queryParams = [];
if (isset($request[1])) {
$queryParams = $request[1];
parse_str($queryParams, $queryParams);
self::$queryParams = $queryParams;
// Get just query string
$pos = strpos(self::$REQUEST_URI, "?");
$uri = ($pos !== false) ? substr(self::$REQUEST_URI, $pos + 1) : "";
if (empty($uri)) {
return;
}
$queryParams = [];
parse_str($uri, $queryParams);
self::$queryParams = $queryParams;
}
public static function get_cli_args(): string {
@ -260,8 +261,10 @@ final class site_helper {
}
private static function set_route(): void {
$uri = explode('?', self::$REQUEST_URI);
$root = str_replace(self::$ROOT, "", $uri[0]);
// Get just route
$pos = strpos(self::$REQUEST_URI, "?");
$uri = ($pos !== false) ? substr(self::$REQUEST_URI, 0, $pos) : self::$REQUEST_URI;
$root = str_replace(self::$ROOT, "", $uri);
$routes = explode('/', trim($root, '/'));
$project = $routes[0] ?? "";
if (self::set_project($project)) {

@ -72,7 +72,9 @@ class file {
fclose($handle);
return unserialize($data);
// unserialize is dangerious, could pass ['allowed_classes' => false]
return json_decode($data, true);
}
return false;
@ -91,7 +93,7 @@ class file {
flock($handle, LOCK_EX);
fwrite($handle, serialize($value));
fwrite($handle, json_encode($value));
fflush($handle);

Loading…
Cancel
Save