mirror of
https://github.com/saphid/frame-control.git
synced 2026-10-06 05:02:50 +02:00
Refuse APK entries Android can't read; ignore stale title lists
- Only stored and deflated entries are read: Python 3.9's bzip2 and lzma readers inflate without bound before trimming. - loadTitles drops a response that a newer request has overtaken, so the install dialog's replace warning uses the fresh list. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
dfacf43e55
commit
fd0a284942
3 files changed
+20
-4
No files matched your search
@@ -165,6 +165,14 @@ class ApkInfo(unittest.TestCase):
|
|||||||
frame_apk.MAX_MANIFEST = limit
|
frame_apk.MAX_MANIFEST = limit
|
||||||
self.assertLess(peak, 8 * 1024**2)
|
self.assertLess(peak, 8 * 1024**2)
|
||||||
|
|
||||||
|
def test_refuses_compression_android_cant_read(self):
|
||||||
|
for method in (zipfile.ZIP_BZIP2, zipfile.ZIP_LZMA):
|
||||||
|
buf = io.BytesIO()
|
||||||
|
with zipfile.ZipFile(buf, 'w', method) as z:
|
||||||
|
z.writestr('AndroidManifest.xml', manifest('com.example.odd', 0x7f010000, 0x7f010001, 21))
|
||||||
|
with self.assertRaisesRegex(frame_apk.ApkError, 'compression'):
|
||||||
|
self.read(buf.getvalue())
|
||||||
|
|
||||||
def test_reference_cycles_and_fan_out_are_bounded(self):
|
def test_reference_cycles_and_fan_out_are_bounded(self):
|
||||||
res = frame_apk.Resources(b'')
|
res = frame_apk.Resources(b'')
|
||||||
ref = frame_apk.T_REF
|
ref = frame_apk.T_REF
|
||||||
|
|||||||
+6
-1
@@ -189,7 +189,12 @@ def _icons(attr, res):
|
|||||||
def _read(z, name, limit):
|
def _read(z, name, limit):
|
||||||
"""A member's bytes, inflating at most limit + 1 of them whatever its header claims
|
"""A member's bytes, inflating at most limit + 1 of them whatever its header claims
|
||||||
(ZipFile.read inflates everything first, then trims to the declared size)."""
|
(ZipFile.read inflates everything first, then trims to the declared size)."""
|
||||||
size = z.getinfo(name).file_size
|
info = z.getinfo(name)
|
||||||
|
# Android only reads stored and deflated entries, and only those bound what
|
||||||
|
# a read inflates (Python 3.9's bzip2 and lzma readers don't).
|
||||||
|
if info.compress_type not in (zipfile.ZIP_STORED, zipfile.ZIP_DEFLATED):
|
||||||
|
raise ApkError(f'{name} in the APK uses a compression Android does not')
|
||||||
|
size = info.file_size
|
||||||
if size > limit:
|
if size > limit:
|
||||||
raise ApkError(f'{name} in the APK is {size / 1024**2:.0f} MB, more than a real one ({limit // 1024**2} MB)')
|
raise ApkError(f'{name} in the APK is {size / 1024**2:.0f} MB, more than a real one ({limit // 1024**2} MB)')
|
||||||
with z.open(name) as f:
|
with z.open(name) as f:
|
||||||
|
|||||||
+6
-3
@@ -1277,10 +1277,13 @@ async function installTitle(token, choice) {
|
|||||||
} finally { $("prog").style.display = "none"; loadTitles(); }
|
} finally { $("prog").style.display = "none"; loadTitles(); }
|
||||||
}
|
}
|
||||||
let installedTitles = null; // lower-case ids, so the install dialog can warn before replacing one; null: unknown
|
let installedTitles = null; // lower-case ids, so the install dialog can warn before replacing one; null: unknown
|
||||||
|
let titlesSeq = 0; // a slower, older request mustn't overwrite a newer answer
|
||||||
async function loadTitles() {
|
async function loadTitles() {
|
||||||
let list;
|
const seq = ++titlesSeq;
|
||||||
try { list = (await api("/api/titles")).titles; }
|
let list, err;
|
||||||
catch (e) { installedTitles = null; $("titleList").innerHTML = `<div class="sub">${esc(e.message)}</div>`; return; }
|
try { list = (await api("/api/titles")).titles; } catch (e) { err = e; }
|
||||||
|
if (seq !== titlesSeq) return;
|
||||||
|
if (err) { installedTitles = null; $("titleList").innerHTML = `<div class="sub">${esc(err.message)}</div>`; return; }
|
||||||
installedTitles = new Set(list.map(t => String(t.id).toLowerCase()));
|
installedTitles = new Set(list.map(t => String(t.id).toLowerCase()));
|
||||||
$("titleCount").textContent = list.length ? `${list.length}` : "";
|
$("titleCount").textContent = list.length ? `${list.length}` : "";
|
||||||
$("titleList").innerHTML = list.length ? list.map(t => `
|
$("titleList").innerHTML = list.length ? list.map(t => `
|
||||||
|
|||||||
Reference in new issue
Block a user