【问题标题】:Using plphp - how to write padded hex output to a bytea column in PostgreSQL使用 plphp - 如何将填充的十六进制输出写入 PostgreSQL 中的 bytea 列
【发布时间】:2011-11-09 05:56:46
【问题描述】:

尝试向 PostgreSQL 写入一个 12 字节的字符串

我们的代码计算了一个 $number。然后我们不想将其转换为十六进制,用零填充它并将其写入 PostgreSQL bytea 字段。简单吧?

(例如)希望它返回:\x000000002257('\x' + 12 字节) 即,数字 8791 的左侧填充十六进制表示:

$number = 8791;

$hexnumber = str_pad(dechex($number), 12, '0', STR_PAD_LEFT);
$packed_hex = pack('h*', $hexnumber);

// BOTH of below produce:  000000002257
pg_raise('notice', "hexnumber:         ".$hexnumber);

无法获得这些查询中的 任何 项来更新我希望的 bytea。救命!

//$query = ("UPDATE blobtest SET destfile = '".$hexnumber."' WHERE pkey = ".$args[0]);

// $query = ("UPDATE blobtest SET destfile = '000000002257' WHERE pkey = ".$args[0]);
// Above produces:  \x303030303030303032323537
// (makes sense; it's quoted as a string)

// $query = ("UPDATE blobtest SET destfile = 000000002257 WHERE pkey = ".$args[0]);
// Above produces: ERROR:  column "destfile" is of type bytea but expression is of type integer

// $query = ("UPDATE blobtest SET destfile = '8791' WHERE pkey = ".$args[0]);
// Above produces:  \x38373931  as expected...

/ $query = ("UPDATE blobtest SET destfile = 8791 WHERE pkey = ".$args[0]);
// Above produces: ERROR:  column "destfile" is of type bytea but expression is of type integer

// $query = ("UPDATE blobtest SET destfile = '"."'".$packed_hex."'"."' WHERE pkey = ".$args[0]);
// Above produces:  \x only...

$query = ("UPDATE blobtest SET destfile = "."'".$packed_hex."'"." WHERE pkey = ".$args[0]);
// unterminated quoted string at or near "'"

【问题讨论】:

    标签: php postgresql


    【解决方案1】:

    您似乎刚刚忘记了 bytea 文字的前导 \x。如果$packed_hex 包含000000002257 你可以这样写:

    $query = ("UPDATE blobtest SET destfile = '\x".$packed_hex."' WHERE pkey = ".$args[0]);
    

    您需要在 PostgreSQL 9.0 及更低版本 (IIRC) 上 SET bytea_output = 'hex' 以十六进制形式返回 bytea,而不是 icky 旧的八进制转义格式。较新的版本默认为hex

    SQL 注入

    <soapbox> 你的代码显示了一个坏习惯。使用参数化查询来避免 SQL 注入。 packed_hex 现在可能会在您的应用程序中生成,但谁知道以后如何重用此代码。始终使用参数化查询来避免SQL injection。见the PHP manual on SQL injection.</soapbox>

    正如所写,您的代码非常不安全,非常不安全。想象一下,如果$args[0] 包含来自恶意用户的NULL);DROP SCHEMA public;--。您刚刚发送:

    UPDATE blobtest SET destfile = '\000000002257' WHERE pkey = 0);DROP SCHEMA public;--);
    

    到您的数据库,它执行了一个没有执行任何操作的 UPDATE,然后是很可能破坏您的数据库的 DROP SCHEMA public;,然后是忽略其余部分的注释。哎呀,splat,你的数据库到了,bobby tables 又来了。

    最好这样写:

    $stm = pg_prepare($connection, "", "UPDATE blobtest SET destfile = $1 WHERE pkey = $2");
    $result = pg_execute($connection, "", array($packed_hex, $args[0]));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-09
      • 1970-01-01
      • 2019-04-28
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      • 2014-03-16
      相关资源
      最近更新 更多