diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 758e72bdd0..324e8d62f7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -5857,7 +5857,7 @@ parameters: - message: "#^Only booleans are allowed in a negated boolean, int\\|false given\\.$#" - count: 2 + count: 1 path: src/Core.php - @@ -5875,11 +5875,6 @@ parameters: count: 1 path: src/Core.php - - - message: "#^Parameter \\#1 \\$pattern of function preg_match expects string, mixed given\\.$#" - count: 1 - path: src/Core.php - - message: "#^Parameter \\#1 \\$sqlQuery of static method PhpMyAdmin\\\\Html\\\\Generator\\:\\:formatSql\\(\\) expects string, mixed given\\.$#" count: 1 @@ -5895,11 +5890,6 @@ parameters: count: 1 path: src/Core.php - - - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, \\(int\\|string\\) given\\.$#" - count: 1 - path: src/Core.php - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 3 @@ -11295,11 +11285,6 @@ parameters: count: 1 path: src/Plugins/ExportPlugin.php - - - message: "#^Cannot access offset 0 on mixed\\.$#" - count: 10 - path: src/Plugins/Import/ImportCsv.php - - message: "#^Cannot call method getMessage\\(\\) on mixed\\.$#" count: 1 @@ -11307,7 +11292,7 @@ parameters: - message: "#^Cannot cast mixed to string\\.$#" - count: 3 + count: 8 path: src/Plugins/Import/ImportCsv.php - @@ -11335,46 +11320,11 @@ parameters: count: 1 path: src/Plugins/Import/ImportCsv.php - - - message: "#^Parameter \\#1 \\$csvTerminated of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:buildErrorsForParams\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Plugins/Import/ImportCsv.php - - message: "#^Parameter \\#1 \\$serverMessage of static method PhpMyAdmin\\\\Html\\\\Generator\\:\\:mysqlDie\\(\\) expects string, mixed given\\.$#" count: 1 path: src/Plugins/Import/ImportCsv.php - - - message: "#^Parameter \\#1 \\$str of function strtr expects string, mixed given\\.$#" - count: 4 - path: src/Plugins/Import/ImportCsv.php - - - - message: "#^Parameter \\#1 \\$string of function mb_strlen expects string, mixed given\\.$#" - count: 1 - path: src/Plugins/Import/ImportCsv.php - - - - message: "#^Parameter \\#2 \\$csvEnclosed of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:buildErrorsForParams\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Plugins/Import/ImportCsv.php - - - - message: "#^Parameter \\#2 \\$needle of function str_contains expects string, mixed given\\.$#" - count: 1 - path: src/Plugins/Import/ImportCsv.php - - - - message: "#^Parameter \\#3 \\$csvColumns of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:getSqlTemplateAndRequiredFields\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/Plugins/Import/ImportCsv.php - - - - message: "#^Parameter \\#3 \\$csvEscaped of method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportCsv\\:\\:buildErrorsForParams\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Plugins/Import/ImportCsv.php - - message: "#^Parameter \\#3 \\$rows of class PhpMyAdmin\\\\Import\\\\ImportTable constructor expects array\\\\>, array\\, array\\> given\\.$#" count: 1 @@ -11395,16 +11345,6 @@ parameters: count: 1 path: src/Plugins/Import/ImportLdi.php - - - message: "#^Parameter \\#1 \\$str of method PhpMyAdmin\\\\DatabaseInterface\\:\\:quoteString\\(\\) expects string, mixed given\\.$#" - count: 2 - path: src/Plugins/Import/ImportLdi.php - - - - message: "#^Parameter \\#2 \\$subject of function preg_split expects string, mixed given\\.$#" - count: 1 - path: src/Plugins/Import/ImportLdi.php - - message: "#^Method PhpMyAdmin\\\\Plugins\\\\Import\\\\ImportMediawiki\\:\\:doImport\\(\\) should return array\\ but returns mixed\\.$#" count: 1 @@ -12972,7 +12912,7 @@ parameters: - message: "#^Cannot cast mixed to int\\.$#" - count: 8 + count: 4 path: src/Server/Privileges.php - diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 9cc49f3ade..e08764dcf5 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -4169,7 +4169,6 @@ - @@ -4188,7 +4187,6 @@ - @@ -4201,9 +4199,6 @@ - - - @@ -8587,11 +8582,9 @@ - - @@ -8602,11 +8595,7 @@ - - - - @@ -8617,12 +8606,6 @@ - - - - - - @@ -8645,41 +8628,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -10119,13 +10070,7 @@ - - - - - - diff --git a/src/Controllers/Import/ImportController.php b/src/Controllers/Import/ImportController.php index 6528ab0cbc..7622d1a313 100644 --- a/src/Controllers/Import/ImportController.php +++ b/src/Controllers/Import/ImportController.php @@ -195,9 +195,6 @@ final class ImportController extends AbstractController return; } - $postPatterns = ['/^' . $format . '_/']; - Core::setPostAsGlobal($postPatterns); - if (Current::$table !== '' && Current::$database !== '') { $GLOBALS['urlParams'] = ['db' => Current::$database, 'table' => Current::$table]; } elseif (Current::$database !== '') { @@ -485,6 +482,8 @@ final class ImportController extends AbstractController if (! $GLOBALS['error']) { $importPlugin = new ($importFormat->getClassName()); + $importPlugin->setImportOptions($request); + // Do the real import $defaultFkCheck = ForeignKey::handleDisableCheckInit(); try { diff --git a/src/Controllers/Server/PrivilegesController.php b/src/Controllers/Server/PrivilegesController.php index cc7b0e8a2d..58b79abbb1 100644 --- a/src/Controllers/Server/PrivilegesController.php +++ b/src/Controllers/Server/PrivilegesController.php @@ -7,7 +7,6 @@ namespace PhpMyAdmin\Controllers\Server; use PhpMyAdmin\ConfigStorage\Relation; use PhpMyAdmin\ConfigStorage\RelationCleanup; use PhpMyAdmin\Controllers\AbstractController; -use PhpMyAdmin\Core; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\Html\Generator; use PhpMyAdmin\Http\ServerRequest; @@ -75,11 +74,6 @@ class PrivilegesController extends AbstractController ]); } - /** - * Sets globals from $_POST patterns, for privileges and max_* vars - */ - Core::setPostAsGlobal(['/_priv$/i', '/^max_/i']); - $GLOBALS['errorUrl'] = Url::getFromRoute('/'); if ($this->dbi->isSuperUser()) { diff --git a/src/Core.php b/src/Core.php index 8e37fca1d4..5ec72e9d01 100644 --- a/src/Core.php +++ b/src/Core.php @@ -9,7 +9,6 @@ use PhpMyAdmin\Exceptions\MissingExtensionException; use PhpMyAdmin\Http\ServerRequest; use function __; -use function array_keys; use function array_pop; use function array_walk_recursive; use function chr; @@ -534,24 +533,6 @@ class Core return empty($value); } - /** - * Creates some globals from $_POST variables matching a pattern - * - * @param mixed[] $postPatterns The patterns to search for - */ - public static function setPostAsGlobal(array $postPatterns): void - { - foreach (array_keys($_POST) as $postKey) { - foreach ($postPatterns as $onePostPattern) { - if (! preg_match($onePostPattern, $postKey)) { - continue; - } - - $GLOBALS[$postKey] = $_POST[$postKey]; - } - } - } - /** * Gets the "true" IP address of the current user * diff --git a/src/Plugins/Import/ImportCsv.php b/src/Plugins/Import/ImportCsv.php index 96a021740f..7025945080 100644 --- a/src/Plugins/Import/ImportCsv.php +++ b/src/Plugins/Import/ImportCsv.php @@ -13,6 +13,7 @@ use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\File; use PhpMyAdmin\Html\Generator; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Import\ImportTable; use PhpMyAdmin\Message; @@ -53,6 +54,12 @@ class ImportCsv extends AbstractImportCsv */ private bool $analyze = false; + private string $terminated = ''; + private string $enclosed = ''; + private string $escaped = ''; + private string $newLine = ''; + private string $columns = ''; + /** @psalm-return non-empty-lowercase-string */ public function getName(): string { @@ -154,6 +161,15 @@ class ImportCsv extends AbstractImportCsv return $importPluginProperties; } + public function setImportOptions(ServerRequest $request): void + { + $this->terminated = (string) $request->getParsedBodyParam('csv_terminated'); + $this->enclosed = (string) $request->getParsedBodyParam('csv_enclosed'); + $this->escaped = (string) $request->getParsedBodyParam('csv_escaped'); + $this->newLine = (string) $request->getParsedBodyParam('csv_new_line'); + $this->columns = (string) $request->getParsedBodyParam('csv_columns'); + } + /** * Handles the whole import logic * @@ -165,34 +181,29 @@ class ImportCsv extends AbstractImportCsv { $GLOBALS['error'] ??= null; $GLOBALS['message'] ??= null; - $GLOBALS['csv_terminated'] ??= null; - $GLOBALS['csv_enclosed'] ??= null; - $GLOBALS['csv_escaped'] ??= null; - $GLOBALS['csv_new_line'] ??= null; - $GLOBALS['csv_columns'] ??= null; $GLOBALS['errorUrl'] ??= null; // $csv_replace and $csv_ignore should have been here, // but we use directly from $_POST $replacements = ['\\n' => "\n", '\\t' => "\t", '\\r' => "\r"]; - $GLOBALS['csv_terminated'] = strtr($GLOBALS['csv_terminated'], $replacements); - $GLOBALS['csv_enclosed'] = strtr($GLOBALS['csv_enclosed'], $replacements); - $GLOBALS['csv_escaped'] = strtr($GLOBALS['csv_escaped'], $replacements); - $GLOBALS['csv_new_line'] = strtr($GLOBALS['csv_new_line'], $replacements); + $this->terminated = strtr($this->terminated, $replacements); + $this->enclosed = strtr($this->enclosed, $replacements); + $this->escaped = strtr($this->escaped, $replacements); + $this->newLine = strtr($this->newLine, $replacements); [$GLOBALS['error'], $GLOBALS['message']] = $this->buildErrorsForParams( - $GLOBALS['csv_terminated'], - $GLOBALS['csv_enclosed'], - $GLOBALS['csv_escaped'], - $GLOBALS['csv_new_line'], + $this->terminated, + $this->enclosed, + $this->escaped, + $this->newLine, (string) $GLOBALS['errorUrl'], ); [$sqlTemplate, $fields] = $this->getSqlTemplateAndRequiredFields( Current::$database, Current::$table, - $GLOBALS['csv_columns'], + $this->columns, ); $sqlStatements = []; @@ -225,7 +236,7 @@ class ImportCsv extends AbstractImportCsv $rows = []; $buffer = ''; $maxCols = 0; - $csvTerminatedLen = mb_strlen($GLOBALS['csv_terminated']); + $csvTerminatedLen = mb_strlen($this->terminated); $dbi = DatabaseInterface::getInstance(); while (! (ImportSettings::$finished && $i >= $len) && ! $GLOBALS['error'] && ! ImportSettings::$timeoutPassed) { $data = $this->import->getNextChunk($importHandle); @@ -243,21 +254,21 @@ class ImportCsv extends AbstractImportCsv // Force a trailing new line at EOF to prevent parsing problems if (ImportSettings::$finished && $buffer) { $finalch = mb_substr($buffer, -1); - if ($GLOBALS['csv_new_line'] === 'auto' && $finalch !== "\r" && $finalch !== "\n") { + if ($this->newLine === 'auto' && $finalch !== "\r" && $finalch !== "\n") { $buffer .= "\n"; - } elseif ($GLOBALS['csv_new_line'] !== 'auto' && $finalch != $GLOBALS['csv_new_line']) { - $buffer .= $GLOBALS['csv_new_line']; + } elseif ($this->newLine !== 'auto' && $finalch !== $this->newLine) { + $buffer .= $this->newLine; } } // Do not parse string when we're not at the end // and don't have new line inside if ( - ($GLOBALS['csv_new_line'] === 'auto' + ($this->newLine === 'auto' && ! str_contains($buffer, "\r") && ! str_contains($buffer, "\n")) - || ($GLOBALS['csv_new_line'] !== 'auto' - && ! str_contains($buffer, $GLOBALS['csv_new_line'])) + || ($this->newLine !== 'auto' + && ! str_contains($buffer, $this->newLine)) ) { continue; } @@ -268,7 +279,7 @@ class ImportCsv extends AbstractImportCsv // Currently parsed char $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen); $i += $csvTerminatedLen - 1; } @@ -290,7 +301,7 @@ class ImportCsv extends AbstractImportCsv // This can happen with auto EOL and \r at the end of buffer if (! $csvFinish) { // Grab empty field - if ($ch == $GLOBALS['csv_terminated']) { + if ($ch == $this->terminated) { if ($i === $len - 1) { break; } @@ -298,7 +309,7 @@ class ImportCsv extends AbstractImportCsv $values[] = ''; $i++; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen); $i += $csvTerminatedLen - 1; } @@ -308,7 +319,7 @@ class ImportCsv extends AbstractImportCsv // Grab one field $fallbacki = $i; - if ($ch == $GLOBALS['csv_enclosed']) { + if ($ch == $this->enclosed) { if ($i === $len - 1) { break; } @@ -316,7 +327,7 @@ class ImportCsv extends AbstractImportCsv $needEnd = true; $i++; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen); $i += $csvTerminatedLen - 1; } @@ -328,15 +339,15 @@ class ImportCsv extends AbstractImportCsv $value = ''; while ( ($needEnd - && ($ch != $GLOBALS['csv_enclosed'] - || $GLOBALS['csv_enclosed'] == $GLOBALS['csv_escaped'])) + && ($ch != $this->enclosed + || $this->enclosed === $this->escaped)) || (! $needEnd - && ! ($ch == $GLOBALS['csv_terminated'] - || $ch == $GLOBALS['csv_new_line'] - || ($GLOBALS['csv_new_line'] === 'auto' + && ! ($ch === $this->terminated + || $ch === $this->newLine + || ($this->newLine === 'auto' && ($ch === "\r" || $ch === "\n")))) ) { - if ($ch == $GLOBALS['csv_escaped']) { + if ($ch == $this->escaped) { if ($i === $len - 1) { $fail = true; break; @@ -344,16 +355,16 @@ class ImportCsv extends AbstractImportCsv $i++; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen); $i += $csvTerminatedLen - 1; } if ( - $GLOBALS['csv_enclosed'] == $GLOBALS['csv_escaped'] - && ($ch == $GLOBALS['csv_terminated'] - || $ch == $GLOBALS['csv_new_line'] - || ($GLOBALS['csv_new_line'] === 'auto' + $this->enclosed === $this->escaped + && ($ch == $this->terminated + || $ch == $this->newLine + || ($this->newLine === 'auto' && ($ch === "\r" || $ch === "\n"))) ) { break; @@ -371,7 +382,7 @@ class ImportCsv extends AbstractImportCsv $i++; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen <= 1 || $ch != $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen <= 1 || $ch != $this->terminated[0]) { continue; } @@ -387,7 +398,7 @@ class ImportCsv extends AbstractImportCsv if ($fail) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $i += $csvTerminatedLen - 1; } @@ -395,13 +406,13 @@ class ImportCsv extends AbstractImportCsv } // Need to strip trailing enclosing char? - if ($needEnd && $ch == $GLOBALS['csv_enclosed']) { + if ($needEnd && $ch == $this->enclosed) { if (ImportSettings::$finished && $i === $len - 1) { $ch = null; } elseif ($i === $len - 1) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $i += $csvTerminatedLen - 1; } @@ -409,7 +420,7 @@ class ImportCsv extends AbstractImportCsv } else { $i++; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen); $i += $csvTerminatedLen - 1; } @@ -418,19 +429,19 @@ class ImportCsv extends AbstractImportCsv // Are we at the end? if ( - $ch == $GLOBALS['csv_new_line'] - || ($GLOBALS['csv_new_line'] === 'auto' && ($ch === "\r" || $ch === "\n")) + $ch == $this->newLine + || ($this->newLine === 'auto' && ($ch === "\r" || $ch === "\n")) || (ImportSettings::$finished && $i === $len - 1) ) { $csvFinish = true; } // Go to next char - if ($ch == $GLOBALS['csv_terminated']) { + if ($ch == $this->terminated) { if ($i === $len - 1) { $i = $fallbacki; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $i += $csvTerminatedLen - 1; } @@ -439,7 +450,7 @@ class ImportCsv extends AbstractImportCsv $i++; $ch = mb_substr($buffer, $i, 1); - if ($csvTerminatedLen > 1 && $ch == $GLOBALS['csv_terminated'][0]) { + if ($csvTerminatedLen > 1 && $ch == $this->terminated[0]) { $ch = $this->readCsvTerminatedString($buffer, $ch, $i, $csvTerminatedLen); $i += $csvTerminatedLen - 1; } @@ -452,13 +463,13 @@ class ImportCsv extends AbstractImportCsv // End of line if ( ! $csvFinish - && $ch != $GLOBALS['csv_new_line'] - && ($GLOBALS['csv_new_line'] !== 'auto' || ($ch !== "\r" && $ch !== "\n")) + && $ch != $this->newLine + && ($this->newLine !== 'auto' || ($ch !== "\r" && $ch !== "\n")) ) { continue; } - if ($GLOBALS['csv_new_line'] === 'auto' && $ch === "\r") { // Handle "\r\n" + if ($this->newLine === 'auto' && $ch === "\r") { // Handle "\r\n" if ($i >= ($len - 2) && ! ImportSettings::$finished) { break; // We need more data to decide new line } @@ -718,7 +729,7 @@ class ImportCsv extends AbstractImportCsv private function getSqlTemplateAndRequiredFields( string|null $db, string|null $table, - string|null $csvColumns, + string $csvColumns, ): array { $GLOBALS['error'] ??= null; $GLOBALS['message'] ??= null; @@ -735,7 +746,7 @@ class ImportCsv extends AbstractImportCsv $tmpFields = DatabaseInterface::getInstance()->getColumnNames($db, $table); - if ($csvColumns === null || $csvColumns === '') { + if ($csvColumns === '') { $fields = $tmpFields; } else { $sqlTemplate .= ' ('; diff --git a/src/Plugins/Import/ImportLdi.php b/src/Plugins/Import/ImportLdi.php index 9f25d2a2b9..884097ec66 100644 --- a/src/Plugins/Import/ImportLdi.php +++ b/src/Plugins/Import/ImportLdi.php @@ -8,6 +8,7 @@ use PhpMyAdmin\Config; use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\File; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Message; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup; @@ -28,6 +29,15 @@ use const PHP_EOL; */ class ImportLdi extends AbstractImportCsv { + private bool $localOption = false; + private bool $replace = false; + private bool $ignore = false; + private string $terminated = ''; + private string $enclosed = ''; + private string $escaped = ''; + private string $newLine = ''; + private string $columns = ''; + /** @psalm-return non-empty-lowercase-string */ public function getName(): string { @@ -84,6 +94,18 @@ class ImportLdi extends AbstractImportCsv return $importPluginProperties; } + public function setImportOptions(ServerRequest $request): void + { + $this->localOption = $request->getParsedBodyParam('ldi_local_option') !== null; + $this->replace = $request->getParsedBodyParam('ldi_replace') !== null; + $this->ignore = $request->getParsedBodyParam('ldi_ignore') !== null; + $this->terminated = (string) $request->getParsedBodyParam('ldi_terminated'); + $this->enclosed = (string) $request->getParsedBodyParam('ldi_enclosed'); + $this->escaped = (string) $request->getParsedBodyParam('ldi_escaped'); + $this->newLine = (string) $request->getParsedBodyParam('ldi_new_line'); + $this->columns = (string) $request->getParsedBodyParam('ldi_columns'); + } + /** * Handles the whole import logic * @@ -91,15 +113,6 @@ class ImportLdi extends AbstractImportCsv */ public function doImport(File|null $importHandle = null): array { - $GLOBALS['ldi_local_option'] ??= null; - $GLOBALS['ldi_replace'] ??= null; - $GLOBALS['ldi_ignore'] ??= null; - $GLOBALS['ldi_terminated'] ??= null; - $GLOBALS['ldi_enclosed'] ??= null; - $GLOBALS['ldi_escaped'] ??= null; - $GLOBALS['ldi_new_line'] ??= null; - $GLOBALS['ldi_columns'] ??= null; - $sqlStatements = []; $compression = ''; if ($importHandle !== null) { @@ -117,38 +130,38 @@ class ImportLdi extends AbstractImportCsv } $sql = 'LOAD DATA'; - if (isset($GLOBALS['ldi_local_option'])) { + if ($this->localOption) { $sql .= ' LOCAL'; } $dbi = DatabaseInterface::getInstance(); $sql .= ' INFILE ' . $dbi->quoteString(ImportSettings::$importFile); - if (isset($GLOBALS['ldi_replace'])) { + if ($this->replace) { $sql .= ' REPLACE'; - } elseif (isset($GLOBALS['ldi_ignore'])) { + } elseif ($this->ignore) { $sql .= ' IGNORE'; } $sql .= ' INTO TABLE ' . Util::backquote(Current::$table); - if ((string) $GLOBALS['ldi_terminated'] !== '') { - $sql .= ' FIELDS TERMINATED BY \'' . $GLOBALS['ldi_terminated'] . '\''; + if ($this->terminated !== '') { + $sql .= ' FIELDS TERMINATED BY \'' . $this->terminated . '\''; } - if ((string) $GLOBALS['ldi_enclosed'] !== '') { - $sql .= ' ENCLOSED BY ' . $dbi->quoteString($GLOBALS['ldi_enclosed']); + if ($this->enclosed !== '') { + $sql .= ' ENCLOSED BY ' . $dbi->quoteString($this->enclosed); } - if ((string) $GLOBALS['ldi_escaped'] !== '') { - $sql .= ' ESCAPED BY ' . $dbi->quoteString($GLOBALS['ldi_escaped']); + if ($this->escaped !== '') { + $sql .= ' ESCAPED BY ' . $dbi->quoteString($this->escaped); } - if ((string) $GLOBALS['ldi_new_line'] !== '') { - if ($GLOBALS['ldi_new_line'] === 'auto') { - $GLOBALS['ldi_new_line'] = PHP_EOL; + if ($this->newLine !== '') { + if ($this->newLine === 'auto') { + $this->newLine = PHP_EOL; } - $sql .= ' LINES TERMINATED BY \'' . $GLOBALS['ldi_new_line'] . '\''; + $sql .= ' LINES TERMINATED BY \'' . $this->newLine . '\''; } if (ImportSettings::$skipQueries > 0) { @@ -156,9 +169,9 @@ class ImportLdi extends AbstractImportCsv ImportSettings::$skipQueries = 0; } - if ((string) $GLOBALS['ldi_columns'] !== '') { + if ($this->columns !== '') { $sql .= ' ('; - $tmp = preg_split('/,( ?)/', $GLOBALS['ldi_columns']); + $tmp = preg_split('/,( ?)/', $this->columns); if (! is_array($tmp)) { $tmp = []; diff --git a/src/Plugins/Import/ImportMediawiki.php b/src/Plugins/Import/ImportMediawiki.php index c25cb17170..d68a74f02a 100644 --- a/src/Plugins/Import/ImportMediawiki.php +++ b/src/Plugins/Import/ImportMediawiki.php @@ -9,6 +9,7 @@ namespace PhpMyAdmin\Plugins\Import; use PhpMyAdmin\Current; use PhpMyAdmin\File; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Import\ImportTable; use PhpMyAdmin\Message; @@ -62,6 +63,10 @@ class ImportMediawiki extends ImportPlugin return $importPluginProperties; } + public function setImportOptions(ServerRequest $request): void + { + } + /** * Handles the whole import logic * diff --git a/src/Plugins/Import/ImportOds.php b/src/Plugins/Import/ImportOds.php index 7916ccc98c..eb422c062d 100644 --- a/src/Plugins/Import/ImportOds.php +++ b/src/Plugins/Import/ImportOds.php @@ -12,6 +12,7 @@ namespace PhpMyAdmin\Plugins\Import; use PhpMyAdmin\Current; use PhpMyAdmin\File; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Import\ImportTable; use PhpMyAdmin\Message; @@ -96,6 +97,10 @@ class ImportOds extends ImportPlugin return $importPluginProperties; } + public function setImportOptions(ServerRequest $request): void + { + } + /** * Handles the whole import logic * diff --git a/src/Plugins/Import/ImportShp.php b/src/Plugins/Import/ImportShp.php index 441c55da2f..3ddbb84419 100644 --- a/src/Plugins/Import/ImportShp.php +++ b/src/Plugins/Import/ImportShp.php @@ -15,6 +15,7 @@ use PhpMyAdmin\Gis\GisMultiLineString; use PhpMyAdmin\Gis\GisMultiPoint; use PhpMyAdmin\Gis\GisPoint; use PhpMyAdmin\Gis\GisPolygon; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\ColumnType; use PhpMyAdmin\Import\Import; use PhpMyAdmin\Import\ImportSettings; @@ -74,6 +75,10 @@ class ImportShp extends ImportPlugin return $importPluginProperties; } + public function setImportOptions(ServerRequest $request): void + { + } + /** * Handles the whole import logic * diff --git a/src/Plugins/Import/ImportSql.php b/src/Plugins/Import/ImportSql.php index a3263199f4..42d0a0eca4 100644 --- a/src/Plugins/Import/ImportSql.php +++ b/src/Plugins/Import/ImportSql.php @@ -9,6 +9,7 @@ namespace PhpMyAdmin\Plugins\Import; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\File; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Plugins\ImportPlugin; use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup; @@ -83,6 +84,10 @@ class ImportSql extends ImportPlugin return $importPluginProperties; } + public function setImportOptions(ServerRequest $request): void + { + } + /** * Handles the whole import logic * diff --git a/src/Plugins/Import/ImportXml.php b/src/Plugins/Import/ImportXml.php index 131164d89e..988ab64bff 100644 --- a/src/Plugins/Import/ImportXml.php +++ b/src/Plugins/Import/ImportXml.php @@ -11,6 +11,7 @@ namespace PhpMyAdmin\Plugins\Import; use PhpMyAdmin\Current; use PhpMyAdmin\File; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Import\ImportTable; use PhpMyAdmin\Message; @@ -51,6 +52,10 @@ class ImportXml extends ImportPlugin return $importPluginProperties; } + public function setImportOptions(ServerRequest $request): void + { + } + /** * Handles the whole import logic * diff --git a/src/Plugins/ImportPlugin.php b/src/Plugins/ImportPlugin.php index 2eb9406540..02ac54d2d8 100644 --- a/src/Plugins/ImportPlugin.php +++ b/src/Plugins/ImportPlugin.php @@ -8,6 +8,7 @@ declare(strict_types=1); namespace PhpMyAdmin\Plugins; use PhpMyAdmin\File; +use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Import\Import; use PhpMyAdmin\Properties\Plugins\ImportPluginProperties; use PhpMyAdmin\Properties\Plugins\PluginPropertyItem; @@ -65,4 +66,6 @@ abstract class ImportPlugin implements Plugin { return true; } + + abstract public function setImportOptions(ServerRequest $request): void; } diff --git a/src/Server/Privileges.php b/src/Server/Privileges.php index 4efb37f751..efeff7c57e 100644 --- a/src/Server/Privileges.php +++ b/src/Server/Privileges.php @@ -998,38 +998,32 @@ class Privileges { $sqlQuery = ''; if ( - ((isset($_POST['Grant_priv']) && $_POST['Grant_priv'] === 'Y') - || (isset($GLOBALS['Grant_priv']) && $GLOBALS['Grant_priv'] === 'Y')) + isset($_POST['Grant_priv']) && $_POST['Grant_priv'] === 'Y' && ! (Compatibility::isMySqlOrPerconaDb() && $this->dbi->getVersion() >= 80011) ) { $sqlQuery .= ' GRANT OPTION'; } - if (isset($_POST['max_questions']) || isset($GLOBALS['max_questions'])) { - $maxQuestions = isset($_POST['max_questions']) - ? (int) $_POST['max_questions'] : (int) $GLOBALS['max_questions']; + if (isset($_POST['max_questions'])) { + $maxQuestions = (int) $_POST['max_questions']; $maxQuestions = max(0, $maxQuestions); $sqlQuery .= ' MAX_QUERIES_PER_HOUR ' . $maxQuestions; } - if (isset($_POST['max_connections']) || isset($GLOBALS['max_connections'])) { - $maxConnections = isset($_POST['max_connections']) - ? (int) $_POST['max_connections'] : (int) $GLOBALS['max_connections']; + if (isset($_POST['max_connections'])) { + $maxConnections = (int) $_POST['max_connections']; $maxConnections = max(0, $maxConnections); $sqlQuery .= ' MAX_CONNECTIONS_PER_HOUR ' . $maxConnections; } - if (isset($_POST['max_updates']) || isset($GLOBALS['max_updates'])) { - $maxUpdates = isset($_POST['max_updates']) - ? (int) $_POST['max_updates'] : (int) $GLOBALS['max_updates']; + if (isset($_POST['max_updates'])) { + $maxUpdates = (int) $_POST['max_updates']; $maxUpdates = max(0, $maxUpdates); $sqlQuery .= ' MAX_UPDATES_PER_HOUR ' . $maxUpdates; } - if (isset($_POST['max_user_connections']) || isset($GLOBALS['max_user_connections'])) { - $maxUserConnections = isset($_POST['max_user_connections']) - ? (int) $_POST['max_user_connections'] - : (int) $GLOBALS['max_user_connections']; + if (isset($_POST['max_user_connections'])) { + $maxUserConnections = (int) $_POST['max_user_connections']; $maxUserConnections = max(0, $maxUserConnections); $sqlQuery .= ' MAX_USER_CONNECTIONS ' . $maxUserConnections; } @@ -3131,10 +3125,7 @@ class Privileges $alterSqlQuery = ''; if (Compatibility::isMySqlOrPerconaDb() && $serverVersion >= 80011) { $sqlQueryStmt = ''; - if ( - (isset($_POST['Grant_priv']) && $_POST['Grant_priv'] === 'Y') - || (isset($GLOBALS['Grant_priv']) && $GLOBALS['Grant_priv'] === 'Y') - ) { + if (isset($_POST['Grant_priv']) && $_POST['Grant_priv'] === 'Y') { $sqlQueryStmt = ' WITH GRANT OPTION'; } diff --git a/tests/unit/Plugins/Import/ImportCsvTest.php b/tests/unit/Plugins/Import/ImportCsvTest.php index 2aaf2b14e8..ae764516ef 100644 --- a/tests/unit/Plugins/Import/ImportCsvTest.php +++ b/tests/unit/Plugins/Import/ImportCsvTest.php @@ -8,6 +8,7 @@ use PhpMyAdmin\Config; use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\File; +use PhpMyAdmin\Http\Factory\ServerRequestFactory; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Plugins\Import\ImportCsv; use PhpMyAdmin\Tests\AbstractTestCase; @@ -57,6 +58,16 @@ class ImportCsvTest extends AbstractTestCase $this->object = new ImportCsv(); + $request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/') + ->withParsedBody([ + 'csv_terminated' => "\015", + 'csv_enclosed' => '"', + 'csv_escaped' => '"', + 'csv_new_line' => 'auto', + 'csv_columns' => null, + ]); + $this->object->setImportOptions($request); + //setting ImportSettings::$finished = false; ImportSettings::$readLimit = 100000000; @@ -68,11 +79,6 @@ class ImportCsvTest extends AbstractTestCase $GLOBALS['compression'] = 'none'; ImportSettings::$readMultiply = 10; - //separator for csv - $GLOBALS['csv_terminated'] = "\015"; - $GLOBALS['csv_enclosed'] = '"'; - $GLOBALS['csv_escaped'] = '"'; - $GLOBALS['csv_new_line'] = 'auto'; ImportSettings::$importFileName = basename(ImportSettings::$importFile, '.csv'); //$_SESSION @@ -239,6 +245,16 @@ class ImportCsvTest extends AbstractTestCase $GLOBALS['csv_terminated'] = ','; $GLOBALS['import_text'] = '"Row 1","Row 2"' . "\n" . '"123","456"'; + $request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/') + ->withParsedBody([ + 'csv_terminated' => ',', + 'csv_enclosed' => '"', + 'csv_escaped' => '"', + 'csv_new_line' => 'auto', + 'csv_columns' => null, + ]); + $this->object->setImportOptions($request); + $this->dummyDbi = $this->createDbiDummy(); $this->dbi = $this->createDatabaseInterface($this->dummyDbi); DatabaseInterface::$instance = $this->dbi; @@ -281,6 +297,16 @@ class ImportCsvTest extends AbstractTestCase $GLOBALS['csv_terminated'] = ','; $GLOBALS['import_text'] = '"Row 1","Row 2"' . "\n" . '"123","456"'; + $request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/') + ->withParsedBody([ + 'csv_terminated' => ',', + 'csv_enclosed' => '"', + 'csv_escaped' => '"', + 'csv_new_line' => 'auto', + 'csv_columns' => null, + ]); + $this->object->setImportOptions($request); + $_REQUEST['csv_col_names'] = 'something'; $this->dummyDbi = $this->createDbiDummy(); diff --git a/tests/unit/Plugins/Import/ImportLdiTest.php b/tests/unit/Plugins/Import/ImportLdiTest.php index 2ce86b6805..d1e070c618 100644 --- a/tests/unit/Plugins/Import/ImportLdiTest.php +++ b/tests/unit/Plugins/Import/ImportLdiTest.php @@ -8,6 +8,7 @@ use PhpMyAdmin\Config; use PhpMyAdmin\Current; use PhpMyAdmin\DatabaseInterface; use PhpMyAdmin\File; +use PhpMyAdmin\Http\Factory\ServerRequestFactory; use PhpMyAdmin\Import\ImportSettings; use PhpMyAdmin\Plugins\Import\ImportLdi; use PhpMyAdmin\Tests\AbstractTestCase; @@ -30,11 +31,6 @@ class ImportLdiTest extends AbstractTestCase DatabaseInterface::$instance = $this->createDatabaseInterface(); ImportSettings::$charsetConversion = false; - $GLOBALS['ldi_terminated'] = null; - $GLOBALS['ldi_escaped'] = null; - $GLOBALS['ldi_columns'] = null; - $GLOBALS['ldi_enclosed'] = null; - $GLOBALS['ldi_new_line'] = null; ImportSettings::$maxSqlLength = 0; $GLOBALS['sql_query'] = ''; ImportSettings::$executedQueries = 0; @@ -179,19 +175,26 @@ class ImportLdiTest extends AbstractTestCase ->willReturnCallback(static fn (string $string): string => "'" . $string . "'"); DatabaseInterface::$instance = $dbi; - $GLOBALS['ldi_local_option'] = true; - $GLOBALS['ldi_replace'] = true; - $GLOBALS['ldi_ignore'] = true; - $GLOBALS['ldi_terminated'] = ','; - $GLOBALS['ldi_enclosed'] = ')'; - $GLOBALS['ldi_new_line'] = 'newline_mark'; + $request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/') + ->withParsedBody([ + 'ldi_local_option' => '1', + 'ldi_replace' => '1', + 'ldi_ignore' => '1', + 'ldi_terminated' => ',', + 'ldi_enclosed' => ')', + 'ldi_escaped' => null, + 'ldi_new_line' => 'newline_mark', + 'ldi_columns' => null, + ]); ImportSettings::$skipQueries = 1; $importHandle = new File(ImportSettings::$importFile); $importHandle->open(); //Test function called - (new ImportLdi())->doImport($importHandle); + $object = new ImportLdi(); + $object->setImportOptions($request); + $object->doImport($importHandle); //asset that all sql are executed //replace