Skip to content

fix: resolve runtime errors in 7 artifact parsers#709

Open
FrancoMorales1 wants to merge 2 commits into
abrignoni:mainfrom
FrancoMorales1:fix/multi-artifact-fixes
Open

fix: resolve runtime errors in 7 artifact parsers#709
FrancoMorales1 wants to merge 2 commits into
abrignoni:mainfrom
FrancoMorales1:fix/multi-artifact-fixes

Conversation

@FrancoMorales1
Copy link
Copy Markdown
Contributor

Summary

This PR fixes runtime errors that caused 7 artifact parsers to crash when processing an Android 13 image. Each fix is confined to changes within the affected artifact file. All fixes were verified by running the full ALEAPP pipeline against a real Android 13 extraction before and after the patch.

Changes per artifact

scripts/artifacts/wifiConfigstore2.py

Error: UnboundLocalError: cannot access local variable 'configcombined' + KeyError: 'name'

The *combined variables were assigned inside if datafieldname == '...' blocks but read after the inner loop, so any network entry missing a field (e.g. no ConfigKey) left the variable unbound. A second issue caused a KeyError when iterating child elements of WifiConfiguration that lack a name attribute (e.g. ).

Fix: Initialize all *combined variables to '' before the for b in a: loop so every network entry has defaults regardless of which fields are present. Switch c.attrib['name'] to c.attrib.get('name') and continue when the attribute is absent.

scripts/artifacts/deviceHealthServices_Battery.py

Error (Turbo_Battery): NameError: name 'time_offset' is not defined
Error (Turbo_Bluetooth): NameError: name 'file_found' is not defined

Turbo_Battery referenced an undefined time_offset variable instead of using the timezone column already present in the query result. Turbo_Bluetooth was missing the for file_found in files_found: iteration loop entirely, and had the same time_offset issue using the time_zone column.

Fix: Replace time_offset with row[4] (Turbo_Battery) and row[5] (Turbo_Bluetooth). Add the missing iteration loop in Turbo_Bluetooth and use os.path.basename for the source path to match the pattern used in the sibling function.

scripts/artifacts/FCMQueuedMessagesSkype.py

Error: json.decoder.JSONDecodeError: Unterminated string starting at: line 1 column 1654

json.loads(rec.key_values["rawPayload"]) raised an unhandled exception for records with truncated or corrupted JSON payloads, aborting processing of all subsequent messages.

Fix: Wrap the json.loads call in a try/except json.JSONDecodeError block and continue to skip malformed records while processing the rest.

scripts/artifacts/airGuard.py

Error: ValueError: time data '2022-08-18 17:26' does not match format '%Y-%m-%d %H:%M:%S'

The scan table stores timestamps without seconds (HH:MM), but convert_ts_human_to_utc strictly expects HH:MM:SS.

Fix: Before calling convert_ts_human_to_utc, check if the timestamp has only two colon-separated parts and append :00 if so.

scripts/artifacts/keepNotes.py

Error: sqlite3.OperationalError: no such table: text_search_note_content_content

The query joins against text_search_note_content_content, a full-text-search virtual table that is absent in some versions of the Google Keep database schema.

Fix: Wrap the cursor.execute call in a try/except sqlite3.OperationalError block that logs a descriptive message and continues to the next file instead of raising an unhandled exception.

scripts/artifacts/googleInitiatedNav.py

Error: TypeError: list indices must be integers or slices, not str

When the protobuf contains multiple navigation entries, blackboxprotobuf decodes values['1'] as a list; when there is only one entry it returns a dict. The original code used isinstance(values, dict) (always True) instead of checking the inner value, so the single-entry path was always taken and failed on the list case.

Fix: Retrieve values.get('1', []), wrap a bare dict in a list, and iterate uniformly over the resulting list.

scripts/artifacts/googleVoice.py

Error: AttributeError: 'dict' object has no attribute 'decode'

Field '10' of the decoded message protobuf holds the message text as bytes in older layouts, but as a nested dict in newer ones. The code unconditionally called .decode('utf-8').

Fix: Check isinstance(raw, bytes) first; if it is a dict instead, extract the first bytes value found within it (falling back to str(raw) if none is present).

Notes

This is one of my first open source contributions — I would really appreciate any feedback or corrections if something is not right. I received assistance from Claude Sonnet 4.6 (Anthropic) in diagnosing the root causes, writing the fixes, and verifying them against a real Android 13 extraction.

FrancoMorales1 and others added 2 commits May 29, 2026 21:54
- wifiConfigstore2: initialize combined-field variables before the inner
  loop so missing XML fields no longer raise UnboundLocalError; use
  attrib.get('name') to skip sub-elements without a name attribute
  (e.g. SecurityParamsList) that previously caused KeyError
- deviceHealthServices_Battery: replace undefined time_offset with the
  timezone value from the query row in Turbo_Battery; add the missing
  for-loop over files_found and fix the same time_offset reference in
  Turbo_Bluetooth
- FCMQueuedMessagesSkype: wrap json.loads in try/except JSONDecodeError
  so truncated rawPayload values are skipped instead of crashing
- airGuard: pad HH:MM timestamps to HH:MM:SS before passing to
  convert_ts_human_to_utc, which expects seconds
- keepNotes: catch sqlite3.OperationalError around the FTS table query
  so devices without text_search_note_content_content produce a graceful
  log message instead of an unhandled exception
- googleInitiatedNav: normalise values['1'] to a list before iterating
  so both single-entry (dict) and multi-entry (list) protobuf results
  are handled correctly
- googleVoice: check whether field '10' is bytes or dict before calling
  .decode(), accommodating newer protobuf message layouts

Pylint (--disable=C,R): all E-level errors in the changed files were
introduced by the original code and are resolved by this patch; the
score for the affected files improved from 7.84 to 9.06.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Remove unused imports, simplify intermediate variables, rename unused
function arguments to the _ convention, and fix f-strings that lacked
interpolation. These were pre-existing issues surfaced by the lint CI
running on every file touched by a PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant