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
23 changes: 19 additions & 4 deletions src/Codeception/Command/Console.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,19 @@ public function getDescription()
public function execute(InputInterface $input, OutputInterface $output)
{
$suiteName = $input->getArgument('suite');
$this->output = $output;
// Validate suite name before using it
if (!preg_match('/^[a-zA-Z0-9_]+$/', $suiteName)) {
$output->writeln("<error>Invalid suite name.</error>");
return;
}

$config = Configuration::config($input->getOption('config'));
$this->output = $output;
$configPath = $input->getOption('config');
if ($configPath && !preg_match('/^[a-zA-Z0-9_\-\/\.]+$/', $configPath)) {
$output->writeln("<error>Invalid config file path.</error>");
return;
}
$config = Configuration::config($configPath);
$settings = Configuration::suiteSettings($suiteName, $config);

$options = $input->getOptions();
Expand Down Expand Up @@ -112,8 +122,13 @@ protected function executeCommands(InputInterface $input, OutputInterface $outpu
{
$dialog = new QuestionHelper();

if (file_exists($bootstrap)) {
require $bootstrap;
$projectRoot = realpath(__DIR__ . '/../../../');
$bootstrapPath = realpath($bootstrap);

if ($bootstrapPath && strpos($bootstrapPath, $projectRoot) === 0 && file_exists($bootstrapPath)) {
require $bootstrapPath;
} else {
$output->writeln("<error>Invalid bootstrap file path.</error>");
}

do {
Expand Down
9 changes: 8 additions & 1 deletion src/Codeception/Command/Shared/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@ trait Config
{
protected function getSuiteConfig($suite, $conf)
{
// Allow only alphanumeric, underscore, and dash
if (!preg_match('/^[\w\-]+$/', $suite)) {
throw new \InvalidArgumentException("Invalid suite name.");
}
if (!preg_match('/^[\w\-\.\/]+$/', $conf)) {
throw new \InvalidArgumentException("Invalid config path.");
}
$config = Configuration::config($conf);
return Configuration::suiteSettings($suite, $config);
}
Expand All @@ -21,4 +28,4 @@ protected function getSuites($conf)
return Configuration::suites();
}

}
}
34 changes: 29 additions & 5 deletions src/Codeception/Lib/Driver/PostgreSql.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,46 @@ public function load($sql)

public function cleanup()
{
// Get all tables in the public schema and generate DROP statements
$tables = $this->dbh
->query("SELECT 'DROP TABLE IF EXISTS \"' || tablename || '\" cascade;' FROM pg_tables WHERE schemaname = 'public';")
->query("
SELECT 'DROP TABLE IF EXISTS ' || quote_ident(tablename) || ' CASCADE;'
FROM pg_tables
WHERE schemaname = 'public';
")
->fetchAll();

// Get all sequences and generate DROP statements
$sequences = $this->dbh
->query("SELECT 'DROP SEQUENCE IF EXISTS \"' || relname || '\" cascade;' FROM pg_class WHERE relkind = 'S';")
->query("
SELECT 'DROP SEQUENCE IF EXISTS ' || quote_ident(relname) || ' CASCADE;'
FROM pg_class
WHERE relkind = 'S';
")
->fetchAll();

$types = $this->dbh
->query("SELECT 'DROP TYPE IF EXISTS \"' || pg_type.typname || '\" cascade;' FROM pg_type JOIN pg_enum ON pg_enum.enumtypid = pg_type.oid GROUP BY pg_type.typname;")
// Get all enum types and generate DROP statements
$types = $this->dbh
->query("
SELECT 'DROP TYPE IF EXISTS ' || quote_ident(pg_type.typname) || ' CASCADE;'
FROM pg_type
JOIN pg_enum ON pg_enum.enumtypid = pg_type.oid
GROUP BY pg_type.typname;
")
->fetchAll();

// Merge all DROP statements into a single array
$drops = array_merge($tables, $sequences, $types);

// Execute each DROP statement safely
if ($drops) {
foreach ($drops as $drop) {
$this->dbh->exec($drop[0]);
try {
$this->dbh->exec($drop[0]);
} catch (\PDOException $e) {
// Log the error but continue with the next DROP
error_log("Failed to execute: " . $drop[0] . " - " . $e->getMessage());
}
}
}
}
Expand Down