Skip to content

Commit

Permalink
Issue openmediavault#1751: Handle empty objects correctly (openmediav…
Browse files Browse the repository at this point in the history
…ault#1757)

Note, the whole handling of the `params` argument of the RPC implementation is faulty, but it can not be fixed without breaking existing code and behavior in core and all existing plugins. Therefore, the current implementation will be retained, even if it is wrong. The error is the processing of the `params` argument. This is not converted and processed as PHP objects but converted into an associative array. As a result, the information is lost as to whether it is an empty object or an empty array.

Relates to: openmediavault#1751

Signed-off-by: Volker Theile <votdev@gmx.de>
  • Loading branch information
votdev committed May 3, 2024
1 parent 0a326a2 commit 80c42de
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 16 deletions.
16 changes: 14 additions & 2 deletions deb/openmediavault/usr/sbin/omv-engined
Original file line number Diff line number Diff line change
Expand Up @@ -517,13 +517,25 @@ while(FALSE === $sigTerm) {
require_once("openmediavault/env.inc");

try {
// Decode JSON string to a PHP array.
if (NULL === ($request = json_decode($request, TRUE))) {
// Decode JSON string to a PHP object.
if (NULL === ($request = json_decode_safe($request))) {
throw new \OMV\Exception(
"Failed to decode JSON string: %s",
json_last_error_msg());
}

// Bring the variable into the expected form.
// Note, `params` shouldn't be converted to an array here,
// but this will break existing code in core and all plugins, so
// the current implementation will be kept for compatibility
// reasons.
$request = [
"service" => $request->service,
"method" => $request->method,
"params" => (array)$request->params,
"context" => (array)$request->context
];

////////////////////////////////////////////////////////////////
// Execute RPC.
////////////////////////////////////////////////////////////////
Expand Down
4 changes: 2 additions & 2 deletions deb/openmediavault/usr/sbin/omv-rpc
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,13 @@ $service = $argv[1];
$method = $argv[2];
$params = null;

// Decode RPC method parameters from JSON to a PHP array.
// Decode RPC method parameters from JSON to a PHP object.
if($argc > 3) {
if(!is_json($argv[3])) {
print gettext("ERROR: The params argument is no valid JSON\n");
exit(1);
}
$params = json_decode($argv[3], TRUE);
$params = json_decode_safe($argv[3]);
}

// Execute the RPC and print the response.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ class Schema {
}

protected function validateObject($value, $schema, $name) {
if (!is_object($value)) {
if (!empty($value) && !is_object($value)) {
throw new SchemaValidationException(
"%s: The value %s is not an object.",
$name, json_encode_safe($value));
Expand Down Expand Up @@ -612,7 +612,10 @@ class Schema {
"%s: No 'properties' attribute defined.",
$name);
}
$valueProps = get_object_vars($value);
// Note, this is a workaround to process empty objects
// correctly that are submitted as arrays because of
// historical reasons.
$valueProps = !empty($value) ? get_object_vars($value) : [];
foreach ($schema['properties'] as $propk => $propv) {
// Build the new path. Strip empty parts.
$parts = [ $name, $propk ];
Expand Down
20 changes: 10 additions & 10 deletions deb/openmediavault/usr/share/php/openmediavault/rpc/rpc.inc
Original file line number Diff line number Diff line change
Expand Up @@ -46,22 +46,22 @@ class Rpc {

/**
* Execute the given RPC.
* @param service The name of the service.
* @param method The name of the method.
* @param params The parameters hash object to be passed to the method
* of the given service.
* @param context The context hash object of the caller containing the
* fields \em username and \em role.
* @param mode The mode how to execute this RPC. The following modes
* are available:<ul>
* @param string $service The name of the service.
* @param string $method The name of the method.
* @param array $params The parameters to be passed to the method of
* the given service.
* @param array $context The context of the caller containing the keys
* \em username and \em role.
* @param int $mode The mode how to execute this RPC. The following
* modes are available:<ul>
* \li MODE_LOCAL
* \li MODE_REMOTE
* </ul>
* Defaults to MODE_LOCAL.
* @param restoreSrvEnv Restore various web server and execution
* @param bool $restoreSrvEnv Restore various web server and execution
* environment information. This might be helpful in some cases if
* these information are required in the engine backend. Note, this
* only takes action when mode is MODE_REMOTE. Defauts to FALSE.
* only takes action when mode is MODE_REMOTE. Defaults to FALSE.
* @return The RPC response.
*/
public static function call($service, $method, $params, $context,
Expand Down

0 comments on commit 80c42de

Please sign in to comment.