Fixes about using html chars in object names. Fix bug #1607047. More work could be...
authorGuillaume (ioguix) de Rorthais <ioguix@free.fr>
Mon, 11 May 2009 01:21:08 +0000 (21:21 -0400)
committerGuillaume (ioguix) de Rorthais <ioguix@free.fr>
Mon, 11 May 2009 01:21:08 +0000 (21:21 -0400)
- fix insert on a table with name or fields containing html chars
- fix altering a field containing html chars in its name
- fix altering a table containint html chars in its name

classes/database/Postgres.php
dataimport.php
tables.php
tblproperties.php

index a95af3fd0d2035facb2cd9cffc0ad758adbf482b..d01b6c8e851db754af6f363c748c58e23cc21b1c 100755 (executable)
@@ -1135,7 +1135,7 @@ class Postgres extends ADODB_base {
                        // sequence on the field.
                        $sql = "
                                SELECT
-                                       a.attname,
+                                       a.attname, a.attnum,
                                        pg_catalog.format_type(a.atttypid, a.atttypmod) as type,
                                        a.atttypmod,
                                        a.attnotnull, a.atthasdef, adef.adsrc,
@@ -1167,7 +1167,7 @@ class Postgres extends ADODB_base {
                else {
                        $sql = "
                                SELECT
-                                       a.attname,
+                                       a.attname, a.attnum,
                                        pg_catalog.format_type(a.atttypid, a.atttypmod) as type,
                                        pg_catalog.format_type(a.atttypid, NULL) as base_type,
                                        a.atttypmod,
@@ -1915,28 +1915,27 @@ class Postgres extends ADODB_base {
         */
        function alterTable($table, $name, $owner, $schema, $comment, $tablespace) {
 
-               $this->fieldClean($table);
                $data = $this->getTable($table);
 
                if ($data->recordCount() != 1)
                        return -2;
 
-                       $status = $this->beginTransaction();
-                       if ($status != 0) {
-                               $this->rollbackTransaction();
-                               return -1;
-                       }
+               $status = $this->beginTransaction();
+               if ($status != 0) {
+                       $this->rollbackTransaction();
+                       return -1;
+               }
 
                $status = $this->_alterTable($data, $name, $owner, $schema, $comment, $tablespace);
 
                if ($status != 0) {
-                               $this->rollbackTransaction();
+                       $this->rollbackTransaction();
                        return $status;
-                       }
-
-                       return $this->endTransaction();
                }
 
+               return $this->endTransaction();
+       }
+
        /**
         * Returns the SQL for changing the current user
         * @param $user The user to change to
@@ -2103,23 +2102,39 @@ class Postgres extends ADODB_base {
        function alterColumn($table, $column, $name, $notnull, $oldnotnull, $default, $olddefault,
                $type, $length, $array, $oldtype, $comment)
        {
+               // Begin transaction
+               $status = $this->beginTransaction();
+               if ($status != 0) {
+                       $this->rollbackTransaction();
+                       return -6;
+               }
+
+               // Rename the column, if it has been changed
+               if ($column != $name) {
+                       $status = $this->renameColumn($table, $column, $name);
+                       if ($status != 0) {
+                               $this->rollbackTransaction();
+                               return -4;
+                       }
+               }
+
+               $this->fieldClean($name);
                $this->fieldClean($table);
                $this->fieldClean($column);
-               $this->clean($comment);
 
                $toAlter = array();
                // Create the command for changing nullability
                if ($notnull != $oldnotnull) {
-                       $toAlter[] = "ALTER COLUMN \"{$column}\" ". (($notnull) ? 'SET' : 'DROP') . " NOT NULL";
+                       $toAlter[] = "ALTER COLUMN \"{$name}\" ". (($notnull) ? 'SET' : 'DROP') . " NOT NULL";
                }
 
                // Add default, if it has changed
                if ($default != $olddefault) {
                        if ($default == '') {
-                               $toAlter[] = "ALTER COLUMN \"{$column}\" DROP DEFAULT";
+                               $toAlter[] = "ALTER COLUMN \"{$name}\" DROP DEFAULT";
                        }
                        else {
-                               $toAlter[] = "ALTER COLUMN \"{$column}\" SET DEFAULT {$default}";
+                               $toAlter[] = "ALTER COLUMN \"{$name}\" SET DEFAULT {$default}";
                        }
                }
 
@@ -2152,18 +2167,12 @@ class Postgres extends ADODB_base {
                        $toAlter[] = "ALTER COLUMN \"{$column}\" TYPE {$ftype}";
                }
 
-               // Begin transaction
-               $status = $this->beginTransaction();
-               if ($status != 0) {
-                       $this->rollbackTransaction();
-                       return -6;
-               }
-
                // Attempt to process the batch alteration, if anything has been changed
                if (!empty($toAlter)) {
                        // Initialise an empty SQL string
                        $sql = "ALTER TABLE \"{$this->_schema}\".\"{$table}\" "
                                . implode(',', $toAlter);
+       
                        $status = $this->execute($sql);
                        if ($status != 0) {
                                $this->rollbackTransaction();
@@ -2172,21 +2181,12 @@ class Postgres extends ADODB_base {
                }
 
                // Update the comment on the column
-               $status = $this->setComment('COLUMN', $column, $table, $comment);
+               $status = $this->setComment('COLUMN', $name, $table, $comment);
                if ($status != 0) {
                        $this->rollbackTransaction();
                        return -5;
                }
 
-               // Rename the column, if it has been changed
-               if ($column != $name) {
-                       $status = $this->renameColumn($table, $column, $name);
-                       if ($status != 0) {
-                               $this->rollbackTransaction();
-                               return -4;
-                       }
-               }
-
                return $this->endTransaction();
        }
 
@@ -2372,41 +2372,47 @@ class Postgres extends ADODB_base {
        /**
         * Adds a new row to a table
         * @param $table The table in which to insert
-        * @param $var An array mapping new values for the row
+        * @param $fields Array of given field in values
+        * @param $values Array of new values for the row
         * @param $nulls An array mapping column => something if it is to be null
         * @param $format An array of the data type (VALUE or EXPRESSION)
         * @param $types An array of field types
         * @return 0 success
         * @return -1 invalid parameters
         */
-       function insertRow($table, $vars, $nulls, $format, $types) {
+       function insertRow($table, $fields, $values, $nulls, $format, $types) {
 
-               if (!is_array($vars) || !is_array($nulls) || !is_array($format)
-                       || !is_array($types)) return -1;
+               if (!is_array($fields) || !is_array($values) || !is_array($nulls)
+                       || !is_array($format) || !is_array($types)
+                       || (count($fields) != count($values))
+               ) {
+                       return -1;
+               }
                else {
-               $this->fieldClean($table);
-
                        // Build clause
-                       if (sizeof($vars) > 0) {
-                               $fields = '';
-                               $values = '';
-                               foreach($vars as $key => $value) {
-                                       $this->fieldClean($key);
+                       if (count($values) > 0) {
+                               // Escape all field names
+                               $fields = array_map(array('Postgres','fieldClean'), $fields);
+                               $this->fieldClean($table);
+
+                               $sql = '';
+                               foreach($values as $i => $value) {
 
                                        // Handle NULL values
-                                       if (isset($nulls[$key])) $tmp = 'NULL';
-                                       else $tmp = $this->formatValue($types[$key], $format[$key], $value);
+                                       if (isset($nulls[$i]))
+                                               $sql .= ',NULL';
+                                       else
+                                               $sql .= ',' . $this->formatValue($types[$i], $format[$i], $value);
+                               }
 
-                                       if ($fields) $fields .= ", \"{$key}\"";
-                                       else $fields = "INSERT INTO \"{$this->_schema}\".\"{$table}\" (\"{$key}\"";
+                               $sql = "INSERT INTO \"{$this->_schema}\".\"{$table}\" (\"". implode('","', $fields) ."\")
+                                       VALUES (". substr($sql, 1) .")";
 
-                                       if ($values) $values .= ", {$tmp}";
-                                       else $values = ") VALUES ({$tmp}";
-                               }
-                               $sql = $fields . $values . ')';
+                               return $this->execute($sql);
                        }
-               return $this->execute($sql);
-       }
+               }
+
+               return -1;
        }
 
        /**
@@ -6805,6 +6811,11 @@ class Postgres extends ADODB_base {
         */
        function setComment($obj_type, $obj_name, $table, $comment, $basetype = NULL) {
                $sql = "COMMENT ON {$obj_type} " ;
+               $this->clean($comment);
+/*
+               $this->fieldClean($table);
+               $this->fieldClean($obj_name);
+*/
 
                switch ($obj_type) {
                        case 'TABLE':
index ba283c3738f8afdf106b2022ce290dce2d710cda..ff81cd960c60b885eeeb23a5a23e5e604f9691dc 100644 (file)
                                break;
                        case 'ROW':
                                // Build value map in order to insert row into table
+                               $fields = array();
                                $vars = array();
                                $nulls = array();
                                $format = array();              
-                               $types = array();                               
+                               $types = array();
+                               $i = 0;                 
                                foreach ($curr_row as $k => $v) {
+                                       $fields[$i] = $k;
                                        // Check for nulls
-                                       if ($v === null) $nulls[$k] = 'on';
+                                       if ($v === null) $nulls[$i] = 'on';
                                        // Add to value array
-                                       $vars[$k] = $v;
+                                       $vars[$i] = $v;
                                        // Format is always VALUE
-                                       $format[$k] = 'VALUE';
+                                       $format[$i] = 'VALUE';
                                        // Type is always text
-                                       $types[$k] = 'text';
+                                       $types[$i] = 'text';
+                                       $i++;
                                }
-                               $status = $data->insertRow($_REQUEST['table'], $vars, $nulls, $format, $types);
+                               $status = $data->insertRow($_REQUEST['table'], $fields, $vars, $nulls, $format, $types);
                                if ($status != 0) {
                                        $data->rollbackTransaction();
                                        $misc->printMsg($lang['strimporterror']);
                                        $row = 2; //We start on the line AFTER the field names
                                        while ($line = fgetcsv($fd, $csv_max_line, $csv_delimiter)) {
                                                // Build value map
+                                               $t_fields = array();
                                                $vars = array();
                                                $nulls = array();
                                                $format = array();
                                                                $misc->printMsg(sprintf($lang['strimporterrorline-badcolumnnum'], $row));
                                                                exit;
                                                        }
+                                                       $t_fields[$i] = $f;
+                                                       
                                                        // Check for nulls
                                                        if (determineNull($line[$i], $null_array)) {
-                                                               $nulls[$f] = 'on';
+                                                               $nulls[$i] = 'on';
                                                        }
                                                        // Add to value array
-                                                       $vars[$f] = $line[$i];
+                                                       $vars[$i] = $line[$i];
                                                        // Format is always VALUE
-                                                       $format[$f] = 'VALUE';
+                                                       $format[$i] = 'VALUE';
                                                        // Type is always text
-                                                       $types[$f] = 'text';
+                                                       $types[$i] = 'text';
                                                        $i++;
                                                }
 
-                                               $status = $data->insertRow($_REQUEST['table'], $vars, $nulls, $format, $types);
+                                               $status = $data->insertRow($_REQUEST['table'], $t_fields, $vars, $nulls, $format, $types);
                                                if ($status != 0) {
                                                        $data->rollbackTransaction();
                                                        $misc->printMsg(sprintf($lang['strimporterrorline'], $row));
index dd6c23113002f8ea76b80e5d11228d7c2aa64519..85fa96334f023d82222bf61da8cdb08d5fa17ea9 100644 (file)
                                echo "<th class=\"data\">{$lang['strnull']}</th><th class=\"data\">{$lang['strvalue']}</th></tr>";
 
                                $i = 0;
+                               $fields = array();
                                while (!$attrs->EOF) {
-                                       $szValueName = "values[{$attrs->fields['attname']}]";
+                                       $fields[$attrs->fields['attnum']] = $attrs->fields['attname'];
+                                       $szValueName = "values[{$attrs->fields['attnum']}]";
                                        $szEvents = '';
                                        $szDivPH = '';
                                        if($bAllowAC) {
                                        }
                                        $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']);
                                        // Set up default value if there isn't one already
-                                       if (!isset($_REQUEST['values'][$attrs->fields['attname']]))
-                                               $_REQUEST['values'][$attrs->fields['attname']] = $attrs->fields['adsrc'];
+                                       if (!isset($_REQUEST['values'][$attrs->fields['attnum']]))
+                                               $_REQUEST['values'][$attrs->fields['attnum']] = $attrs->fields['adsrc'];
                                        // Default format to 'VALUE' if there is no default,
                                        // otherwise default to 'EXPRESSION'
-                                       if (!isset($_REQUEST['format'][$attrs->fields['attname']]))
-                                               $_REQUEST['format'][$attrs->fields['attname']] = ($attrs->fields['adsrc'] === null) ? 'VALUE' : 'EXPRESSION';
+                                       if (!isset($_REQUEST['format'][$attrs->fields['attnum']]))
+                                               $_REQUEST['format'][$attrs->fields['attnum']] = ($attrs->fields['adsrc'] === null) ? 'VALUE' : 'EXPRESSION';
                                        // Continue drawing row
                                        $id = (($i % 2) == 0 ? '1' : '2');
                                        echo "<tr>\n";
                                        echo "<td class=\"data{$id}\" style=\"white-space:nowrap;\">", $misc->printVal($attrs->fields['attname']), "</td>";
                                        echo "<td class=\"data{$id}\" style=\"white-space:nowrap;\">\n";
                                        echo $misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod']));
-                                       echo "<input type=\"hidden\" name=\"types[", htmlspecialchars($attrs->fields['attname']), "]\" value=\"",
+                                       echo "<input type=\"hidden\" name=\"types[", htmlspecialchars($attrs->fields['attnum']), "]\" value=\"",
                                                htmlspecialchars($attrs->fields['type']), "\" /></td>";
                                        echo "<td class=\"data{$id}\" style=\"white-space:nowrap;\">\n";
-                                       echo "<select name=\"format[", htmlspecialchars($attrs->fields['attname']), "]\">\n";
-                                       echo "<option value=\"VALUE\"", ($_REQUEST['format'][$attrs->fields['attname']] == 'VALUE') ? ' selected="selected"' : '', ">{$lang['strvalue']}</option>\n";
-                                       echo "<option value=\"EXPRESSION\"", ($_REQUEST['format'][$attrs->fields['attname']] == 'EXPRESSION') ? ' selected="selected"' : '', ">{$lang['strexpression']}</option>\n";
+                                       echo "<select name=\"format[", htmlspecialchars($attrs->fields['attnum']), "]\">\n";
+                                       echo "<option value=\"VALUE\"", ($_REQUEST['format'][$attrs->fields['attnum']] == 'VALUE') ? ' selected="selected"' : '', ">{$lang['strvalue']}</option>\n";
+                                       echo "<option value=\"EXPRESSION\"", ($_REQUEST['format'][$attrs->fields['attnum']] == 'EXPRESSION') ? ' selected="selected"' : '', ">{$lang['strexpression']}</option>\n";
                                        echo "</select>\n</td>\n";
                                        echo "<td class=\"data{$id}\" style=\"white-space:nowrap;\">";
                                        // Output null box if the column allows nulls (doesn't look at CHECKs or ASSERTIONS)
                                        if (!$attrs->fields['attnotnull']) {
-                                               echo "<input type=\"checkbox\" name=\"nulls[", htmlspecialchars($attrs->fields['attname']), "]\"",
-                                                       isset($_REQUEST['nulls'][$attrs->fields['attname']]) ? ' checked="checked"' : '', " /></td>";
+                                               echo "<input type=\"checkbox\" name=\"nulls[", htmlspecialchars($attrs->fields['attnum']), "]\"",
+                                                       isset($_REQUEST['nulls'][$attrs->fields['attnum']]) ? ' checked="checked"' : '', " /></td>";
                                        }
                                        else {
                                                echo "&nbsp;</td>";
                                        }
                                        echo "<td class=\"data{$id}\" id=\"aciwp{$i}\" style=\"white-space:nowrap;\">", $data->printField($szValueName,
-                                       $_REQUEST['values'][$attrs->fields['attname']], $attrs->fields['type'],array(),$szEvents),$szDivPH ,"</td>";
+                                       $_REQUEST['values'][$attrs->fields['attnum']], $attrs->fields['type'],array(),$szEvents),$szDivPH ,"</td>";
                                        echo "</tr>\n";
                                        $i++;
                                        $attrs->moveNext();
                                if (!isset($_SESSION['counter'])) { $_SESSION['counter'] = 0; }
 
                                echo "<input type=\"hidden\" name=\"action\" value=\"insertrow\" />\n";
+                               echo "<input type=\"hidden\" name=\"fields\" value=\"", htmlentities(serialize($fields),ENT_QUOTES) ,"\" />\n";
                                echo "<input type=\"hidden\" name=\"protection_counter\" value=\"".$_SESSION['counter']."\" />\n";
                                echo "<input type=\"hidden\" name=\"table\" value=\"", htmlspecialchars($_REQUEST['table']), "\" />\n";
                                echo "<p><input type=\"submit\" name=\"insert\" value=\"{$lang['strinsert']}\" />\n";
                else {
                        if (!isset($_POST['values'])) $_POST['values'] = array();
                        if (!isset($_POST['nulls'])) $_POST['nulls'] = array();
+                       $_POST['fields'] = unserialize(htmlspecialchars_decode($_POST['fields'], ENT_QUOTES));
 
                        if ($_SESSION['counter']++ == $_POST['protection_counter']) {
-                               $status = $data->insertRow($_POST['table'], $_POST['values'],
-                                                                                                       $_POST['nulls'], $_POST['format'], $_POST['types']);
+                               $status = $data->insertRow($_POST['table'], $_POST['fields'], $_POST['values'],
+                                                                                       $_POST['nulls'], $_POST['format'], $_POST['types']);
                                if ($status == 0) {
                                        if (isset($_POST['insert']))
                                                doDefault($lang['strrowinserted']);
index e3f6b704f1882ac61579af3509aefa2a97497d67..28547cbd30583b4993c16482b9cd75b684efe00c 100644 (file)
@@ -76,7 +76,7 @@
                        echo "<tr><th class=\"data left required\">{$lang['strname']}</th>\n";
                        echo "<td class=\"data1\">";
                        echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
-                               htmlspecialchars($_POST['name']), "\" /></td></tr>\n";
+                               htmlspecialchars($_POST['name'], ENT_QUOTES), "\" /></td></tr>\n";
 
                        $server_info = $misc->getServerInfo();
                        if ($data->hasAlterTableOwner() && $data->isSuperUser($server_info['username'])) {