Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions shell/plugins/lock/Service.qml
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,12 @@ Item {

function lock(): string {
if (!root.passwordPamConfigured) return "missing-pam"
if (root.lockRequested && !sessionLock.locked && !sessionLock.secure) {
root.lockRequested = false
root.pendingSessionLock = false
sessionLockStabilizeTimer.stop()
pendingSessionLockTimer.stop()
}
if (!root.locked && !root.beginLock()) return "failed"
return "ok"
}
Expand Down
39 changes: 39 additions & 0 deletions test/shell.d/lock-requested-latch-test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#!/bin/bash

set -euo pipefail

source "$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/base-test.sh"

run_node_test <<'JS'
const fs = require('fs')
const serviceQml = fs.readFileSync(path.join(root, 'shell/plugins/lock/Service.qml'), 'utf8')

// When lock() is called and lockRequested is latched but the session is not
// actually locked or secure, clear the latch so the request can retry.
// Fixes #10299: a stalled lock must not prevent later lock attempts.
assert(
/function lock\(\): string \{[\s\S]*if \(root\.lockRequested && !sessionLock\.locked && !sessionLock\.secure\) \{[\s\S]*root\.lockRequested = false/.test(serviceQml),
'lock() clears a stalled lockRequested latch before retrying'
)

assert(
/if \(root\.lockRequested && !sessionLock\.locked && !sessionLock\.secure\) \{[\s\S]*root\.pendingSessionLock = false/.test(serviceQml),
'lock() clears pendingSessionLock when resetting a stalled request'
)

assert(
/if \(root\.lockRequested && !sessionLock\.locked && !sessionLock\.secure\) \{[\s\S]*sessionLockStabilizeTimer\.stop\(\)/.test(serviceQml),
'lock() stops the stabilize timer when resetting a stalled request'
)

assert(
/if \(root\.lockRequested && !sessionLock\.locked && !sessionLock\.secure\) \{[\s\S]*pendingSessionLockTimer\.stop\(\)/.test(serviceQml),
'lock() stops the pending timer when resetting a stalled request'
)

// The latch reset must happen before the locked check, so beginLock() gets called.
assert(
/function lock\(\): string \{[\s\S]*if \(root\.lockRequested && !sessionLock\.locked && !sessionLock\.secure\) \{[\s\S]*\}\s*if \(!root\.locked && !root\.beginLock\(\)\)/.test(serviceQml),
'lock() resets the latch before checking root.locked'
)
JS