• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

IJHack / QtPass / 35635087026
93%

Build:
DEFAULT BRANCH: main
Ran 21 Sep 2026 06:04PM UTC
Jobs 1
Files 114
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

21 Sep 2026 05:55PM UTC coverage: 79.01% (-0.01%) from 79.021%
35635087026

push

github

web-flow
Insert: gpg never opens a path in the store for output (#1882)

* Insert: gpg never opens a path in the store for output

ImitatePass::Insert() ran gpg with --output on the entry's own path right
after refuseLinkedPath() had judged the name. Whoever can write to the
store could make the name a link in between, and gpg --yes wrote the
ciphertext through to whatever the link pointed at (reproduced: a file
outside the store overwritten with ciphertext). The link checks cannot
close that window; not opening store paths by name can.

gpg encrypts into a QTemporaryDir of QtPass's own (0700, outside the
store, out of a co-writer's reach). When its step ends, before the git
steps queued behind it run, placeEncryptedFile() reads that output and
writes it through a QTemporaryFile created next to the entry, by its open
handle, then gives it the entry's name with Util::replaceFile(): rename(2)
or MoveFileEx, which replaces whatever entry is under the name (a planted
link as an entry) and follows nothing. Not QFile::rename(): when the plain
rename fails it falls back to a copy that opens the target by name, and
would write through a link planted in between. Without overwrite, link()
and unlink refuse a name that gained an entry since the check. If the
temporary's own name was swapped for a link, the entry is now that link
and the insert is reported as failed; nothing was written through it.

A failed placement is not shown from inside the executor's completion (a
dialog would spin the event loop and let the queued git steps run first):
finished() turns it into a failed gpg step, the cancel loop drops the git
steps, and the reason reaches the interface through processErrorExit. A
store-relative name, which the dialog passes for a new entry, is resolved
against the store first: gpg used to do that in its working directory.
Entries are written 0600, as pass writes them.

Tests (tst_imitatepass): gpg's --output is outside the store and the
scratch is gone afterwards, ... (continued)

45 of 63 new or added lines in 2 files covered. (71.43%)

8 existing lines in 2 files now uncovered.

7419 of 9390 relevant lines covered (79.01%)

80.39 hits per line

Uncovered Changes

Lines Coverage ∆ File
18
76.36
-0.58% src/imitatepass.cpp

Coverage Regressions

Lines Coverage ∆ File
7
0.0
0.0% src/qrc_qmake_qmake_qm_files.cpp
1
76.36
-0.58% src/imitatepass.cpp
Jobs
ID Job ID Ran Files Coverage
1 35635087026.1 21 Sep 2026 06:04PM UTC 114
79.01
GitHub Action Run
Source Files on build 35635087026
  • Tree
  • List 114
  • Changed 6
  • Source Changed 4
  • Coverage Changed 6
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #35635087026
  • e24e0f4e on github
  • Prev Build on main (#35624352350)
  • Next Build on main (#35638958349)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc