使用plhow将填充的十六进制输出写入PostgreSQL中的字节列


Using plhow to write padded hex output to a bytea column in PostgreSQL

尝试将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]));