mirror of
https://github.com/mvt-project/mvt.git
synced 2026-10-12 02:37:12 +02:00
Merge pull request #970 from WingManOO7/fix/settings-leap-day
Keep settings history timestamps on 29 February
This commit is contained in:
2 files changed
+57
-8
No files matched your search
@@ -255,19 +255,25 @@ class Settings(AndroidArtifact):
|
|||||||
dumpsys prints the change history without a year, so it is resolved
|
dumpsys prints the change history without a year, so it is resolved
|
||||||
against the time the section was dumped: the most recent matching date
|
against the time the section was dumped: the most recent matching date
|
||||||
at or before that time.
|
at or before that time.
|
||||||
|
|
||||||
|
The year is parsed together with the value, because strptime() would
|
||||||
|
otherwise parse it in 1900, which has no 29 February. The most recent
|
||||||
|
matching leap day can be eight years earlier when a century year is
|
||||||
|
not a leap year and the current year's leap day is still in the future.
|
||||||
"""
|
"""
|
||||||
if section_end is None:
|
if section_end is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
for year in range(section_end.year, section_end.year - 9, -1):
|
||||||
partial = datetime.strptime(value, "%m-%d %H:%M:%S.%f")
|
try:
|
||||||
timestamp = partial.replace(year=section_end.year)
|
timestamp = datetime.strptime(f"{year}-{value}", "%Y-%m-%d %H:%M:%S.%f")
|
||||||
if timestamp > section_end:
|
except ValueError:
|
||||||
timestamp = partial.replace(year=section_end.year - 1)
|
continue
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
return convert_datetime_to_iso(timestamp)
|
if timestamp <= section_end:
|
||||||
|
return convert_datetime_to_iso(timestamp)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def _parse_history(
|
def _parse_history(
|
||||||
self, line: str, section_end: Optional[datetime]
|
self, line: str, section_end: Optional[datetime]
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
# Use of this software is governed by the MVT License 1.1 that can be found at
|
# Use of this software is governed by the MVT License 1.1 that can be found at
|
||||||
# https://license.mvt.re/1.1/
|
# https://license.mvt.re/1.1/
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from mvt.android.artifacts.settings import Settings
|
from mvt.android.artifacts.settings import Settings
|
||||||
|
|
||||||
from ..utils import get_artifact
|
from ..utils import get_artifact
|
||||||
@@ -21,6 +23,21 @@ def find(settings: Settings, name: str) -> list:
|
|||||||
return [result for result in settings.results if result["name"] == name]
|
return [result for result in settings.results if result["name"] == name]
|
||||||
|
|
||||||
|
|
||||||
|
def resolve_history_time(time: str, section_end: str) -> Optional[str]:
|
||||||
|
settings = Settings()
|
||||||
|
settings.parse(
|
||||||
|
"SECURE SETTINGS (user 0)\n"
|
||||||
|
"_id:240 name:accessibility_enabled pkg:android value:1\n"
|
||||||
|
"\tHistory (accessibility_enabled)\n"
|
||||||
|
f"\t\ttime:{time} mode:update oldValue:0 newValue:1 "
|
||||||
|
"package:com.example.helper\n"
|
||||||
|
"\n"
|
||||||
|
"--------- 0.019s was the duration of dumpsys settings, "
|
||||||
|
f"ending at: {section_end}\n"
|
||||||
|
)
|
||||||
|
return settings.results[0]["history"][0]["timestamp"]
|
||||||
|
|
||||||
|
|
||||||
class TestSettingsArtifact:
|
class TestSettingsArtifact:
|
||||||
def test_parsing(self):
|
def test_parsing(self):
|
||||||
settings = parse_bugreport_settings()
|
settings = parse_bugreport_settings()
|
||||||
@@ -159,6 +176,32 @@ class TestSettingsArtifact:
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def test_leap_day_history_keeps_its_timestamp(self):
|
||||||
|
assert (
|
||||||
|
resolve_history_time("02-29 22:41:07.980", "2024-03-05 23:14:28")
|
||||||
|
== "2024-02-29 22:41:07.980000"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_leap_day_history_resolved_to_the_last_leap_year(self):
|
||||||
|
# The most recent 29 February at or before the dump can be several
|
||||||
|
# years back when the dump was taken in a year without one.
|
||||||
|
assert (
|
||||||
|
resolve_history_time("02-29 22:41:07.980", "2025-03-01 10:00:00")
|
||||||
|
== "2024-02-29 22:41:07.980000"
|
||||||
|
)
|
||||||
|
assert (
|
||||||
|
resolve_history_time("02-29 22:41:07.980", "2024-01-10 10:00:00")
|
||||||
|
== "2020-02-29 22:41:07.980000"
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_leap_day_history_before_a_leap_day_after_a_skipped_century(self):
|
||||||
|
# 2100 is not a leap year, so before 29 February 2104 the most
|
||||||
|
# recent matching date is eight years earlier, in 2096.
|
||||||
|
assert (
|
||||||
|
resolve_history_time("02-29 22:41:07.980", "2104-01-10 10:00:00")
|
||||||
|
== "2096-02-29 22:41:07.980000"
|
||||||
|
)
|
||||||
|
|
||||||
def test_dangerous_setting_is_detected_with_the_changing_package(self):
|
def test_dangerous_setting_is_detected_with_the_changing_package(self):
|
||||||
settings = parse_bugreport_settings()
|
settings = parse_bugreport_settings()
|
||||||
settings.check_indicators()
|
settings.check_indicators()
|
||||||
|
|||||||
Reference in new issue
Block a user