Skip to content

fix(db): stringify scalar values in PDO blob serialization#14

Merged
TDannhauer merged 2 commits into
FRAMEWORK_6_0from
fix/string_into_binary_storage
Jun 18, 2026
Merged

fix(db): stringify scalar values in PDO blob serialization#14
TDannhauer merged 2 commits into
FRAMEWORK_6_0from
fix/string_into_binary_storage

Conversation

@TDannhauer

@TDannhauer TDannhauer commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fix PDO BLOB serialization so scalar values (integers, floats, booleans) are stored correctly instead of empty binary data
  • Apply the same change in both autoload trees: legacy lib/ (PSR-0) and modern src/ (PSR-4)
  • Complements horde/prefs SQL storage fix; protects all callers of insertBlob() / updateBlob(), not only preferences

Problem

Horde_Db_Adapter_Pdo_Base and Horde\Db\Adapter\Pdo\Base extract LOB payload via _lobValueString() / lobValueString():

return is_string($data) ? $data : '';

Non-string scalars (e.g. integer 1 from checkbox preferences) are treated as invalid and serialized as an empty string. The database write succeeds, but the stored blob is empty.

This affected horde_prefs when integer values reached the DB layer without prior string coercion—for example IMP use_trash appeared saved in the UI but reloaded as disabled.

Solution

Stringify scalar LOB values before binding:

return is_string($data) ? $data : (is_scalar($data) ? (string) $data : '');

Changed files

Tree File Method
lib/ (PSR-0) lib/Horde/Db/Adapter/Pdo/Base.php _lobValueString()
src/ (PSR-4) src/Adapter/Pdo/Base.php lobValueString()

Both copies must stay in sync: horde/db autoloads Horde_Db_* from lib/ today and Horde\Db\* from src/ for the ongoing namespace migration.

Related change

  • horde/prefs: lib/Horde/Prefs/Storage/Sql.php also casts preference values with strval() before wrapping them in Horde_Db_Value_Binary (defense in depth at the prefs layer)

Test plan

  • Store integer 1 via Horde_Db_Value_Binary + updateBlob() on PostgreSQL; confirm pref_value / blob column is not empty
  • Store integer 0 and string '1' / '0'; confirm round-trip matches input
  • Save IMP checkbox preference use_trash and verify persistence without the prefs-only workaround
  • Run existing horde/db unit/integration tests if available
  • Smoke-test other BLOB writes (e.g. binary attachment metadata) to ensure no regression for stream/resource LOB values

Checkbox and number preferences are stored as integers by the UI layer.
Passing those scalars to Horde_Db_Value_Binary caused empty blobs to be
written to horde_prefs, so settings such as IMP use_trash looked saved but
reloaded as disabled.
@TDannhauer TDannhauer requested a review from ralflang June 17, 2026 12:22
@TDannhauer TDannhauer changed the title fix(prefs): cast values to string before binary SQL storage fix(db): stringify scalar values in PDO blob serialization Jun 17, 2026
@ralflang

Copy link
Copy Markdown
Member

Do you see this across PDO or only on postgres?

Added tests for inserting and updating blob data with scalar binary payloads.
@TDannhauer

Copy link
Copy Markdown
Contributor Author

yes, affects all, as it is located in the base. added testcase with SQLite

@TDannhauer TDannhauer merged commit 71ecc37 into FRAMEWORK_6_0 Jun 18, 2026
0 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants