Skip to content

test(integration): grep skips files that gpg can't decrypt#1471

Merged
annejan merged 4 commits into
mainfrom
tests/grep-skips-undecryptable
May 13, 2026
Merged

test(integration): grep skips files that gpg can't decrypt#1471
annejan merged 4 commits into
mainfrom
tests/grep-skips-undecryptable

Conversation

@annejan
Copy link
Copy Markdown
Member

@annejan annejan commented May 13, 2026

Summary

End-to-end coverage for the env-aware `Executor::executeBlocking` call in `ImitatePass::grepMatchFile` (imitatepass.cpp:1055). The function feeds each `.gpg` file in the store to `gpg --decrypt` via the env-aware Executor overload; when gpg exits non-zero (or stdout is empty), the match list for that file is discarded and `grepScanStore` continues to the next file.

The existing unit test `grepMatchFileFailedDecryptReturnsEmpty` (tst_util) covers the single-file branch by pointing at a non-existent gpg binary. This new integration test exercises the multi-file scan with real gpg + a real keyring:

  1. Insert two legitimate entries (`work/github`, `work/gitlab`) both containing the "token" substring.
  2. Plant two `.gpg` files that aren't valid gpg ciphertext at all:
    • `work/garbage-token.gpg` — plain text "...contains the token word"
    • `corrupt.gpg` — binary junk
  3. Run `Grep("token")`.
  4. Assert exactly the two legitimate entries are returned; neither corrupt file leaks a match (even though one has "token" in its raw plaintext bytes, gpg fails to decrypt it and `grepMatchFile` returns empty).

Test plan

  • `qmake6 -r && make -j4` clean
  • `tests/auto/integration/tst_integration` — 20/20 (was 19, +1)
  • `clang-format` applied

Notes

This is a behavioural / smoke test of the full env-aware grep path, not a guard-isolation test — `grepMatchFile` is naturally robust to empty plaintext via its empty-line skip in the match loop, so even with the `rc != 0` early-return defanged the integration test still passes. The dedicated unit test covers the guard branch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Added an integration test ensuring grep/search ignores corrupt or undecryptable encrypted password files and returns only genuine matched entries, reducing false positives and improving search reliability when damaged or tampered files are present.

Review Change Stack

End-to-end coverage for the env-aware Executor call in
ImitatePass::grepMatchFile (imitatepass.cpp:1055). The function feeds
each .gpg file in the store to `gpg --decrypt` via the env-aware
Executor overload; when gpg exits non-zero (or stdout is empty), the
match list for that file is discarded and grepScanStore continues to
the next file.

The unit-test grepMatchFileFailedDecryptReturnsEmpty already covers
the single-file branch by pointing at a non-existent gpg binary. This
new integration test exercises the multi-file scan with real gpg:

- Insert two legitimate entries containing the "token" substring.
- Plant two .gpg files that aren't valid gpg ciphertext at all (one
  with "token" in plaintext bytes, one with binary junk).
- Run Grep("token").
- Assert exactly the two legitimate entries are returned; neither
  corrupt file leaks a match.

Build clean, 20/20 integration tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: fb3edca9-f859-485c-b23a-b3ca8ac8c1c6

📥 Commits

Reviewing files that changed from the base of the PR and between 7793149 and 1648a41.

📒 Files selected for processing (1)
  • tests/auto/integration/tst_integration.cpp

📝 Walkthrough

Walkthrough

A new integration test slot, imitatePass_grepSkipsUndecryptableFiles, adds an <algorithm> include, sets up an ImitatePass temp store, creates two valid encrypted entries containing "token" plus two corrupt .gpg files, runs Grep("token"), and asserts only the two valid entries are returned.

Changes

Grep robustness test

Layer / File(s) Summary
Grep skips undecryptable files test
tests/auto/integration/tst_integration.cpp
Adds an <algorithm> include and a Qt test slot imitatePass_grepSkipsUndecryptableFiles that configures a temporary ImitatePass store, creates two valid encrypted entries and two corrupt .gpg files, runs Grep("token"), and verifies only the two legitimate entries are returned.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • IJHack/QtPass#1112: Adds ImitatePass integration tests covering grep edge cases and shared test store setup.
  • IJHack/QtPass#1073: Refactors grep output parsing in src/pass.cpp, which underpins pass.Grep behavior validated by this test.

Suggested labels

size:S

Poem

🐰 I hopped through tests with nimble paws,
Skipping broken files without a pause,
Only true tokens made my whiskers twitch,
Corrupt .gpg left in a ditch,
Hooray for clean grep — and carrot bliss!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: a new integration test that verifies grep functionality skips files GPG cannot decrypt.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tests/grep-skips-undecryptable

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Line 402: Replace the bare QVERIFY assertion that checks
QDir(storeDir.path()).mkpath("work") with QVERIFY2 to include a descriptive
failure message; update the call in the test where
QVERIFY(QDir(storeDir.path()).mkpath("work")) is used so it becomes
QVERIFY2(..., "<message>") and craft the message to include context and the
store path (e.g., "failed to create work directory at " + storeDir.path()) so
test failures clearly report which directory creation failed.
- Around line 425-430: The test writes 24 bytes from a 17-byte literal causing a
buffer over-read; fix the corrupt fixture creation by using a sized buffer or
QByteArray of the exact length and pass that length to QFile::write instead of
the incorrect 24. Locate the corrupt file creation where QFile c2(corrupt2) is
opened and c2.write("\xFF\xFE\x00\x01 binary junk\n", 24) is called and replace
it with writing a QByteArray or const char* with the correct size (e.g., compute
strlen or use QByteArrayLiteral) and pass that correct size to c2.write to
eliminate undefined behavior.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2017a496-acdd-49ca-abe8-c3ed72ce1f14

📥 Commits

Reviewing files that changed from the base of the PR and between ef67e0e and 124511e.

📒 Files selected for processing (1)
  • tests/auto/integration/tst_integration.cpp

Comment thread tests/auto/integration/tst_integration.cpp Outdated
Comment thread tests/auto/integration/tst_integration.cpp Outdated
@coveralls
Copy link
Copy Markdown

coveralls commented May 13, 2026

Coverage Status

coverage: 29.068% (-0.02%) from 29.083% — tests/grep-skips-undecryptable into main

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

❌ Failed to clone repository into sandbox. Please try again.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 2 unresolved review comments.

Files modified:

  • tests/auto/integration/tst_integration.cpp

Commit: 9c983a738a9eef1a67bdb2329020662c6f88805e

The changes have been pushed to the tests/grep-skips-undecryptable branch.

Time taken: 2m 8s

@codecov
Copy link
Copy Markdown

codecov Bot commented May 13, 2026

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
491 1 490 8
View the top 1 failed test(s) by shortest run time
tst_integration::imitatePass_grepSkipsUndecryptableFiles
Stack Traces | 0.007s run time
'bytesWritten1 == 55' returned FALSE. (failed to write test payload to c1)

To view more test analytics, go to the Test Analytics Dashboard
📋 Got 3 mins? Take this short survey to help us improve Test Analytics.

Fixed 1 file(s) based on 2 unresolved review comments.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Line 428: Add explicit assertions after the QIODevice write calls (the
c1.write(...) calls) to verify the write succeeded; for each write (the one
writing "not a real gpg payload but contains the token word\n" and the other at
the later occurrence) check the returned qint64 equals the expected byte count
(or is not -1) and use QVERIFY2 with a descriptive message (e.g., "failed to
write test payload to c1") so the test fails clearly on write errors.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: d5a29fb4-a0f9-4ad4-b052-ed5adb073703

📥 Commits

Reviewing files that changed from the base of the PR and between 124511e and 9c983a7.

📒 Files selected for processing (1)
  • tests/auto/integration/tst_integration.cpp

Comment thread tests/auto/integration/tst_integration.cpp Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • tests/auto/integration/tst_integration.cpp

Commit: 7793149aa75c2477fa2c07e224901844b9dfc3c8

The changes have been pushed to the tests/grep-skips-undecryptable branch.

Time taken: 2m 1s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/auto/integration/tst_integration.cpp`:
- Around line 428-429: The assertion uses the wrong expected byte count for the
payload written via c1.write; update the check that compares bytesWritten1 (from
c1.write("not a real gpg payload but contains the token word\n")) to use the
correct length (52) or compute the expected length dynamically (e.g., via strlen
on the literal) and replace the hardcoded 55 in the QVERIFY2 assertion so
bytesWritten1 == <correct_length> is asserted.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 74a594a0-9d19-4414-a5a1-e7daf1a99e58

📥 Commits

Reviewing files that changed from the base of the PR and between 9c983a7 and 7793149.

📒 Files selected for processing (1)
  • tests/auto/integration/tst_integration.cpp

Comment thread tests/auto/integration/tst_integration.cpp Outdated
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • tests/auto/integration/tst_integration.cpp

Commit: 1648a4147ac102846599ae51e561883f4c7b4c4f

The changes have been pushed to the tests/grep-skips-undecryptable branch.

Time taken: 1m 39s

Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
@annejan annejan merged commit 751a317 into main May 13, 2026
23 of 25 checks passed
@annejan annejan deleted the tests/grep-skips-undecryptable branch May 13, 2026 21:50
annejan added a commit that referenced this pull request May 13, 2026
…pp (#1475)

CodeRabbit's auto-fix on #1471 captured the QFile::write() return value
and asserted it equals the payload size — sensible nit. The resulting
QVERIFY2 calls busted the 80-col limit and the super-linter is rejecting
unrelated PRs (#1474 head was 7430a35) because clang-format runs over
the whole tree.

Reformat both calls — break after the condition, matches the style of
all the other QVERIFY2 sites added in earlier security PRs.

No semantic change.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
annejan added a commit that referenced this pull request May 13, 2026
* chore: clang-format two over-long QVERIFY2 lines in tst_integration.cpp

CodeRabbit's auto-fix on #1471 captured the QFile::write() return value
and asserted it equals the payload size — sensible nit. The resulting
QVERIFY2 calls busted the 80-col limit and the super-linter is rejecting
unrelated PRs (#1474 head was 7430a35) because clang-format runs over
the whole tree.

Reformat both calls — break after the condition, matches the style of
all the other QVERIFY2 sites added in earlier security PRs.

No semantic change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(keygendialog): widget tests for the GPG keygen dialog

KeygenDialog (the modal that fronts GPG key-pair generation) had zero
test coverage. Added six widget-level tests in a new tests/auto/
keygendialog/ subdirectory, modelled on the existing tests/auto/
importkeydialog/ pattern:

- constructionLoadsNonEmptyTemplate: dialog instantiates, plainTextEdit
  receives the default GPG batch template (covers both the ed25519 and
  RSA fallback paths via the shared Name-Real:/Name-Email: substring
  check).
- expertCheckboxTogglesTemplateEditor: toggling the "Expert" checkbox
  flips plainTextEdit between read-only/disabled and editable/enabled.
- nameTextUpdatesNameRealLine: typing in the Name field replaces the
  Name-Real: line in the template.
- emailTextUpdatesNameEmailLine: same for Name-Email:.
- matchingPassphrasesEnableButtonBox: identical text in both passphrase
  fields enables the OK button.
- mismatchedPassphrasesDisableButtonBox: differing passphrases disable
  OK.

The dialog is normally parented to ConfigDialog; tests pass nullptr to
sidestep ConfigDialog construction. The protected done() slot isn't
exercised — it dispatches into dialog->genKey() which dereferences the
ConfigDialog parent.

Build clean, 8/8 keygendialog tests pass, 46/46 ui tests still pass,
doxygen unchanged.

Wired into tests/auto/auto.pro SUBDIRS and .gitignore.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(keygendialog): QVERIFY2 + scanner-safe passphrase fixtures

Two reviewer nits on #1476:

- Replace bare QVERIFY(obj != nullptr) with QVERIFY2(obj != nullptr,
  "<name> != nullptr") at every findChild site so a future test failure
  reports which specific widget couldn't be located.
- Swap the "secret" passphrase literals in the two passphrase-matching
  tests for "testkey123" / "testkey456" — gitleaks-friendly fixtures
  that still exercise the equality / inequality paths.

No behavioural change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* test(keygendialog): descriptive QVERIFY2 messages instead of tautological ones

CodeRabbit nit on the previous follow-up: "checkBox != nullptr" as a
failure message just restates the condition; QVERIFY2 already prints
the condition. Switch to the existing "<widget-name> widget must exist"
style already used on line 47 for plainTextEdit.

No behavioural change.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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