尝试将12字节字符串写入PostgreSQL
我们的代码计算一个$数字。然后,我们不喜欢将其转换为十六进制,用零填充并将其写入PostgreSQL字节字段。很简单,对吧?
(例如(希望返回:''x000000002257('''x'+12字节(即,数字8791:的左填充HEX表示
$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);
无法按照我的意愿获取这些查询中的任何来更新字节。帮助
//$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 "'"
看起来您刚刚忘记了字节文字的前导'x
。如果$packed_hex
包含000000002257
,您可以写:
$query = ("UPDATE blobtest SET destfile = ''x".$packed_hex."' WHERE pkey = ".$args[0]);
您需要在PostgreSQL 9.0及更低版本(IIRC(上使用SET bytea_output = 'hex'
才能将字节恢复为十六进制形式,而不是旧的八进制转义格式。较新版本默认为hex
。
SQL注入
<soapbox>
您的代码显示了一个坏习惯。使用参数化查询以避免SQL注入。packed_hex
现在可能会在你的应用程序中生成,但谁知道以后会如何重用这些代码呢。始终使用参数化查询以避免SQL注入。请参阅有关SQL注入的PHP手册。</soapbox>
正如所写的,您的代码非常不安全。想象一下,如果$args[0]
包含来自恶意用户的NULL);DROP SCHEMA public;--
。您刚刚发送:
UPDATE blobtest SET destfile = ''000000002257' WHERE pkey = 0);DROP SCHEMA public;--);
到你的数据库,它做了一个没有做任何事情的UPDATE,然后是一个很可能破坏了你的数据库的DROP SCHEMA public;
,然后是忽略其余部分的注释。哇,飞溅,你的数据库又来了,浮动表又来了。
这最好写为:
$stm = pg_prepare($connection, "", "UPDATE blobtest SET destfile = $1 WHERE pkey = $2");
$result = pg_execute($connection, "", array($packed_hex, $args[0]));