Last modified: 2010-05-15 15:59:49 UTC

Wikimedia Bugzilla is closed!

Wikimedia migrated from Bugzilla to Phabricator. Bug reports are handled in Wikimedia Phabricator.
This static website is read-only and for historical purposes. It is not possible to log in and except for displaying bug reports and their history, links might be broken. See T13292, the corresponding Phabricator task for complete and up-to-date bug report information.
Bug 11292 - Notice: unserialize() Error when using Postgres
Notice: unserialize() Error when using Postgres
Status: RESOLVED FIXED
Product: MediaWiki
Classification: Unclassified
Parser (Other open bugs)
1.11.x
All Linux
: Normal enhancement with 2 votes (vote)
: ---
Assigned To: Nobody - You can work on this!
:
Depends on:
Blocks: postgres
  Show dependency treegraph
 
Reported: 2007-09-11 18:31 UTC by Alessandro Fernandes Martins
Modified: 2010-05-15 15:59 UTC (History)
7 users (show)

See Also:
Web browser: ---
Mobile Platform: ---
Assignee Huggle Beta Tester: ---


Attachments
Proposed Blob class (1.55 KB, patch)
2007-09-19 16:26 UTC, Greg Sabino Mullane
Details
Revision 26040 (1.57 KB, patch)
2008-01-24 17:06 UTC, Chris Bandy
Details

Description Alessandro Fernandes Martins 2007-09-11 18:31:35 UTC
I have a problem with MediaWiki 1.11.0 and PostgreSQL 8.1.9 (from Ubuntu Server 6.06.1 LTS).

Well, my little problem started today, when I do an update in MediaWiki from 1.10.1 to 1.11.0.

Everything worked fine, however, I'm getting the error message (in the top) in the Main Page and in some others:

Notice: unserialize() [function.unserialize]: Error at offset 0 of 4197 bytes in /var/www/wiki/includes/BagOStuff.php on line 392
Comment 1 Santtu Pajukanta 2007-09-11 18:52:28 UTC
I'm experiencing this problem too. Gentoo, Apache 2.2.4, PHP 5.2.4, PostgreSQL 8.2.4.
Comment 2 Song Younghwan 2007-09-12 10:47:03 UTC
(MediaWiki 1.11.0 with PostgreSQL 8.2.4, PHP 5.2.1)

The cause of this problem is inconsistency in DatabasePostgres.php.


function encodeBlob($b) on line 1141 just returns pg_escape_bytea($b).

function addQuotes($s) on line 1152 returns escaped string of $s which is surrounded by quotes.


These functions are called to escape serialized data by 'set' function in BagOStuff.php.

Consequently, serialized data is escaped by pg_escape_string(pg_escape_bytea($b)).

So in database, serialized data is stored as an abnormally escaped string.

After receiving the data from database, pg_unescape_bytea just replaces two backslashes to one backslash.


It seems that function 'addQuotes' expects its bytea argument to be an array.

So it is resolved if serialized data is passed to 'addQuotes' in array form.

Emergency fix could be made like below:

function encodeBlob($b) {
  return array(0, pg_escape_bytea($b)); # emergency fix
}
Comment 3 Isaac Waldron 2007-09-15 00:37:39 UTC
I have this problem as well on FreeBSD 6.2 with PostgreSQL 8.2
Comment 4 Greg Sabino Mullane 2007-09-19 13:19:11 UTC
This is a tricky problem: there are places where we need the raw decoded string passed back in, such as the select statements in Math.php. The problem is that the function select() in Database.php also uses arrays, but to indicate a range of values.Thus there is no easy way to indicate that a value does not need quoting. One option may be to use a special key that select() can recognize and not treat as an array of values. Looking into it...
Comment 5 Song Younghwan 2007-09-19 15:32:21 UTC
How about to create a class? It seems that DatabaseOracle.php has a similar class. And we can use a magic method __toString() in PHP 5.

class PostgresBlob {
    var $mData;

    function __construct($data) {
        $this->mData = $data;
    }

    function __toString() {
        return $this->mData;
    }
}

...

(in class DatabasePostgres)

function encodeBlob( $b ) {
    return new PostgresBlob(pg_escape_bytea( $b ));
}

function addQuotes( $s ) {
    ...
    } else if ($s instanceof PostgresBlob) {
        return "E'$s'";
    ...
}
Comment 6 Greg Sabino Mullane 2007-09-19 15:53:10 UTC
Yes, that's the direction I've been going, except putting the class in Database.php, as we'll need to check it from within there as well, and other DBs will also need to use it.
Comment 7 Greg Sabino Mullane 2007-09-19 16:26:38 UTC
Created attachment 4133 [details]
Proposed Blob class

How does this look? I'll also have the updater blow away any existing caches.
Comment 8 Song Younghwan 2007-09-19 17:00:05 UTC
Added code in Database.makeList() should be removed. Because it calls the function addQuotes() with the unwrapped string value of the Blob object, so addQuotes() which is called by it always fail to recognize the value as a blob. __toString() is a magic method in PHP 5. It's automatically called when its object should be used as a string. So that code isn't needed.

Other changes seem right.
Comment 9 Greg Sabino Mullane 2007-09-19 17:31:21 UTC
> __toString() is a magic method in PHP 5. It's automatically called when its
> object should be used as a string. So that code isn't needed.


Maybe in theory, but in testing it's trying to insert strings such as 'Object id #20' if the explicit call to toString is removed. Still getting unserialize offset errors anyway, will try again later tonight. Suggestions welcome, a working serialize->blobencode->blobdecode->unserialize example is what I'm aiming for.
Comment 10 Song Younghwan 2007-09-19 18:06:38 UTC
I use PHP 5.2.1 and it works properly. So I checked the problem from PHP 5 changelog, and the behavior of the method is different between versions.

Version 5.0.0 Release Candidate 1
18-Mar-2004
...
Changed __toString() to be called automatically only with print and echo statements. (Andi)

Version 5.2.0
02-Nov-2006
...
Changed __toString() to be called wherever applicable. (Marcus)

If the next mediawiki release should keep the required version of PHP as same as current(just PHP 5), it'll be good to move that explicit call into the function addQuotes() like below:

function addQuotes( $s ) {
    ...
    } else if ($s instanceof Blob) {
        return "'{$s->__toString()}'";
    ...
}

How about it?

Now I should sleep as it's 3 o'clock in Korea now, I'll be able to check a new comment tomorrow.
Comment 11 Greg Sabino Mullane 2007-09-20 21:34:58 UTC
Still not able to get this working without unserialize errors. I'm tempted to switch to base64. I starting to suspect that pg_escape_bytea and pg_unescape_bytea are broken in at least some versions.
Comment 12 Greg Sabino Mullane 2007-09-23 19:55:11 UTC
Okay, finally figured it out, thanks for the help here. See r26040.
Comment 13 Joe 2007-11-10 01:42:51 UTC
I have applied the Bug Fix to Database.php and DatabasePostgres.php but still have the same problem.  I am still recieving:
Notice: unserialize()[function.unserialize]: Error at offset 0 of 616 bytes in .../includes/BagOStuff.php on line 392

Is this the only fix to this bug?  Did the fix work for anybody else?  It's a little frustrating because everything online points to this fix, but I've tried it and it's not working for me.  Thanks.
Comment 14 Niccolo Rigacci 2007-11-23 10:36:21 UTC
Problem not solved here.

Upgraded MediaWiki from 1.9.3 to 1.11.0, then the unserialize() error.
Copied Database.php and DatabasePostgres.php from svn trunk, but this do not solve the problem.

- Debian Testing (Lenny)
- Postgres 8.2.4
- PHP 5.2.3
Comment 15 Niccolo Rigacci 2007-11-23 10:55:29 UTC
Sorry, sorry, sorry!!! The problem is solved.

May be some aggressive cache did keep the error showing (shift-reload was not sufficient).
I cleared the browser cache and restarted Apache server : the error is disappeared.

I re-close the bug, hoping that Comment #13 is a false alarm, like mine.

Sorry for annoying.
Comment 16 Berend de Boer 2007-12-11 20:13:19 UTC
Unfortunately the emergency fix nor the patch worked for me. Still see the same error message. And yes, did stop and start apache, but that made no difference.

PostgreSQL: 8.1.10.
PHP 5.1.4
Linux (LFS).

Also when I applied the patch it said there were a few lines of difference, so not sure against what version the patch was made.
Comment 17 Berend de Boer 2007-12-11 20:17:37 UTC
Perhaps helpful if I give the exact error messages:

Notice:  unserialize() function.unserialize: Error at offset 0 of 2214 bytes in .../creationpedia/includes/BagOStuff.php on line 392

Notice:  unserialize() function.unserialize: Error at offset 0 of 80 bytes in .../creationpedia/includes/BagOStuff.php on line 392
Comment 18 Greg Sabino Mullane 2007-12-11 20:46:45 UTC
No time to dig into this at the moment, but make sure you clear out the old entries by doing "TRUNCATE TABLE objectcache" and "TRUNCATE TABLE querycache" as the patch will only fix new entries, not fix any with bad bytes already in the database.
Comment 19 Berend de Boer 2007-12-11 22:45:07 UTC
Nope, didn't do anything. I already had gone to new pages to check if that might be an issue, but the error keeps popping up on every page.
Comment 20 Greg Sabino Mullane 2007-12-16 15:36:14 UTC
Can you try the revision of MediaWiki and see if that works for you? Which version of MW are you using?
Comment 21 Berend de Boer 2007-12-16 19:17:12 UTC
I'm using the version mentioned in this bug report. What do you mean with "Can you try the revision of MediaWiki"?
Comment 22 Greg Sabino Mullane 2007-12-16 23:48:45 UTC
I meant the latest subversion revision of MediaWiki. Right now I cannot duplicate your problem, so it might help to see if it is something that was fixed between the version you are using and the latest. If it is not fixed, we ideally need some sort of duplicateable test.
Comment 23 Chris Bandy 2008-01-24 17:06:40 UTC
Created attachment 4577 [details]
Revision 26040

Confirm that Comment #12 fixes this for me on Postgres 8.1.9 in MediaWiki 1.11.1
Comment 24 Greg Sabino Mullane 2008-02-10 17:01:49 UTC
Any luck on a newer revision, Berend?
Comment 25 Berend de Boer 2008-02-10 20:03:43 UTC
Went to use MySQL as that solved the problem. Unfortunately won't have time in the near future, so perhaps close as can't duplicate.
Comment 26 Greg Sabino Mullane 2008-02-10 20:06:31 UTC
Yep, that's one way to solve it :) Thanks for the response, please reopen this bug if you see the problem again with Postgres in the future.

Note You need to log in before you can comment on or make changes to this bug.


Navigation
Links