Validate identifiers and file paths
This commit is contained in:
parent
607f3d8159
commit
571c24e5b7
@ -55,12 +55,6 @@ class JsonDatabase implements IJsonUnflattener
|
||||
}
|
||||
}
|
||||
|
||||
private function migrate()
|
||||
{
|
||||
// TODO: This is a stub
|
||||
// Make this function migrate between different settings
|
||||
}
|
||||
|
||||
private function getObjectPath($class, $name, ?int $time = null)
|
||||
{
|
||||
$retPath = $this->storagePath;
|
||||
@ -75,6 +69,10 @@ class JsonDatabase implements IJsonUnflattener
|
||||
|
||||
$segments = array_filter(explode('\\', $class));
|
||||
|
||||
for ($i = 0; $i < count($segments); $i++) {
|
||||
$segments[$i] = JsonDatabase::SanitizeIdentifier($segments[$i]);
|
||||
}
|
||||
|
||||
if ($this->fullDomain)
|
||||
$retPath .= DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $segments);
|
||||
else
|
||||
@ -92,15 +90,24 @@ class JsonDatabase implements IJsonUnflattener
|
||||
|
||||
public function load(string $class, string $name, ?int $timestamp = null): JsonSerializable|null
|
||||
{
|
||||
// TODO: Do some basic validation of class and name to
|
||||
// avoid path traversal and make sure a class is specified
|
||||
// This is really fucking important, implement it, or don't and watch someone use your code
|
||||
// and get their production machine hacked
|
||||
if ($class == null || empty(trim($name)))
|
||||
return null;
|
||||
|
||||
if ($name != null && !empty(trim(strval($name))))
|
||||
$name = JSONDatabase::SanitizeIdentifier($name);
|
||||
else
|
||||
return null;
|
||||
|
||||
$class = trim($class);
|
||||
|
||||
if (!$this->audit && $timestamp != null)
|
||||
return null;
|
||||
|
||||
$objPath = $this->getObjectPath($class, $name, ($timestamp != null));
|
||||
|
||||
if (strlen($objPath) > PHP_MAXPATHLEN)
|
||||
return null;
|
||||
|
||||
if (!is_file($objPath))
|
||||
return null;
|
||||
|
||||
@ -115,22 +122,29 @@ class JsonDatabase implements IJsonUnflattener
|
||||
return JsonSerializable::Deserialize($json, $this->nested, $this, $class);
|
||||
}
|
||||
|
||||
public function save(JsonSerializable $obj, string $name = null)
|
||||
public function save(JsonSerializable $obj, ?string $name = null)
|
||||
{
|
||||
if ($name == null || empty(trim(strval($name))))
|
||||
if ($name != null && !empty(trim($name))) {
|
||||
$name = JSONDatabase::SanitizeIdentifier($name);
|
||||
} else {
|
||||
if ($obj instanceof IJsonIdentifiable)
|
||||
$name = $obj->flatIdentifier() ?? uniqid();
|
||||
$name = JSONDatabase::SanitizeIdentifier($obj->flatIdentifier() ?? uniqid());
|
||||
else
|
||||
$name = uniqid();
|
||||
|
||||
$name = JSONDatabase::SanitizeIdentifier($name);
|
||||
}
|
||||
|
||||
$objPath = $this->getObjectPath(get_class($obj), $name);
|
||||
if (strlen($objPath) > PHP_MAXPATHLEN)
|
||||
throw new Exception('JsonDatabase: Specified Path ' . $objPath . ' is longer than allowed.');
|
||||
|
||||
$objJson = $obj->Serialize(nested: $this->nested, to_array: false);
|
||||
|
||||
if ($this->audit)
|
||||
{
|
||||
$historyPath = $this->getObjectPath(get_class($obj), $name, time());
|
||||
if (strlen($historyPath) > PHP_MAXPATHLEN)
|
||||
throw new Exception('JsonDatabase: Specified Path ' . $objPath . ' is longer than allowed.');
|
||||
|
||||
// For Historic files we always save the whole Object Tree since
|
||||
// dependencies might have different timestamps
|
||||
// and resolving that would be annoying
|
||||
@ -149,8 +163,15 @@ class JsonDatabase implements IJsonUnflattener
|
||||
return $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore a JsonSerializable from the Database by using it's Identifier reference.
|
||||
* @param string $className the full class name with domain of the JsonSerializable property
|
||||
* @param $identifer The identifier that uniquely identifies the object
|
||||
* @return JsonSerializable|null
|
||||
*/
|
||||
public function unflattenByID(string $className, $identifier) : JsonSerializable | null
|
||||
{
|
||||
// Fetch JsonSerializable Object from Database using given Identifier
|
||||
return $this->load($className, strval($identifier));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user