Fix database schema compatibility issues in multiple artifacts ( deviceHealthServices_Battery.py, FacebookMessenger.py, googleDuo.py, googleMessages.py, keepNotes.py , notificationHistory.py ) by 5025231128#639
Conversation
- deviceHealthServices_Battery.py: Fix undefined time_offset variable by using timezone from database row - FacebookMessenger.py: Add fallback for missing message_reactions.reaction_timestamp column - googleDuo.py: Add fallback for missing saved_status column - googleMessages.py: Add fallback for missing parts.file_size_bytes column - keepNotes.py: Add fallback for missing text_search_note_content_content table - notificationHistory.py: Add blackboxprotobuf fallback for protobuf parsing errors These fixes ensure backward compatibility across different Android app versions.
There was a problem hiding this comment.
Pull request overview
This pull request enhances backward compatibility across multiple Android artifact parsers by adding fallback mechanisms for database schema variations found in different Android app versions.
Key Changes:
- Added blackboxprotobuf-based fallback parser for notification history when protobuf schema parsing fails
- Implemented cascading SQL query fallbacks for missing database columns/tables across 5 artifact parsers
- Fixed timezone parameter bug in deviceHealthServices_Battery.py to use database row values instead of undefined variable
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| notificationHistory.py | Added blackboxprotobuf import and new parse_notification_with_blackbox() fallback function; restructured parsing logic to try schema parser first, then blackbox parser |
| keepNotes.py | Added three-level fallback for missing text_search_note_content_content table, gracefully degrading to tree_entity table with filtering, then without |
| googleMessages.py | Added two-level fallback for missing file_size_bytes and local_cache_path columns in parts table |
| googleDuo.py | Added fallback for missing saved_status column in messages table with proper flag handling |
| deviceHealthServices_Battery.py | Fixed bug where time_offset variable was undefined; now correctly uses row[4] (timezone) and row[5] (timezone) for Battery and Bluetooth parsers respectively |
| FacebookMessenger.py | Added nested fallbacks for missing message_reactions table and missing friendship_status/contact_relationship_status columns |
Comments suppressed due to low confidence (11)
scripts/artifacts/FacebookMessenger.py:259
- Except block directly handles BaseException.
except:
scripts/artifacts/FacebookMessenger.py:370
- Except block directly handles BaseException.
except:
scripts/artifacts/googleDuo.py:129
- Except block directly handles BaseException.
except:
scripts/artifacts/googleMessages.py:43
- Except block directly handles BaseException.
except:
scripts/artifacts/googleMessages.py:62
- Except block directly handles BaseException.
except:
scripts/artifacts/keepNotes.py:43
- Except block directly handles BaseException.
except:
scripts/artifacts/keepNotes.py:57
- Except block directly handles BaseException.
except:
scripts/artifacts/notificationHistory.py:134
- Except block directly handles BaseException.
except:
scripts/artifacts/notificationHistory.py:141
- Except block directly handles BaseException.
except:
scripts/artifacts/notificationHistory.py:134
- 'except' clause does nothing but pass and there is no explanatory comment.
except:
scripts/artifacts/notificationHistory.py:141
- 'except' clause does nothing but pass and there is no explanatory comment.
except:
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| FROM tree_entity | ||
| WHERE tree_entity.type = 0 | ||
| ''') | ||
| except: |
There was a problem hiding this comment.
Bare except clause without specifying exception type. Consider catching specific exceptions like sqlite3.OperationalError or at minimum Exception to avoid catching SystemExit and KeyboardInterrupt.
| from messages | ||
| ''') | ||
| has_saved_status = True | ||
| except: |
There was a problem hiding this comment.
Bare except clause without specifying exception type. Consider catching specific exceptions like sqlite3.OperationalError or at minimum Exception to avoid catching SystemExit and KeyboardInterrupt.
| except: | |
| except sqlite3.OperationalError: |
| contact_relationship_status | ||
| from thread_users | ||
| ''') | ||
| except: |
There was a problem hiding this comment.
Bare except clause without specifying exception type. Consider catching specific exceptions like sqlite3.OperationalError or at minimum Exception to avoid catching SystemExit and KeyboardInterrupt.
| except: | |
| except sqlite3.OperationalError: |
| except: | ||
| pass | ||
|
|
||
| # Convert file creation time | ||
| file_creation = None | ||
| try: | ||
| file_creation = convert_utc_human_to_timezone(convert_ts_int_to_utc(int(file_name)/1000.0),'UTC') | ||
| except: | ||
| pass | ||
|
|
||
| data_list.append(( | ||
| f'{posted_time}', title, text, package, user_id, uid, package_index, | ||
| channel_name, channel_name_index, channel_id, channel_id_index, | ||
| conversation_id, conversation_id_index, major_version, | ||
| image_type, image_bitmap_filename, image_resource_id, | ||
| image_resource_id_package, image_data_length, image_data_offset, | ||
| image_uri, file_name, f'{file_creation}' | ||
| )) | ||
| except Exception as e: | ||
| pass # Silently fail for blackbox parsing |
There was a problem hiding this comment.
Bare except clauses silently swallow all exceptions. The inner try-except at line 134 and the outer try-except at line 152 should specify exception types (e.g., except Exception as e:) to avoid catching SystemExit and KeyboardInterrupt. Additionally, the silent pass at line 153 makes debugging difficult - consider logging the error.
| order by messages.thread_key, datestamp; | ||
| ''') | ||
| except: | ||
| # Fallback for databases without reaction_timestamp column |
There was a problem hiding this comment.
The comment "Fallback for databases without reaction_timestamp column" is misleading. This fallback actually handles databases that are missing the entire message_reactions table (note the LEFT JOIN is removed). If only the reaction_timestamp column is missing but the message_reactions table exists, this query would still fail when trying to access message_reactions.reaction on line 251-252 in the previous try block. Consider clarifying the comment to: "Fallback for databases without message_reactions table".
| # Fallback for databases without reaction_timestamp column | |
| # Fallback for databases without message_reactions table |
| "version": "0.0.2", | ||
| "date": "2024-07-02", | ||
| "requirements": "", | ||
| "requirements": "blackboxprotobuf", |
There was a problem hiding this comment.
The requirements field now lists "blackboxprotobuf" as a requirement, but the import at lines 25-29 treats it as optional (catching ImportError and setting HAS_BLACKBOXPROTOBUF flag). This creates ambiguity about whether blackboxprotobuf is a required or optional dependency. Consider either:
- Marking it as an optional requirement in the metadata (e.g., "requirements": "blackboxprotobuf (optional)")
- Making it truly required by not catching the ImportError
Given that it's used as a fallback parser, treating it as optional seems more appropriate.
| "requirements": "blackboxprotobuf", | |
| "requirements": "blackboxprotobuf (optional)", |
| FROM text_search_note_content_content | ||
| INNER JOIN tree_entity ON text_search_note_content_content.docid = tree_entity._id | ||
| ''') | ||
| except: |
There was a problem hiding this comment.
Bare except clauses are being used without specifying exception types. This is a best practice violation as it catches all exceptions including SystemExit and KeyboardInterrupt, which can hide bugs and make debugging difficult. Consider catching specific exceptions like sqlite3.OperationalError or at minimum Exception.
| JOIN conversations ON conversations._id=parts.conversation_id | ||
| ORDER BY "Timestamp (UTC)" ASC | ||
| ''') | ||
| except: |
There was a problem hiding this comment.
Bare except clause without specifying exception type. Consider catching specific exceptions like sqlite3.OperationalError or at minimum Exception to avoid catching SystemExit and KeyboardInterrupt.
| JOIN conversations ON conversations._id=parts.conversation_id | ||
| ORDER BY "Timestamp (UTC)" ASC | ||
| ''') | ||
| except: |
There was a problem hiding this comment.
Bare except clause without specifying exception type. Consider catching specific exceptions like sqlite3.OperationalError or at minimum Exception to avoid catching SystemExit and KeyboardInterrupt.
| except: | |
| except sqlite3.OperationalError: |
| where messages.thread_key=threads.thread_key and generic_admin_message_extensible_data IS NULL and msg_type != -1 | ||
| order by messages.thread_key, datestamp; | ||
| ''') | ||
| except: |
There was a problem hiding this comment.
Bare except clause without specifying exception type. Consider catching specific exceptions like sqlite3.OperationalError or at minimum Exception to avoid catching SystemExit and KeyboardInterrupt.
These fixes ensure backward compatibility across different Android app versions.