Page MenuHomePhabricator

LCStoreDB not working on postgres due to \0
Closed, ResolvedPublic

Description

LCStoreDB has a problem under postgres.

The lc_key 'deps' contains objects which will be serialized and than there are \0 in the serialized string, but for postgres a \0 is end of input stream, this means the lc_value for deps is cut of at the first \0, which breaks unserialize when getting this value back.

The insert row is ([...] is a placeholder to make it shorter):
array (

'lc_lang' => 'de',
'lc_key' => 'deps',
'lc_value' => 'a:9:{i:0;O:14:"FileDependency":2:{s:24:"' . "\0" . 'FileDependency' . "\0" . 'filename";s:110:[...];i:2;}}',

)

Gives:
INSERT /* LCStoreDB::set */ INTO "l10n_cache" (lc_lang,lc_key,lc_value) VALUES ('de','deps','a:9:{i:0;O:14:"FileDependency":2:{s:24:"')

Reading on the internet, the only chance here is to use bytea, which can be done by using Database::decodeBlob and Database::encodeBlob. Than the \0 is changed to \000, but I didnot know, if oracle and sqlite still will work than.

Maybe there is another solution.


Version: 1.23.0
Severity: normal

Details

Reference
bz62098

Related Objects

View Standalone Graph
This task is connected to more than 200 other tasks. Only direct parents and subtasks are shown here. Use View Standalone Graph to show more of the graph.
StatusSubtypeAssignedTask
InvalidNone
ResolvedNone

Event Timeline

bzimport raised the priority of this task from to Medium.Nov 22 2014, 3:07 AM
bzimport set Reference to bz62098.
bzimport added a subscriber: Unknown Object (MLST).

I ran into this problem last week too.

I bisect this down to Change-Id I427c6de5a0a29b43cff755db0eb8a750db620173.

But that seems to be just a code beautification patch that should not change any behavior. Why does that change expose this latent bug?

PHP seralizer uses \0 for private/protected fields. Since we stuff serialized PHP into the DB, this caused the problem.

Change 131075 had a related patch set uploaded by Jjanes:
PostgreSQL: Make l10n_cache.lc_value binary

https://gerrit.wikimedia.org/r/131075

(In reply to Aaron Schulz from comment #3)

PHP seralizer uses \0 for private/protected fields. Since we stuff
serialized PHP into the DB, this caused the problem.

Is there any way for the serializer to generate \0 without there being private/protected fields? I wonder how likely it is that someone has already tried to store \0 even before I427c6de5a0a29b43cff755db0eb8a750db620173.

Change 131075 merged by jenkins-bot:
PostgreSQL: Make l10n_cache.lc_value binary

https://gerrit.wikimedia.org/r/131075

Change 131919 had a related patch set uploaded by Jjanes:
PostgreSQL: Make l10n_cache.lc_value binary

https://gerrit.wikimedia.org/r/131919

Change 131919 merged by jenkins-bot:
PostgreSQL: Make l10n_cache.lc_value binary

https://gerrit.wikimedia.org/r/131919

patch set was successfully merged and backported

Jdforrester-WMF subscribed.

Migrating from the old tracking task to a tag for PostgreSQL-related tasks.