Skip to content

fix(activesync): guard null charset before strcasecmp in getMimePart()#80

Merged
TDannhauer merged 1 commit into
FRAMEWORK_6_0from
fix/imap-mimepart-null-charset
Jul 9, 2026
Merged

fix(activesync): guard null charset before strcasecmp in getMimePart()#80
TDannhauer merged 1 commit into
FRAMEWORK_6_0from
fix/imap-mimepart-null-charset

Conversation

@TDannhauer

Copy link
Copy Markdown
Contributor

Summary

  • Guard against null charset before calling strcasecmp() in Horde_ActiveSync_Imap_Message::getMimePart()

Motivation

Horde_Mime_Part::getCharset() returns null for any non-text MIME part (attachments, inline images, etc.). getMimePart() passed that value directly into strcasecmp(), which on PHP 8.1+ deprecates passing null to a non-nullable string parameter. Since getMimePart() runs for every MIME part fetched during a sync, this produces a "Passing null to parameter #1 ($string1) of type string is deprecated" notice for every non-text part of every synced message -- a significant amount of log I/O on accounts with attachments, and a plausible contributor to the erratic sync behavior reported in #77.

Changes

  • lib/Horde/ActiveSync/Imap/Message.php: only run the ISO-8859-1 comparison when the part actually has a charset; behavior is unchanged (parts without a charset were never ISO-8859-1).

Test plan

  • Manual: sync an account with attachments/inline images on PHP 8.4 and confirm the deprecation notice no longer appears in the Horde log
  • Existing package test suite (no behavior change expected)

Related to #77

Horde_Mime_Part::getCharset() returns null for any non-text MIME part
(attachments, inline images, etc.). getMimePart() passed that value
directly into strcasecmp(), which is deprecated on PHP 8.1+ and logs a
notice for every non-text part fetched during a sync -- flooding the
log with "Passing null to parameter #1 ($string1) of type string is
deprecated" warnings, as reported against Gmail/Nine on Android sync.

Skip the ISO-8859-1 comparison when no charset is set instead of
comparing against null. Behavior is unchanged: parts without a
charset were never ISO-8859-1 anyway.

Refs #77
@TDannhauer
TDannhauer requested a review from ralflang July 9, 2026 19:44
@TDannhauer
TDannhauer merged commit e28f708 into FRAMEWORK_6_0 Jul 9, 2026
1 check failed
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

🔍 CI Results

Overall: ❌ 12/12 lanes failed

TL;DR: ❌ Quality issues: PHPUnit: 36 tests failed; PHPStan: 331 unique errors in 8 lanes; PHP-CS-Fixer: 18 files.

Summary by PHP Version

PHP dev stable
8.0
8.1
8.2
8.3
8.4
8.5

Quality Metrics

  • PHPUnit: 16 failures, 20 errors out of 205 tests in 8 lanes ❌
    Per-test detail in the table below. Raw JUnit XML and JSON are uploaded as workflow artifacts.

    Which tests failed
    Type Test Lanes Message
    ❌ failure Horde\ActiveSync\AppointmentTest::testSetRecurrenceEas16SetsFirstDayOfWeek php8.2-dev, php8.2-stable, php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [PHPUnit\Framework\ExpectationFailedException] Failed asserting that '' matches expected 0.
    ⚠️ error Horde\ActiveSync\Request\FindRequestTest::testMockDriverReturnsSuccessfulEmptyFindResults php8.2-dev, php8.2-stable, php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [InvalidArgumentException] Missing required state object
    ❌ failure Horde\ActiveSync\Request\FindRequestTest::testParseFindRangeHonorsClientWindow php8.2-dev, php8.2-stable, php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [PHPUnit\Framework\ExpectationFailedException] Failed asserting that 100 is identical to 101.
    ⚠️ error Horde\ActiveSync\SyncTimeBudgetTest::testGetSyncConfigDefaultsToEmptyArray php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
    ⚠️ error Horde\ActiveSync\SyncTimeBudgetTest::testGetSyncConfigReturnsConfiguredValues php8.3-dev, php8.3-stable, php8.4-dev, php8.4-stable, php8.5-dev, php8.5-stable [Error] Call to undefined method PHPUnit\Framework\MockObject\MockBuilder::getMockForAbstractClass()
  • PHPStan (advisory): 331 unique errors in 8 lanes ⚠️

  • PHP-CS-Fixer: 18 unique files with issues (of 197 checked) ⚠️

❌ Failed Lanes

php8.0-dev

  • PHPUnit: ❌ Setup failed (No result file found)
  • PHPStan: ❌ Setup failed (No result file found)

php8.0-stable

  • PHPUnit: ❌ Setup failed (Composer install failed in /tmp/horde-ci/lanes/php8.0-stable/ActiveSync: Your requirements could not be resolved to an installable set of packages.)
  • PHPStan: ❌ Setup failed (Composer install failed in /tmp/horde-ci/lanes/php8.0-stable/ActiveSync: Your requirements could not be resolved to an installable set of packages.)

php8.1-dev

  • PHPUnit: ❌ Setup failed (No result file found)
  • PHPStan: ❌ Setup failed (No result file found)

php8.1-stable

  • PHPUnit: ❌ Setup failed (No result file found)
  • PHPStan: ❌ Setup failed (No result file found)

php8.2-dev

  • PHPUnit: 2 failures, 1 error

php8.2-stable

  • PHPUnit: 2 failures, 1 error

php8.3-dev

  • PHPUnit: 2 failures, 3 errors

php8.3-stable

  • PHPUnit: 2 failures, 3 errors

php8.4-dev

  • PHPUnit: 2 failures, 3 errors
  • PHP-CS-Fixer: 18 files with issues

php8.4-stable

  • PHPUnit: 2 failures, 3 errors

php8.5-dev

  • PHPUnit: 2 failures, 3 errors

php8.5-stable

  • PHPUnit: 2 failures, 3 errors

CI powered by horde-componentsView full results

@TDannhauer
TDannhauer deleted the fix/imap-mimepart-null-charset branch July 10, 2026 11:02
ralflang added a commit that referenced this pull request Jul 18, 2026
Release version 3.1.0

fix(sync): emit SYNC_MODIFY replies for EAS 16 email modifies
fix(activesync): throttle deferred-import keep-alive tokens
fix(activesync): address streaming review findings
docs(activesync): restructure documentation by audience
feat(activesync): defer up-sync imports and emit WBXML keep-alives when streaming
docs(activesync): note batch-size vector consolidation for Horde 6
feat(activesync): stream Sync responses incrementally
Merge pull request #82 from horde/fix/settings-oof-empty-msgs
fix(activesync): guard empty OOF messages in Settings response
docs(todo): document folder UID map long-term work
docs(activesync): explain crc32 mask in folder UID generation
Merge pull request #81 from horde/fix/deterministic-folder-uids-moveitems-gone
Potential fix for pull request finding
Potential fix for pull request finding
Potential fix for pull request finding
fix(activesync): stabilize folder UIDs after hierarchy changes
Merge pull request #80 from horde/fix/imap-mimepart-null-charset
fix(activesync): guard null charset before strcasecmp in getMimePart()
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.

1 participant