Skip to content

transplants: warn on zero-byte binary file additions (bug 1709608)#1157

Open
tnikkel wants to merge 1 commit into
mozilla-conduit:mainfrom
tnikkel:bug1709608/warn-zero-byte-binary
Open

transplants: warn on zero-byte binary file additions (bug 1709608)#1157
tnikkel wants to merge 1 commit into
mozilla-conduit:mainfrom
tnikkel:bug1709608/warn-zero-byte-binary

Conversation

@tnikkel
Copy link
Copy Markdown

@tnikkel tnikkel commented May 13, 2026

Summary

Surface zero-byte binary file additions to the landing user as a warning that must
be acknowledged before landing.

Bug 1709608 has recurred multiple times since 2021: when Lando lands using a
Phabricator diff whose creationMethod is commit (the auto-generated diff
Phabricator creates from a landed commit), binary file payloads have been stripped,
so the file lands as 0 bytes. Most recently this hit bug 2034984 (test + reference
images in a reftest both landed as 0 bytes, causing the comparison to silently pass
and removing test coverage with no signal) and bug 2005089 (Android sample-app
launcher icons landed as 0 bytes).

The 2023-12 fix in #364 only covered the uplift creation path; non-uplift relands
remain vulnerable. As an interim safety net, this PR adds a warning that inspects
the rendered patch and surfaces any zero-byte binary additions. A follow-up can
add a targeted blocker that uses differential.querydiffs to detect the regression
case (binary file went from non-zero to zero between diff versions on the same
revision) and block automatically, without bothering authors of legitimately-empty
binary fixtures.

The new PreventEmptyBinaryCheck is written as a neutral detection primitive
(no warn/block opinion in its message) so a future blocker can reuse it unchanged.

Bug: https://bugzilla.mozilla.org/show_bug.cgi?id=1709608

Test plan

  • New unit tests in src/lando/utils/tests/test_landing_checks.py cover:
    text-only diff, non-empty binary addition, binary deletion, empty binary
    addition (the bug 1709608 signature), and a mixed diff (only the empty
    addition is reported).
  • Manual smoke: trigger a landing of a revision whose active diff was sourced
    from a landed commit and confirm the warning appears.

@tnikkel tnikkel requested a review from a team as a code owner May 13, 2026 05:01
@github-actions
Copy link
Copy Markdown

View this pull request in Lando to land it once approved.

@shtrom
Copy link
Copy Markdown
Member

shtrom commented May 13, 2026

Looks good. There's a bit more housekeeping needed:

  1. The hook needs to be added to this list
    class HooksChoices(models.TextChoices):
    """List of landing hooks that can be enabled for a repo."""
    so it's available for selection (that causes the first test failure)
  2. We should add a data-migration method in the ilk of https://github.com/mozilla-conduit/lando/blob/main/src/lando/utils/management/commands/migrate_data.py#L71-L99 which enable this hook by default for any Phabricator repo in the DB (see Repo.is_phabricator_repo https://github.com/mozilla-conduit/lando/blob/main/src/lando/main/models/repo.py#L175)
  3. Could you run make format to fix the linting errors?

Thanks!

@tnikkel tnikkel force-pushed the bug1709608/warn-zero-byte-binary branch from 24245fe to 791a5dc Compare May 13, 2026 05:23
@shtrom
Copy link
Copy Markdown
Member

shtrom commented May 13, 2026

  1. Due to 1, this will need a run of make migrations, too (and a git add of the newly created file).

@tnikkel tnikkel force-pushed the bug1709608/warn-zero-byte-binary branch from 791a5dc to bba0f76 Compare May 13, 2026 05:28
Surface zero-byte binary file additions to the landing user as a
warning that must be acknowledged before landing.

Bug 1709608 has recurred multiple times since 2021: when Lando lands
using a Phabricator diff whose `creationMethod` is `commit` (the
auto-generated diff Phabricator creates from a landed commit), binary
file payloads have been stripped, so the file lands as 0 bytes. Most
recently this hit bug 2034984 (where both the test and reference image
in a reftest landed as 0 bytes, causing the comparison to silently pass
and removing test coverage with no signal) and bug 2005089 (Android
sample-app launcher icons landed as 0 bytes).

The 2023-12 fix in mozilla-conduit#364 only covered the uplift creation path; non-uplift
relands remain vulnerable. As an interim safety net, add a warning that
inspects the rendered patch and surfaces any zero-byte binary additions.
A follow-up will add a targeted blocker that uses `differential.querydiffs`
to detect the regression case (binary file went from non-zero to zero
between diff versions on the same revision) and block automatically,
without bothering authors of legitimate empty-binary fixtures.

The new `PreventEmptyBinaryCheck` is written as a neutral detection
primitive (no warn/block opinion in its message) so the follow-up
blocker can reuse it unchanged.
@tnikkel tnikkel force-pushed the bug1709608/warn-zero-byte-binary branch from bba0f76 to bfa5fd9 Compare May 13, 2026 05:47
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this addition in the migration file. (1) we should probably only add this to repos one at a time via the admin, and (2) this should be applied to repos that explicitly need it.

I suggest removing this change.

Comment on lines +666 to +667
zcmZ?wbhEHbWMp7uXkdSr1_lE>3=9k!85kJ?7+e9j7+M3l85kIz?VMfFP&3pMz`(EJ
o&%nUd&(O%n&CtNI%g_nQz5(_qzaP=zsBtDUMI;Cj1_p+T0VKi-RR910
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this content?

Comment on lines +736 to +740
assert "empty.png" in result
assert "real.png" not in result, (
"Non-empty binary additions must not appear in the report."
)
assert "src/bar.cpp" not in result, "Text additions must not appear in the report."
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be more explicit here.

Comment on lines +720 to +721
assert "empty.png" in result
assert "1709608" in result
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be more explicit here with the warning message, and more human readable.

Comment on lines +343 to +344
Symptom of bug 1709608: when Lando lands using a Phabricator diff whose
`creationMethod` is `commit`, binary file payloads have been stripped
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be better to discuss the actual causes (e.g., backouts, reopened revisions, automatically updated revisions, etc.) vs. mentioning creationMethod here, since that is quite low level.


def next_diff(self, diff: dict):
# Only flag *additions* of binary files. Modifications and deletions
# legitimately have zero or partial-binary payloads.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what partial-binary payloads means here?

def result(self) -> str | None:
if self.empty_binary_files:
return (
"Revision adds zero-byte binary files "
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're mixing diff and revision throughout this check. I think we can stick with diff since it is the source of the issue.

from lando.main.support import LegacyAPIException
from lando.utils.landing_checks import (
DiffAssessor,
PreventEmptyBinaryCheck,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PreventEmptyBinaryCheck,
PreventEmptyBinaryFileAdditionCheck,

Comment on lines +546 to +551
Symptom of bug 1709608: diffs sourced from a landed commit have their
binary payloads stripped by Phabricator, so a re-land using such a diff
silently produces empty binary files in the tree. This warning surfaces
the situation; the targeted blocker (later) catches the regression case
automatically. Implemented as a warning so legitimately-empty binary
fixtures (rare but real -- e.g. `empty.xpi`, `0_sized_file`) can still
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reducing verbosity here would be good.

Suggested change
Symptom of bug 1709608: diffs sourced from a landed commit have their
binary payloads stripped by Phabricator, so a re-land using such a diff
silently produces empty binary files in the tree. This warning surfaces
the situation; the targeted blocker (later) catches the regression case
automatically. Implemented as a warning so legitimately-empty binary
fixtures (rare but real -- e.g. `empty.xpi`, `0_sized_file`) can still
Diffs sourced from a landed commit have their
binary payloads stripped by Phabricator, so a re-land using such a diff
silently produces empty binary files in the tree. This warning surfaces
the situation; at time of landing the check catches this case and warns about it.

the situation; the targeted blocker (later) catches the regression case
automatically. Implemented as a warning so legitimately-empty binary
fixtures (rare but real -- e.g. `empty.xpi`, `0_sized_file`) can still
be landed by acknowledging the warning.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
be landed by acknowledging the warning.

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.

3 participants