Skip to content

Commit a6bceb7

Browse files
fix(save_segment): Adds segment len check the same as bootloader does
1 parent 7681ec0 commit a6bceb7

File tree

1 file changed

+21
-7
lines changed

1 file changed

+21
-7
lines changed

esptool/bin_image.py

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -270,13 +270,24 @@ def maybe_patch_segment_data(self, f, segment_data):
270270
)
271271
return segment_data
272272

273-
def save_segment(self, f, segment, checksum=None):
273+
def save_segment(self, f, segment, checksum=None, segment_name=None):
274274
"""
275275
Save the next segment to the image file,
276276
return next checksum value if provided
277277
"""
278278
segment_data = self.maybe_patch_segment_data(f, segment.data)
279-
f.write(struct.pack("<II", segment.addr, len(segment_data)))
279+
segment_len = len(segment_data)
280+
segment_name = segment_name if segment_name is not None else ""
281+
if segment_len & 3:
282+
raise FatalError(
283+
f"Invalid {segment_name} segment length {segment_len:#x}. It has to be multiple of 4."
284+
)
285+
SIXTEEN_MB = 0x1000000
286+
if segment_len >= SIXTEEN_MB:
287+
raise FatalError(
288+
f"Invalid {segment_name} segment length {segment_len:#x}. The 16 MB limit has been exceeded."
289+
)
290+
f.write(struct.pack("<II", segment.addr, segment_len))
280291
f.write(segment_data)
281292
if checksum is not None:
282293
return ESPLoader.checksum(segment_data, checksum)
@@ -293,7 +304,8 @@ def save_flash_segment(self, f, segment, checksum=None):
293304
segment_len_remainder = segment_end_pos % self.IROM_ALIGN
294305
if segment_len_remainder < 0x24:
295306
segment.data += b"\x00" * (0x24 - segment_len_remainder)
296-
return self.save_segment(f, segment, checksum)
307+
segment_name = getattr(segment, "name", None)
308+
return self.save_segment(f, segment, checksum, segment_name)
297309

298310
def read_checksum(self, f):
299311
"""Return ESPLoader checksum from end of just-read image"""
@@ -748,7 +760,7 @@ def get_alignment_data_needed(segment):
748760
# and checksum (ROM bootloader will only care for RAM segments and its
749761
# correct checksums)
750762
for segment in ram_segments:
751-
checksum = self.save_segment(f, segment, checksum)
763+
checksum = self.save_segment(f, segment, checksum, segment.name)
752764
total_segments += 1
753765
self.append_checksum(f, checksum)
754766

@@ -769,7 +781,7 @@ def get_alignment_data_needed(segment):
769781

770782
pad_len -= self.ROM_LOADER.BOOTLOADER_FLASH_OFFSET
771783
pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell())
772-
self.save_segment(f, pad_segment)
784+
self.save_segment(f, pad_segment, None, segment.name)
773785
total_segments += 1
774786
# check the alignment
775787
assert (f.tell() + 8 + self.ROM_LOADER.BOOTLOADER_FLASH_OFFSET) % (
@@ -793,7 +805,9 @@ def get_alignment_data_needed(segment):
793805
ram_segments.pop(0)
794806
else:
795807
pad_segment = ImageSegment(0, b"\x00" * pad_len, f.tell())
796-
checksum = self.save_segment(f, pad_segment, checksum)
808+
checksum = self.save_segment(
809+
f, pad_segment, checksum, segment.name
810+
)
797811
total_segments += 1
798812
else:
799813
# write the flash segment
@@ -806,7 +820,7 @@ def get_alignment_data_needed(segment):
806820

807821
# flash segments all written, so write any remaining RAM segments
808822
for segment in ram_segments:
809-
checksum = self.save_segment(f, segment, checksum)
823+
checksum = self.save_segment(f, segment, checksum, segment.name)
810824
total_segments += 1
811825

812826
if self.secure_pad:

0 commit comments

Comments
 (0)