A fork of https://github.com/crosspoint-reader/crosspoint-reader
1"""
2PlatformIO pre-build script: patch JPEGDEC for MCU_SKIP wild pointer crash.
3
4Problem:
5 JPEGDecodeMCU_P computes pMCU = &sMCUs[iMCU & 0xffffff]. When iMCU is
6 MCU_SKIP (-8), the bitmask produces index 0xFFFFF8 (16 777 208), creating a
7 pointer ~33 MB past the 392-entry sMCUs array. If the progressive JPEG's
8 first scan includes AC coefficients (iScanEnd > 0), the AC decode loop writes
9 through this wild pointer and crashes with a store-access fault.
10
11 Upstream commit 8628297 guarded the DC coefficient write (pMCU[0]) but not the
12 AC coefficient writes at indices 1-63.
13
14Fix:
15 Redirect pMCU to sMCUs[0] when MCU_SKIP is active. Writes to sMCUs[1..63]
16 are harmless: for JPEG_SCALE_EIGHTH only sMCUs[0] is read for output, and
17 the DC write at sMCUs[0] is already guarded by the existing `if (iMCU >= 0)`
18 check.
19
20Applied idempotently — safe to run on every build.
21"""
22
23Import("env")
24import os
25
26
27def patch_jpegdec(env):
28 libdeps_dir = os.path.join(env["PROJECT_DIR"], ".pio", "libdeps")
29 if not os.path.isdir(libdeps_dir):
30 return
31 for env_dir in os.listdir(libdeps_dir):
32 jpeg_inl = os.path.join(libdeps_dir, env_dir, "JPEGDEC", "src", "jpeg.inl")
33 if os.path.isfile(jpeg_inl):
34 _apply_mcu_skip_pointer_fix(jpeg_inl)
35
36
37def _apply_mcu_skip_pointer_fix(filepath):
38 MARKER = "// CrossPoint patch: safe pMCU for MCU_SKIP"
39 with open(filepath, "r") as f:
40 content = f.read()
41
42 if MARKER in content:
43 return # already patched
44
45 # The wild-pointer line in JPEGDecodeMCU_P:
46 OLD = " signed short *pMCU = &pJPEG->sMCUs[iMCU & 0xffffff];"
47
48 NEW = (
49 " " + MARKER + "\n"
50 " signed short *pMCU = (iMCU < 0) ? pJPEG->sMCUs\n"
51 " : &pJPEG->sMCUs[iMCU & 0xffffff];"
52 )
53
54 if OLD not in content:
55 print(
56 "WARNING: JPEGDEC MCU_SKIP pointer patch target not found in %s "
57 "— library may have been updated" % filepath
58 )
59 return
60
61 content = content.replace(OLD, NEW, 1)
62 with open(filepath, "w") as f:
63 f.write(content)
64 print("Patched JPEGDEC: safe pMCU for MCU_SKIP in JPEGDecodeMCU_P: %s" % filepath)
65
66
67# Run immediately at script import time (before compilation).
68patch_jpegdec(env)