bugfix: Q seed entry restrict allowed keys after final word inserted

This commit is contained in:
scgbckbone 2024-04-30 22:11:21 +02:00 committed by doc-hex
parent c028c5ba7b
commit 77f576c50c
3 changed files with 32 additions and 8 deletions

View File

@ -60,6 +60,7 @@ This lists the changes in the most recent firmware, for each hardware platform.
- Bugfix: Battery idle timeout also considers last progress bar update
- Bugfix: Allow `Send Password` (keystrokes) of capital letters of alphabet
- Bugfix: Pressing SYM+SHIFT was toggling CAPS continuously. Now toggles once only.
- Bugfix: Restrict keys that can be pressed during seed entry after final word inserted
# Release History

View File

@ -604,7 +604,7 @@ async def seed_word_entry(prompt, num_words, has_checksum=True, done_cb=None):
assert num_words and prompt and done_cb
words = ['' for i in range(num_words)]
words = ['' for _ in range(num_words)]
dis.clear()
dis.text(None, 0, prompt, invert=1)
@ -645,11 +645,12 @@ async def seed_word_entry(prompt, num_words, has_checksum=True, done_cb=None):
ch = await press.wait()
commit = False
final = (word_num == num_words)
if ch == KEY_ENTER:
if word_num == num_words:
if final:
break
commit = True
elif ch == KEY_DELETE or ch == KEY_LEFT:
elif (ch == KEY_DELETE) or (ch == KEY_LEFT):
# delete last char
if len(value) > 0:
value = value[:-1]
@ -668,8 +669,10 @@ async def seed_word_entry(prompt, num_words, has_checksum=True, done_cb=None):
dis.restore_state(tmp)
continue
return None
elif ch in { ' ', KEY_TAB, KEY_DOWN, KEY_RIGHT }:
elif final:
# below options not allowed if all words already provided
continue
elif ch in {' ', KEY_TAB, KEY_DOWN, KEY_RIGHT}:
# re-consider if word done, like "act" and other 3-letter cases
commit = True
elif ch.isalpha():
@ -677,7 +680,7 @@ async def seed_word_entry(prompt, num_words, has_checksum=True, done_cb=None):
else:
continue
if has_checksum and word_num == num_words-1 and (len(value) >= 1 or commit):
if has_checksum and (word_num == num_words-1) and ((len(value) >= 1) or commit):
assert last_words
if value not in last_words:
maybe = [i for i in last_words if i.startswith(value)]
@ -696,6 +699,7 @@ async def seed_word_entry(prompt, num_words, has_checksum=True, done_cb=None):
nextchars = ''.join(sorted(set(i[len(value)] for i in maybe)))
err_msg = 'Next key: ' + nextchars
continue
if value in last_words:
dis.text(x, y, '%-8s' % value)
words[word_num] = value

View File

@ -66,7 +66,7 @@ def test_home_menu(cap_menu, cap_story, cap_screen, need_keypress, reset_seed_wo
@pytest.fixture
def word_menu_entry(cap_menu, pick_menu_item, is_q1, do_keypresses, cap_screen):
def doit(words, has_checksum=True):
def doit(words, has_checksum=True, q_accept=True):
if is_q1:
# easier for us on Q, but have to anticipate the autocomplete
for n, w in enumerate(words, start=1):
@ -106,7 +106,9 @@ def word_menu_entry(cap_menu, pick_menu_item, is_q1, do_keypresses, cap_screen):
assert 'Valid words' in cap_scr
else:
assert 'Press ENTER if all done' in cap_scr
do_keypresses('\r')
if q_accept:
do_keypresses('\r')
return
# do the massive drilling-down to pick a specific pass phrase
@ -804,6 +806,23 @@ def test_bip39_pw_signing_xfp_ux(pick_menu_item, press_select, cap_story, enter_
reset_seed_words() # for subsequent tests
def test_q1_seed_word_entry_bug(word_menu_entry, unit_test, pick_menu_item,
is_q1, do_keypresses, press_select, expect_ftux):
# internal/issues/750
if not is_q1:
raise pytest.skip("Q only")
unit_test('devtest/clear_seed.py')
pick_menu_item('Import Existing')
pick_menu_item('24 Words')
sw = ["abandon"] * 23
sw += ["art"]
word_menu_entry(sw, q_accept=False)
do_keypresses("art")
# now we we are yikes if bug not fixed
press_select()
expect_ftux()
@pytest.mark.onetime
def test_dump_menutree(sim_execfile):
# saves to ../unix/work/menudump.txt