Merge branch 'main' into fix/accessibility-installed-service-count

This commit is contained in:
besendorf authored and GitHub committed 2026-09-25 19:30:09 +02:00
commit 00a5f11124
2 files changed
+53

No files matched your search

+11
View File
@@ -6,6 +6,7 @@ import datetime
import fnmatch import fnmatch
import logging import logging
import os import os
import re
from pathlib import Path from pathlib import Path
from typing import List, Optional from typing import List, Optional
from zipfile import ZipFile from zipfile import ZipFile
@@ -13,6 +14,10 @@ from zoneinfo import ZoneInfo, ZoneInfoNotFoundError
from mvt.common.module import ModuleResults, MVTModule from mvt.common.module import ModuleResults, MVTModule
# `------ 0.101s was the duration of 'SOME SECTION' ------`, printed when that
# section finishes and not necessarily between two sections.
SECTION_DURATION = re.compile(r"^-{3,}\s*[0-9.]+s was the duration of", re.IGNORECASE)
class BugReportModule(MVTModule): class BugReportModule(MVTModule):
"""This class provides a base for all Android Bug Report modules.""" """This class provides a base for all Android Bug Report modules."""
@@ -122,6 +127,12 @@ class BugReportModule(MVTModule):
in_section = True in_section = True
continue continue
if stripped.startswith("------"): if stripped.startswith("------"):
# dumpstate prints a section's timing line when that section
# finishes, which can land in the middle of the one being
# written. Treating it as a boundary truncates the section at
# an arbitrary point, silently.
if SECTION_DURATION.match(stripped):
continue
break break
lines.append(line) lines.append(line)
return "\n".join(lines) return "\n".join(lines)
@@ -0,0 +1,42 @@
# Mobile Verification Toolkit (MVT)
# Copyright (c) 2021-2026 The MVT Authors.
# Use of this software is governed by the MVT License 1.1 that can be found at
# https://license.mvt.re/1.1/
"""A section ends at the next section, not at a timing line printed inside it."""
from mvt.android.modules.bugreport.base import BugReportModule
# dumpstate prints a section's duration when that section finishes, which can
# land in the middle of the section currently being written.
DUMPSTATE = """\
------ SYSTEM PROPERTIES (getprop) ------
[nfc.initialized]: [true]
------ 0.101s was the duration of 'DROPBOX SYSTEM SERVER CRASHES' ------
[ro.build.version.sdk]: [30]
[ro.product.model]: [SM-A305F]
------ 0.064s was the duration of 'SYSTEM PROPERTIES' ------
------ STORAGE INFO (df) ------
/dev/root 2.9G
"""
class TestExtractCommandSection:
def test_a_foreign_timing_line_does_not_end_the_section(self):
section = BugReportModule.extract_command_section(
DUMPSTATE, "------ SYSTEM PROPERTIES"
)
assert "[ro.product.model]: [SM-A305F]" in section
assert section.count("\n") == 2
def test_the_next_section_is_still_the_boundary(self):
section = BugReportModule.extract_command_section(
DUMPSTATE, "------ SYSTEM PROPERTIES"
)
assert "STORAGE INFO" not in section
assert "/dev/root" not in section
def test_timing_lines_are_not_returned_as_content(self):
section = BugReportModule.extract_command_section(
DUMPSTATE, "------ SYSTEM PROPERTIES"
)
assert "was the duration of" not in section