backups: an empty value in a .reg export must not fail the file

A line of the form "Name=" with nothing after the sign is not strictly legal,
but it occurs in real exports - the part marker's WJPRT.reg has KRelay1 like
this. The parser raised on it, which failed the whole file, which meant that
machine could never be backed up at all. Read it as an empty string so the
value name is still preserved.
This commit is contained in:
cproudlock
2026-08-10 14:24:41 -04:00
parent 2785c0463e
commit b8398a36eb
2 changed files with 54 additions and 0 deletions

View File

@@ -149,6 +149,13 @@ def _parsevalue(body):
return _parsehexvalue(body)
if body == '-':
return 'DELETE', None
if body == '':
# "Name=" with nothing after the sign. Not strictly legal, but it
# occurs in real exports (the part marker's WJPRT.reg has KRelay1 like
# this), and failing the whole file over it would mean that machine can
# never be backed up. Treat it as an empty string so the value NAME is
# still preserved.
return 'REG_SZ', ''
raise NtlarsParseError('unrecognised value form: {!r}'.format(body))

View File

@@ -710,3 +710,50 @@ def test_panel_label_is_rendered_in_the_site_zone(bk_app, bk_plugin):
revision = _db.session.get(BackupRevision, result['backuprevisionid'])
# 16:30 UTC on 2026-08-07 is 12:30 EDT.
assert '12:30' in _label(revision)
# =============================================================================
# REGEDIT4 / part marker exports
# =============================================================================
REGEDIT4REG = (
'REGEDIT4\r\n\r\n'
r'[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\General]' '\r\n'
'"MachineNo"="WJPRT"\r\n'
'"Cnc"="MARKER"\r\n\r\n'
r'[HKEY_LOCAL_MACHINE\SOFTWARE\GE Aircraft Engines\DNC\Mark]' '\r\n'
'"Port Id"="COM4"\r\n'
'"Baud"="9600"\r\n'
'"KRelay1"=\r\n'
)
def test_regedit4_header_is_accepted():
"""The part marker's per-machine file is REGEDIT4, not 'Windows Registry
Editor Version 5.00'."""
projection = ntlars.parse(REGEDIT4REG.encode('utf-8'))
assert registry.NtlarsKind.embeddedmachineno(projection) == 'WJPRT'
def test_value_with_an_empty_right_hand_side_does_not_fail_the_file():
"""A real export contains "KRelay1=" with nothing after the sign. Raising on
it would mean that machine could never be backed up at all."""
projection = ntlars.parse(REGEDIT4REG.encode('utf-8'))
mark = next(k for k in projection['keys'] if k['path'] == 'Mark')
assert mark['values']['KRelay1'] == {'type': 'REG_SZ', 'data': ''}
def test_part_marker_serial_port_survives_the_roundtrip():
"""The COM port the marker hangs off is the point of keeping this config."""
first = ntlars.parse(REGEDIT4REG.encode('utf-8'))
second = ntlars.parse(ntlars.render(first, dialect='wow6432node'))
mark = next(k for k in second['keys'] if k['path'] == 'Mark')
assert mark['values']['Port Id']['data'] == 'COM4'
def test_a_marker_export_shows_the_mark_tab():
card = dncinfo.build(ntlars.parse(REGEDIT4REG.encode('utf-8')), assetid=0)
labels = [s['label'] for s in card['sections']]
assert any('MARK' in label for label in labels)
mark = next(s for s in card['sections'] if 'MARK' in s['label'])
assert any(f['label'] == 'Port Id' and f['value'] == 'COM4' for f in mark['fields'])