Repository navigation
Conversation
Parse failures no longer quote the pasted URL, background failures log only the exception type, the PTB, Canary and discordapp.com hosts are stored as discord.com, and a Keystore or storage failure no longer claims the address is invalid. Findings: sec-egress-secrets-1, q-uiux-11, q-uiux-m1
Both sides are compared after NFC, whitespace collapsing and removal of control, format and bidi characters and unpaired surrogates; suggestions are off for the field, and a name with nothing typeable is confirmed by its ID. Findings: q-input-9, sec-protocol-3
A refused socket only set CONN_STATUS_SOCKET_ERROR, so zdtun_conn_close returned early and on_connection_close never ran: the flow state leaked, Java never saw onFlowClosed, and the client got no RST. Close through zdtun_conn_close instead, with the RST acknowledging the SYN. Fixes sec-native-forward-path-1.
The forced purge destroyed the oldest connections whatever their protocol, so a burst of other in-VPN sockets could RST the game's quiet capture connection. Rank connections instead: socketless ones first and uncounted, then UDP/ICMP, then TCP, and last the flows gf2capture still inspects (new optional on_purge_priority callback). Fixes sec-native-forward-path-2.
Fixes sec-native-forward-path-3.
A FIN+ACK half-closed the server socket at once, dropped the FIN segment's own payload and ACKed bytes still queued, which later failed with EPIPE and reset the connection. Queue the payload and defer the shutdown and its ACK until the queue drains; if the server closes first, ACK the pending FIN so the client can finish. A FIN retransmitted after it was ACKed is ACKed again without being counted twice. Fixes sec-native-forward-path-4.
zdtun.c is compiled into a host test with in-memory fake sockets; run app/src/test/cpp/run-zdtun-host-test.sh on Linux or macOS. Also list the local zdtun modifications in THIRD_PARTY_NOTICES.md. Covers sec-native-forward-path-1, -2, -3 and -4.
…rations The legacy global region seeds each client's capture region at most once, so clearing it after the last Platoon is deleted sticks. A settings replay keeps an automatic reset region automatic, never restores another publisher's region onto a Platoon, and the picker offers only that publisher's servers. A settings migration that cannot be written no longer crashes every cold start. Findings: input-settings-prefs-3, input-settings-prefs-4, input-settings-prefs-m2, input-settings-prefs-6
A field is prefilled only with an exact value or an unsaved draft, and the captured notation (≥90, ?) becomes its hint, so typing the shown number confirms it instead of being dropped as unchanged. Fixes q-uiux-2.
…s visible Login, patrol, score and attempt warnings are now underlined and announced as below cutline, not only colored. The Gunsmoke score and attempts line may wrap to a second line at large font sizes instead of being clipped, the UID line ellipsizes, and the evidence sheet speaks values the way the cell does. Fixes ui-a11y-fontscale-1, ui-a11y-fontscale-3, ui-a11y-fontscale-9.
The deletion now shows a failure message and reloads the list when the repository returns false or throws. Fixes q-uiux-13.
…orage A drag that ends where it started no longer turns the weekly ranking into a saved join-date order, the screen says when the tables are still ranked, and the reset wording no longer promises join-date order. Saving keeps the stored places of members who are not active. Reset reports a failed clear, and a failed commit of the member order or the cutlines puts the previous values back in memory so later reads match what was saved. Fixes input-settings-prefs-1, input-settings-prefs-2, input-settings-prefs-5, input-settings-prefs-7.
Each exported row grows to its longest cell, up to six lines, and a cell that still does not fit ends with an ellipsis. The Korean evidence summary drops the line break that Canvas.drawText cannot draw. Fixes ui-a11y-fontscale-10, ui-status-render-5, ui-status-render-4.
Information rows such as Version are no longer exposed as buttons, a renamed navigation or clear button updates its tooltip, re-applied top-bar actions keep their buttons so screen-reader focus survives Select all, a changed top-bar title and every loading, empty and failure state are announced, roster details wrap instead of hiding last login, and boundary date and time fields stack at large font sizes instead of clipping digits. Findings: q-uiux-12, ui-a11y-fontscale-2, ui-a11y-fontscale-5, ui-a11y-fontscale-6, ui-a11y-fontscale-7, ui-a11y-fontscale-8
Every delta measured from a baseline just before 05:00 now goes through the prefix/tail split, narrowed by login times and Daily Patrol events at both captures, and a capture after Sunday with an earlier login makes the Standard Sunday 0 like every other day. Findings: q-weekly-engine-1, q-weekly-engine-m1
Membership date and time pickers, the Platoon member list and member details show a server-time caption whenever the game reset zone's offset differs from the device's, so a boundary is not entered hours off. Findings: q-time-boundaries-4
An uncapped capture shortly before the Gunsmoke Sunday's 05:00 reset can miss Saturday's last login or Daily Patrol. The anchor is now closed only at the reset itself, with the capped preceding-week counter, or after Saturday's first Daily Patrol. Finding: q-weekly-engine-2
Flow closes now bypass the chunk budget, so a closed flow always releases its parser, metadata and pre-identity payloads. A flow whose open was refused is tainted instead of later failing client verification. Before identity, only roster, activity and updates payloads can reject a flow; other payloads are held for enabled history under their own budget or discarded, so a flow of no Platoon no longer warns about an overflow. Payloads keep the time they arrived through admission and replay, so a roster confirmed after the reset is still dated before it. Findings: data-capture-handoffs-2, data-capture-handoffs-3, data-capture-handoffs-4, data-capture-handoffs-m3, q-data-3
A scope whose interrupted import or undo could not be rolled back would later be restored over whatever capture ingested meanwhile. Capture start now fails with the history import notice instead, and retries recovery on the next start. Findings: data-lifecycle-races-m1, data-sqlite-corruption-poison-3
Findings: ui-status-render-9
Traffic counters no longer replace a warning or error and appear only while running. During teardown, drained work cannot replace the stop reason unless it is more severe, and a second stop without a reason keeps the first one. A revoked VPN now says so, and standby records it as missing VPN consent. A partial one-time capture names its missing items with the checklist labels, and one completed at the grace deadline ends as complete. The checklist shows only while capturing or beside its outcome; its rows are built once and updated in place, and each new warning or error is announced once. Findings: ui-status-render-1, ui-status-render-2, ui-status-render-3, ui-status-render-m1, ui-status-render-6, ui-status-render-7, ui-status-render-8, ui-a11y-fontscale-4
Findings: q-uiux-8
A document the picker created is deleted when its export fails, is refused, or can no longer be written; a refused provider says which locations work. Toasts, the restore refresh and PNG cache cleanup now run once for every finished task even if the screen was recreated meanwhile. A refused VPN consent on Home explains why capture did not start. Findings: ui-process-death-results-1, ui-process-death-results-2, ui-process-death-results-3
Decoding charges each submessage and repeated scalar to a per-payload budget, and the parser applies the same budget to a merged continuation sequence, discarding and quarantining it like the byte limit. Pending continuations are concatenated once on emission instead of on every frame. Pre-identity and admission buffers also weigh payloads by their decoded elements, and payloads whose history is off are no longer held before identification. Findings: sec-capture-1, sec-capture-m2, sec-protocol-1
A name, announcement or declaration longer than its limit no longer ends in an unpaired high surrogate when the cut lands inside a pair. Findings: sec-protocol-m2
Manual merit is capped at a Standard day's 90 or a generous Gunsmoke bound and score at one billion, so no weekly sum can overflow. A Login or Patrol 'no' that a fact or positive score disproves is refused in the editor, and a stored one no longer constrains the Gunsmoke solver. Findings: q-weekly-engine-3, q-weekly-engine-4
The formatter writes into a bounded buffer and gives up as soon as the text would pass the entry limit, so a crafted payload can no longer allocate its whole oversized text before the 2 MiB check rejects it. Findings: sec-capture-m1
AtomicFiles and the roster CSV writer now sync the temporary file's data before the rename, as the import store already does, so a power loss cannot leave a zero-length or truncated file under its final name. Findings: data-sqlite-corruption-poison-m2
Each entry ID now carries a sequence one above the highest already in the directory, and rotation deletes the lowest sequences first, never the entry just saved. Entries from earlier versions, whose counter was process-local, count as recorded first. A clock moved backwards therefore no longer deletes each new capture as soon as it is written. Findings: data-doc-contracts-8
The CSV tokenizer no longer normalizes line endings across the whole document: an unquoted CR, LF or CRLF ends a record, while a carriage return inside a quoted name is kept, so retained rosters read back the same name live capture stored. The history envelope is split without touching the body. The packet table's row and cell limits are derived from the roster limits, so a valid 227 to 256 member roster renders and uploads again. Findings: sec-protocol-m1, sec-protocol-m3
…activity-dated twin
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
2.7.2 is a security and integrity release built from a full source audit of 2.7.1 (security-audit skill: 22 coverage units, 37 validated findings, adversarial critic rounds), plus whole-code reviews for UI/UX, database gaps and duplicates, and input normalization. A consistency and refactor pass followed, then a three-lens adversarial review of the complete 2.7.1→2.7.2 diff. That review confirmed 15 more findings, and all of them are fixed here.
See
CHANGELOG.mdfor the full user-facing list. Highlights:Security
.gf2backupis rebuilt into the app's own DDL with row-content validation. Live databases that still carry DDL from a restore made before 2.7.2 are rebuilt on first access.app/src/test/cpp/run-zdtun-host-test.sh).Data integrity
UI/UX and input
Refactor
One helper each for the game ID range, SQLite identifier quoting and the app-table filter, roster file naming, export failure messages, the screen-lock check and the latest-roster read. The legacy Platoon now has the same commit-or-revert preference writes as a scoped Platoon.
Behaviour changes to note
Known, deliberately not changed
sec-native-forward-path-m1) needs real gap measurements before it is changed.sec-components-2,sec-components-m1) depends on whether the game keeps the screen on. The standby text was clarified instead.Test plan
./gradlew :protocol:test :app:testDebugUnitTest :app:lintDebug: protocol 67 tests and app unit tests green, 0 lint errors:app:connectedDebugAndroidTeston emulator (Android 14 AVD): 171/171app/src/test/cpp/run-zdtun-host-test.sh: passed