Skip to content

Commit

Permalink
Improves input validation in Db::insert()
Browse files Browse the repository at this point in the history
Signed-off-by: Jon Stovell <jonstovell@gmail.com>
  • Loading branch information
Sesquipedalian committed Feb 2, 2025
1 parent 2399c56 commit 4960f80
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
18 changes: 15 additions & 3 deletions Sources/Db/APIs/MySQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -361,9 +361,21 @@ public function insert(string $method, string $table, array $columns, array $dat
}
}

// Inserting data as a single row can be done as a single array.
if (!is_array($data[array_rand($data)])) {
$data = [$data];
// Ensure that $data is a multidimensional array.
if (array_filter($data, fn($dataRow) => is_array($dataRow)) !== $data) {
// If backward compatibility mode is enabled, quietly clean up after
// old mods that did the wrong thing. Otherwise, trigger an error.
if (!empty(Config::$backward_compatibility)) {
$data = [$data];
} else {
$this->error_backtrace(
'Invalid data structure sent to the database.',
'',
E_USER_ERROR,
__FILE__,
__LINE__,
);
}
}

// Create the mold for a single row insert.
Expand Down
17 changes: 15 additions & 2 deletions Sources/Db/APIs/PostgreSQL.php
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,21 @@ public function insert(string $method, string $table, array $columns, array $dat
// Force method to lower case
$method = strtolower($method);

if (!is_array($data[array_rand($data)])) {
$data = [$data];
// Ensure that $data is a multidimensional array.
if (array_filter($data, fn($dataRow) => is_array($dataRow)) !== $data) {
// If backward compatibility mode is enabled, quietly clean up after
// old mods that did the wrong thing. Otherwise, trigger an error.
if (!empty(Config::$backward_compatibility)) {
$data = [$data];
} else {
$this->error_backtrace(
'Invalid data structure sent to the database.',
'',
E_USER_ERROR,
__FILE__,
__LINE__,
);
}
}

// Replace the prefix holder with the actual prefix.
Expand Down
21 changes: 14 additions & 7 deletions Sources/Db/DatabaseApiInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,23 @@ public function fetch_all(object $request): array;
public function free_result(object $result): bool;

/**
* Gets the ID of the most recently inserted row.
* Inserts one or more rows of data into a database table and optionally
* returns the resulting IDs.
*
* @param string $method INSERT or REPLACE.
* @param string $table The table (only used for Postgres).
* @param array $columns An array of the columns we're inserting the data into. Should contain 'column' => 'datatype' pairs.
* @param array $data The data to insert.
* @param array $keys The keys for the table, needs to be not empty on replace mode.
* @param object $connection = null The connection (if null, $db_connection is used).
* @param int returnmode 0 = nothing(default), 1 = last row id, 2 = all rows id as array.
* @return int The ID of the most recently inserted row.
* @param array $columns Array of the columns we're inserting the data into.
* Should contain 'column' => 'datatype' pairs.
* @param array $data Rows of data to insert. Each element of $data must
* be an array of values corresponding to $columns.
* @param array $keys The keys for the table. Must not empty in replace mode.
* @param int $returnmode 0 = nothing, 1 = last row ID, 2 = all row IDs.
* Default: 0.
* @param object $connection The connection to use.
* If null, $db_connection is used.
* @return int|array|null Null if $returnmode is 0, the ID of the most
* recently inserted row if $returnmode is 1, or the IDS of all the
* inserted rows if $returnmode is 2.
*/
public function insert(string $method, string $table, array $columns, array $data, array $keys, int $returnmode = 0, ?object $connection = null): int|array|null;

Expand Down

0 comments on commit 4960f80

Please sign in to comment.