php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #45964 pg_unescape_bytea() does not unescape correctly
Submitted: 2008-09-01 13:10 UTC Modified: 2008-10-19 23:14 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:0 (0.0%)
Same OS:1 (100.0%)
From: skrald at amossen dot dk Assigned: hholzgra (profile)
Status: Not a bug Package: PostgreSQL related
PHP Version: 5.2.6 OS: Linux
Private report: No CVE-ID: None
 [2008-09-01 13:10 UTC] skrald at amossen dot dk
Description:
------------
Calling pg_unescape_bytea() on some data that has been escaped with pg_escape_bytea() does not produce the original data as expected. That is: the "unescape" method is not the opposite of the "escape" method.


Reproduce code:
---------------
<?php
$data = file_get_contents("/path/to/binary/file");
$esc = pg_escape_bytea($data);
$unesc = pg_unescape_bytea($esc);

print($unesc == $data ? "equal" : "different");
?>


Expected result:
----------------
"equal"



Actual result:
--------------
"different"

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-09-03 23:02 UTC] felipe@php.net
Well, actually the result isn't reversed to original state.
Anyway it seems an expected behavior.

<?php

$data = "\0\t";

$esc = pg_escape_bytea($data);
$unesc = pg_unescape_bytea($esc);

var_dump($esc, $unesc);

?>

Output:

string(10) "\\000\\011"
string(8) "\000\011"


Nevertheless, says the documentation: 

  "This conversion is not exactly the inverse of PQescapeBytea, because the string is not expected to be "escaped" when received from PQgetvalue. In particular this means there is no need for string quoting considerations, and so no need for a PGconn parameter."

And about the two backslashes:

  "Certain byte values must be escaped (but all byte values can be escaped) when used as part of a bytea literal in an SQL statement. In general, to escape a byte, it is converted into the three digit octal number equal to the octet value, and preceded by usually two backslashes."
 [2008-10-19 22:01 UTC] hholzgra@php.net
not a PHP issue, using the libpg API directly from C shows the same issue:

-------- pgtest.c -----------------
#include <stdlib.h>
#include <stdio.h>
#include <libpq-fe.h>

int main()
{
  unsigned char from[2] = "\0\t", *to, *to2;
  size_t from_len = 2, to_len, to2_len;

  to = PQescapeBytea(from, from_len, &to_len);
  to2 = PQunescapeBytea(to, &to2_len);

  printf("'%s' '%s' (%d)\n", to, to2, to2_len);

  return 0;
}

------- result ------------------
'\\000\\011' '\000\011' (8)

 [2008-10-19 23:13 UTC] hholzgra@php.net
See also the last paragraph of the libpq PQunescapeBytea()
function documentation

"This conversion is *not* exactly the inverse of PQescapeBytea, because the string is not expected to be "escaped" when received from PQgetvalue. In particular this means there is no need for string quoting considerations, and so no need for a PGconn parameter."

( http://www.postgresql.org/docs/8.3/interactive/libpq-exec.html#AEN31707 )
 [2008-10-19 23:14 UTC] hholzgra@php.net
.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Jun 19 14:01:31 2024 UTC