]> git.openstreetmap.org Git - nominatim.git/commitdiff
Merge pull request #1555 from mtmail/setup-escape-shell-args
authorSarah Hoffmann <lonvia@denofr.de>
Wed, 6 Nov 2019 21:47:00 +0000 (22:47 +0100)
committerGitHub <noreply@github.com>
Wed, 6 Nov 2019 21:47:00 +0000 (22:47 +0100)
setup: escape arguments when executing shell commands (psql, createdb)

1  2 
lib/DB.php
lib/setup/SetupClass.php

diff --combined lib/DB.php
index fe2529b2173d5e9226e6bf2f0e22ab88abe8c56b,ddc0932c871e123214e3d373b7a33e9abcaa193a..e4aa4349dbf7dc4a55fd43417a0ff62448aadc36
@@@ -135,7 -135,7 +135,7 @@@ class D
          try {
              $stmt = $this->getQueryStatement($sSQL, $aInputVars, $sErrMessage);
  
 -            while ($val = $stmt->fetchColumn(0)) { // returns first column or false
 +            while (($val = $stmt->fetchColumn(0)) !== false) { // returns first column or false
                  $aVals[] = $val;
              }
          } catch (\PDOException $e) {
      {
          // https://secure.php.net/manual/en/ref.pdo-pgsql.connection.php
          $aInfo = array();
-         if (preg_match('/^pgsql:(.+)/', $sDSN, $aMatches)) {
+         if (preg_match('/^pgsql:(.+)$/', $sDSN, $aMatches)) {
              foreach (explode(';', $aMatches[1]) as $sKeyVal) {
                  list($sKey, $sVal) = explode('=', $sKeyVal, 2);
                  if ($sKey == 'host') $sKey = 'hostspec';
diff --combined lib/setup/SetupClass.php
index a26b7dae34e816d1054b174e819ce68f693dbdce,b8070e4a2d326255497a979d6ee2b1e5ccac0e0d..818aeeb7d1b5cdb083d025cd9c3790b77e4c292d
@@@ -80,13 -80,15 +80,15 @@@ class SetupFunction
              fail('database already exists ('.CONST_Database_DSN.')');
          }
  
-         $sCreateDBCmd = 'createdb -E UTF-8 -p '.$this->aDSNInfo['port'].' '.$this->aDSNInfo['database'];
+         $sCreateDBCmd = 'createdb -E UTF-8'
+             .' -p '.escapeshellarg($this->aDSNInfo['port'])
+             .' '.escapeshellarg($this->aDSNInfo['database']);
          if (isset($this->aDSNInfo['username'])) {
-             $sCreateDBCmd .= ' -U '.$this->aDSNInfo['username'];
+             $sCreateDBCmd .= ' -U '.escapeshellarg($this->aDSNInfo['username']);
          }
  
          if (isset($this->aDSNInfo['hostspec'])) {
-             $sCreateDBCmd .= ' -h '.$this->aDSNInfo['hostspec'];
+             $sCreateDBCmd .= ' -h '.escapeshellarg($this->aDSNInfo['hostspec']);
          }
  
          $result = $this->runWithPgEnv($sCreateDBCmd);
              exit(1);
          }
          $this->pgsqlRunScriptFile(CONST_BasePath.'/data/country_name.sql');
 -        $this->pgsqlRunScriptFile(CONST_BasePath.'/data/country_osm_grid.sql.gz');
 +        $this->pgsqlRunScriptFile(CONST_ExtraDataPath.'/country_osm_grid.sql.gz');
          $this->pgsqlRunScriptFile(CONST_BasePath.'/data/gb_postcode_table.sql');
          $this->pgsqlRunScriptFile(CONST_BasePath.'/data/us_postcode_table.sql');
  
              fail("osm2pgsql not found in '$osm2pgsql'");
          }
  
-         $osm2pgsql .= ' -S '.CONST_Import_Style;
+         $osm2pgsql .= ' -S '.escapeshellarg(CONST_Import_Style);
  
          if (!is_null(CONST_Osm2pgsql_Flatnode_File) && CONST_Osm2pgsql_Flatnode_File) {
-             $osm2pgsql .= ' --flat-nodes '.CONST_Osm2pgsql_Flatnode_File;
+             $osm2pgsql .= ' --flat-nodes '.escapeshellarg(CONST_Osm2pgsql_Flatnode_File);
          }
  
          if (CONST_Tablespace_Osm2pgsql_Data)
-             $osm2pgsql .= ' --tablespace-slim-data '.CONST_Tablespace_Osm2pgsql_Data;
+             $osm2pgsql .= ' --tablespace-slim-data '.escapeshellarg(CONST_Tablespace_Osm2pgsql_Data);
          if (CONST_Tablespace_Osm2pgsql_Index)
-             $osm2pgsql .= ' --tablespace-slim-index '.CONST_Tablespace_Osm2pgsql_Index;
+             $osm2pgsql .= ' --tablespace-slim-index '.escapeshellarg(CONST_Tablespace_Osm2pgsql_Index);
          if (CONST_Tablespace_Place_Data)
-             $osm2pgsql .= ' --tablespace-main-data '.CONST_Tablespace_Place_Data;
+             $osm2pgsql .= ' --tablespace-main-data '.escapeshellarg(CONST_Tablespace_Place_Data);
          if (CONST_Tablespace_Place_Index)
-             $osm2pgsql .= ' --tablespace-main-index '.CONST_Tablespace_Place_Index;
+             $osm2pgsql .= ' --tablespace-main-index '.escapeshellarg(CONST_Tablespace_Place_Index);
          $osm2pgsql .= ' -lsc -O gazetteer --hstore --number-processes 1';
-         $osm2pgsql .= ' -C '.$this->iCacheMemory;
-         $osm2pgsql .= ' -P '.$this->aDSNInfo['port'];
+         $osm2pgsql .= ' -C '.escapeshellarg($this->iCacheMemory);
+         $osm2pgsql .= ' -P '.escapeshellarg($this->aDSNInfo['port']);
          if (isset($this->aDSNInfo['username'])) {
-             $osm2pgsql .= ' -U '.$this->aDSNInfo['username'];
+             $osm2pgsql .= ' -U '.escapeshellarg($this->aDSNInfo['username']);
          }
          if (isset($this->aDSNInfo['hostspec'])) {
-             $osm2pgsql .= ' -H '.$this->aDSNInfo['hostspec'];
+             $osm2pgsql .= ' -H '.escapeshellarg($this->aDSNInfo['hostspec']);
          }
-         $osm2pgsql .= ' -d '.$this->aDSNInfo['database'].' '.$sOSMFile;
+         $osm2pgsql .= ' -d '.escapeshellarg($this->aDSNInfo['database']).' '.escapeshellarg($sOSMFile);
  
          $this->runWithPgEnv($osm2pgsql);
  
      {
          info('Import Tiger data');
  
 +        $aFilenames = glob(CONST_Tiger_Data_Path.'/*.sql');
 +        info('Found '.count($aFilenames).' SQL files in path '.CONST_Tiger_Data_Path);
 +        if (empty($aFilenames)) return;
 +
          $sTemplate = file_get_contents(CONST_BasePath.'/sql/tiger_import_start.sql');
          $sTemplate = str_replace('{www-user}', CONST_Database_Web_User, $sTemplate);
          $sTemplate = $this->replaceTablespace(
              pg_ping($aDBInstances[$i]);
          }
  
 -        foreach (glob(CONST_Tiger_Data_Path.'/*.sql') as $sFile) {
 +        foreach ($aFilenames as $sFile) {
              echo $sFile.': ';
              $hFile = fopen($sFile, 'r');
              $sSQL = fgets($hFile, 100000);
      public function index($bIndexNoanalyse)
      {
          $sOutputFile = '';
-         $sBaseCmd = CONST_InstallPath.'/nominatim/nominatim -i -d '.$this->aDSNInfo['database'].' -P '
-             .$this->aDSNInfo['port'].' -t '.$this->iInstances.$sOutputFile;
+         $sBaseCmd = CONST_InstallPath.'/nominatim/nominatim -i'
+             .' -d '.escapeshellarg($this->aDSNInfo['database'])
+             .' -P '.escapeshellarg($this->aDSNInfo['port'])
+             .' -t '.escapeshellarg($this->iInstances.$sOutputFile);
          if (isset($this->aDSNInfo['hostspec'])) {
-             $sBaseCmd .= ' -H '.$this->aDSNInfo['hostspec'];
+             $sBaseCmd .= ' -H '.escapeshellarg($this->aDSNInfo['hostspec']);
          }
          if (isset($this->aDSNInfo['username'])) {
-             $sBaseCmd .= ' -U '.$this->aDSNInfo['username'];
+             $sBaseCmd .= ' -U '.escapeshellarg($this->aDSNInfo['username']);
          }
  
          info('Index ranks 0 - 4');
          }
          foreach ($aDropTables as $sDrop) {
              if ($this->bVerbose) echo "Dropping table $sDrop\n";
 -            $this->oDB->exec("DROP TABLE $sDrop CASCADE");
 -            // ignore warnings/errors as they might be caused by a table having
 -            // been deleted already by CASCADE
 +            $this->oDB->exec("DROP TABLE IF EXISTS $sDrop CASCADE");
          }
  
          if (!is_null(CONST_Osm2pgsql_Flatnode_File) && CONST_Osm2pgsql_Flatnode_File) {
  
      private function pgsqlRunDropAndRestore($sDumpFile)
      {
-         $sCMD = 'pg_restore -p '.$this->aDSNInfo['port'].' -d '.$this->aDSNInfo['database'].' --no-owner -Fc --clean '.$sDumpFile;
+         $sCMD = 'pg_restore'
+             .' -p '.escapeshellarg($this->aDSNInfo['port'])
+             .' -d '.escapeshellarg($this->aDSNInfo['database'])
+             .' --no-owner -Fc --clean '.escapeshellarg($sDumpFile);
          if ($this->oDB->getPostgresVersion() >= 9.04) {
              $sCMD .= ' --if-exists';
          }
          if (isset($this->aDSNInfo['hostspec'])) {
-             $sCMD .= ' -h '.$this->aDSNInfo['hostspec'];
+             $sCMD .= ' -h '.escapeshellarg($this->aDSNInfo['hostspec']);
          }
          if (isset($this->aDSNInfo['username'])) {
-             $sCMD .= ' -U '.$this->aDSNInfo['username'];
+             $sCMD .= ' -U '.escapeshellarg($this->aDSNInfo['username']);
          }
  
          $this->runWithPgEnv($sCMD);
      {
          if (!file_exists($sFilename)) fail('unable to find '.$sFilename);
  
-         $sCMD = 'psql -p '.$this->aDSNInfo['port'].' -d '.$this->aDSNInfo['database'];
+         $sCMD = 'psql'
+             .' -p '.escapeshellarg($this->aDSNInfo['port'])
+             .' -d '.escapeshellarg($this->aDSNInfo['database']);
          if (!$this->bVerbose) {
              $sCMD .= ' -q';
          }
          if (isset($this->aDSNInfo['hostspec'])) {
-             $sCMD .= ' -h '.$this->aDSNInfo['hostspec'];
+             $sCMD .= ' -h '.escapeshellarg($this->aDSNInfo['hostspec']);
          }
          if (isset($this->aDSNInfo['username'])) {
-             $sCMD .= ' -U '.$this->aDSNInfo['username'];
+             $sCMD .= ' -U '.escapeshellarg($this->aDSNInfo['username']);
          }
          $aProcEnv = null;
          if (isset($this->aDSNInfo['password'])) {
                               1 => array('pipe', 'w'),
                               2 => array('file', '/dev/null', 'a')
                              );
-             $hGzipProcess = proc_open('zcat '.$sFilename, $aDescriptors, $ahGzipPipes);
+             $hGzipProcess = proc_open('zcat '.escapeshellarg($sFilename), $aDescriptors, $ahGzipPipes);
              if (!is_resource($hGzipProcess)) fail('unable to start zcat');
              $aReadPipe = $ahGzipPipes[1];
              fclose($ahGzipPipes[0]);
          } else {
-             $sCMD .= ' -f '.$sFilename;
+             $sCMD .= ' -f '.escapeshellarg($sFilename);
              $aReadPipe = array('pipe', 'r');
          }
          $aDescriptors = array(