Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

- 2.5.13
- Fix SQL Table offset syntax to work with Postgres
- Prevent SQL Table injection attack

- 2.5.12
- Fix Adaboost proba() probability normalization
- Optimize minmax operations
Expand Down
11 changes: 9 additions & 2 deletions src/Extractors/SQLTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use function Rubix\ML\iterator_first;
use function count;
use function array_keys;
use function preg_match;

/**
* SQL Table
Expand All @@ -25,6 +26,8 @@
*/
class SQLTable implements Extractor
{
protected const TABLE_NAME_PATTERN = '/^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?$/';

/**
* The PDO connection to the database.
*
Expand Down Expand Up @@ -60,13 +63,17 @@ public function __construct(PDO $connection, string $table, int $batchSize = 256
throw new InvalidArgumentException('Table name cannot be empty.');
}

if (!preg_match(self::TABLE_NAME_PATTERN, $table)) {
throw new InvalidArgumentException("Table name '{$table}' is not a valid identifier.");
}

if ($batchSize < 1) {
throw new InvalidArgumentException('Batch size must be'
. " greater than 0, $batchSize given.");
}

$this->connection = $connection;
$this->table = $connection->quote($table);
$this->table = $table;
$this->batchSize = $batchSize;
}

Expand All @@ -87,7 +94,7 @@ public function header() : array
*/
public function getIterator() : Traversable
{
$query = "SELECT * FROM {$this->table} LIMIT :offset, {$this->batchSize}";
$query = "SELECT * FROM {$this->table} LIMIT {$this->batchSize} OFFSET :offset";

$statement = $this->connection->prepare($query);

Expand Down
13 changes: 13 additions & 0 deletions tests/Extractors/SQLTableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Rubix\ML\Extractors\SQLTable;
use Rubix\ML\Extractors\Extractor;
use Rubix\ML\Exceptions\InvalidArgumentException;
use PHPUnit\Framework\TestCase;
use IteratorAggregate;
use Traversable;
Expand Down Expand Up @@ -68,4 +69,16 @@ public function extract() : void

$this->assertEquals($expected, $header);
}

/**
* @test
*/
public function rejectInvalidIdentifier() : void
{
$connection = new PDO('sqlite::memory:');

$this->expectException(InvalidArgumentException::class);

new SQLTable($connection, "pets'; DROP TABLE users; --");
}
}
Loading