Skip to content

Commit 2126546

Browse files
authored
CABI: fix reallocate alignment in string conversion (#734)
Resolves #733
1 parent 6c48079 commit 2126546

2 files changed

Lines changed: 10 additions & 50 deletions

File tree

‎design/mvp/CanonicalABI.md‎

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,6 +1070,8 @@ host:
10701070
self.inst.store.invoke(realloc, on_start, on_resolve)
10711071
self.inst.may_leave = True
10721072
assert(ptr is not None)
1073+
trap_if(ptr != align_to(ptr, alignment))
1074+
trap_if(ptr + new_byte_length > len(self.opts.memory))
10731075
return ptr
10741076

10751077
def allocate(self, alignment, byte_length):
@@ -2619,8 +2621,6 @@ def store_string_copy(cx, src, src_code_units, dst_code_unit_size, dst_alignment
26192621
dst_byte_length = dst_code_unit_size * src_code_units
26202622
assert(dst_byte_length <= REALLOC_I32_MAX)
26212623
ptr = cx.allocate(dst_alignment, dst_byte_length)
2622-
trap_if(ptr != align_to(ptr, dst_alignment))
2623-
trap_if(ptr + dst_byte_length > len(cx.opts.memory))
26242624
encoded = src.encode(dst_encoding)
26252625
assert(dst_byte_length == len(encoded))
26262626
cx.opts.memory[ptr : ptr+len(encoded)] = encoded
@@ -2642,19 +2642,16 @@ def store_latin1_to_utf8(cx, src, src_code_units):
26422642
def store_string_to_utf8(cx, src, src_code_units, worst_case_size):
26432643
assert(src_code_units <= REALLOC_I32_MAX)
26442644
ptr = cx.allocate(1, src_code_units)
2645-
trap_if(ptr + src_code_units > len(cx.opts.memory))
26462645
for i,code_point in enumerate(src):
26472646
if ord(code_point) < 2**7:
26482647
cx.opts.memory[ptr + i] = ord(code_point)
26492648
else:
26502649
assert(worst_case_size <= REALLOC_I32_MAX)
26512650
ptr = cx.reallocate(ptr, src_code_units, 1, worst_case_size)
2652-
trap_if(ptr + worst_case_size > len(cx.opts.memory))
26532651
encoded = src.encode('utf-8')
26542652
cx.opts.memory[ptr+i : ptr+len(encoded)] = encoded[i : ]
26552653
if worst_case_size > len(encoded):
26562654
ptr = cx.reallocate(ptr, worst_case_size, 1, len(encoded))
2657-
trap_if(ptr + len(encoded) > len(cx.opts.memory))
26582655
return (ptr, len(encoded))
26592656
return (ptr, src_code_units)
26602657
```
@@ -2668,14 +2665,10 @@ def store_utf8_to_utf16(cx, src, src_code_units):
26682665
worst_case_size = 2 * src_code_units
26692666
assert(worst_case_size <= REALLOC_I32_MAX)
26702667
ptr = cx.allocate(2, worst_case_size)
2671-
trap_if(ptr != align_to(ptr, 2))
2672-
trap_if(ptr + worst_case_size > len(cx.opts.memory))
26732668
encoded = src.encode('utf-16-le')
26742669
cx.opts.memory[ptr : ptr+len(encoded)] = encoded
26752670
if len(encoded) < worst_case_size:
26762671
ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded))
2677-
trap_if(ptr != align_to(ptr, 2))
2678-
trap_if(ptr + len(encoded) > len(cx.opts.memory))
26792672
code_units = int(len(encoded) / 2)
26802673
return (ptr, code_units)
26812674
```
@@ -2692,8 +2685,6 @@ bytes):
26922685
def store_string_to_latin1_or_utf16(cx, src, src_code_units):
26932686
assert(src_code_units <= REALLOC_I32_MAX)
26942687
ptr = cx.allocate(2, src_code_units)
2695-
trap_if(ptr != align_to(ptr, 2))
2696-
trap_if(ptr + src_code_units > len(cx.opts.memory))
26972688
dst_byte_length = 0
26982689
for usv in src:
26992690
if ord(usv) < (1 << 8):
@@ -2703,23 +2694,17 @@ def store_string_to_latin1_or_utf16(cx, src, src_code_units):
27032694
worst_case_size = 2 * src_code_units
27042695
assert(worst_case_size <= REALLOC_I32_MAX)
27052696
ptr = cx.reallocate(ptr, src_code_units, 2, worst_case_size)
2706-
trap_if(ptr != align_to(ptr, 2))
2707-
trap_if(ptr + worst_case_size > len(cx.opts.memory))
27082697
for j in range(dst_byte_length-1, -1, -1):
27092698
cx.opts.memory[ptr + 2*j] = cx.opts.memory[ptr + j]
27102699
cx.opts.memory[ptr + 2*j + 1] = 0
27112700
encoded = src.encode('utf-16-le')
27122701
cx.opts.memory[ptr+2*dst_byte_length : ptr+len(encoded)] = encoded[2*dst_byte_length : ]
27132702
if worst_case_size > len(encoded):
27142703
ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded))
2715-
trap_if(ptr != align_to(ptr, 2))
2716-
trap_if(ptr + len(encoded) > len(cx.opts.memory))
27172704
tagged_code_units = int(len(encoded) / 2) | utf16_tag(cx.opts.memory.ptr_type())
27182705
return (ptr, tagged_code_units)
27192706
if dst_byte_length < src_code_units:
27202707
ptr = cx.reallocate(ptr, src_code_units, 2, dst_byte_length)
2721-
trap_if(ptr != align_to(ptr, 2))
2722-
trap_if(ptr + dst_byte_length > len(cx.opts.memory))
27232708
return (ptr, dst_byte_length)
27242709
```
27252710

@@ -2738,8 +2723,6 @@ def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units):
27382723
src_byte_length = 2 * src_code_units
27392724
assert(src_byte_length <= REALLOC_I32_MAX)
27402725
ptr = cx.allocate(2, src_byte_length)
2741-
trap_if(ptr != align_to(ptr, 2))
2742-
trap_if(ptr + src_byte_length > len(cx.opts.memory))
27432726
encoded = src.encode('utf-16-le')
27442727
cx.opts.memory[ptr : ptr+len(encoded)] = encoded
27452728
if any(ord(c) >= (1 << 8) for c in src):
@@ -2748,8 +2731,7 @@ def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units):
27482731
latin1_size = int(len(encoded) / 2)
27492732
for i in range(latin1_size):
27502733
cx.opts.memory[ptr + i] = cx.opts.memory[ptr + 2*i]
2751-
ptr = cx.reallocate(ptr, src_byte_length, 1, latin1_size)
2752-
trap_if(ptr + latin1_size > len(cx.opts.memory))
2734+
ptr = cx.reallocate(ptr, src_byte_length, 2, latin1_size)
27532735
return (ptr, latin1_size)
27542736
```
27552737

@@ -2780,8 +2762,6 @@ def store_list_into_range(cx, v, elem_type):
27802762
byte_length = len(v) * elem_size(elem_type, cx.opts.memory.ptr_type())
27812763
assert(byte_length <= REALLOC_I32_MAX)
27822764
ptr = cx.allocate(alignment(elem_type, cx.opts.memory.ptr_type()), byte_length)
2783-
trap_if(ptr != align_to(ptr, alignment(elem_type, cx.opts.memory.ptr_type())))
2784-
trap_if(ptr + byte_length > len(cx.opts.memory))
27852765
store_list_into_valid_range(cx, v, ptr, elem_type)
27862766
return (ptr, len(v))
27872767

@@ -3317,9 +3297,9 @@ def lower_flat_values(cx, max_flat, vs, ts, out_param = None):
33173297
flat_vals = [ptr]
33183298
else:
33193299
ptr = out_param.next(cx.opts.memory.ptr_type())
3300+
trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type())))
3301+
trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory))
33203302
flat_vals = []
3321-
trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type())))
3322-
trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory))
33233303
store(cx, tuple_value, tuple_type, ptr)
33243304
else:
33253305
flat_vals = []

‎design/mvp/canonical-abi/definitions.py‎

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,8 @@ def on_resolve(result):
638638
self.inst.store.invoke(realloc, on_start, on_resolve)
639639
self.inst.may_leave = True
640640
assert(ptr is not None)
641+
trap_if(ptr != align_to(ptr, alignment))
642+
trap_if(ptr + new_byte_length > len(self.opts.memory))
641643
return ptr
642644

643645
def allocate(self, alignment, byte_length):
@@ -1574,8 +1576,6 @@ def store_string_copy(cx, src, src_code_units, dst_code_unit_size, dst_alignment
15741576
dst_byte_length = dst_code_unit_size * src_code_units
15751577
assert(dst_byte_length <= REALLOC_I32_MAX)
15761578
ptr = cx.allocate(dst_alignment, dst_byte_length)
1577-
trap_if(ptr != align_to(ptr, dst_alignment))
1578-
trap_if(ptr + dst_byte_length > len(cx.opts.memory))
15791579
encoded = src.encode(dst_encoding)
15801580
assert(dst_byte_length == len(encoded))
15811581
cx.opts.memory[ptr : ptr+len(encoded)] = encoded
@@ -1592,42 +1592,33 @@ def store_latin1_to_utf8(cx, src, src_code_units):
15921592
def store_string_to_utf8(cx, src, src_code_units, worst_case_size):
15931593
assert(src_code_units <= REALLOC_I32_MAX)
15941594
ptr = cx.allocate(1, src_code_units)
1595-
trap_if(ptr + src_code_units > len(cx.opts.memory))
15961595
for i,code_point in enumerate(src):
15971596
if ord(code_point) < 2**7:
15981597
cx.opts.memory[ptr + i] = ord(code_point)
15991598
else:
16001599
assert(worst_case_size <= REALLOC_I32_MAX)
16011600
ptr = cx.reallocate(ptr, src_code_units, 1, worst_case_size)
1602-
trap_if(ptr + worst_case_size > len(cx.opts.memory))
16031601
encoded = src.encode('utf-8')
16041602
cx.opts.memory[ptr+i : ptr+len(encoded)] = encoded[i : ]
16051603
if worst_case_size > len(encoded):
16061604
ptr = cx.reallocate(ptr, worst_case_size, 1, len(encoded))
1607-
trap_if(ptr + len(encoded) > len(cx.opts.memory))
16081605
return (ptr, len(encoded))
16091606
return (ptr, src_code_units)
16101607

16111608
def store_utf8_to_utf16(cx, src, src_code_units):
16121609
worst_case_size = 2 * src_code_units
16131610
assert(worst_case_size <= REALLOC_I32_MAX)
16141611
ptr = cx.allocate(2, worst_case_size)
1615-
trap_if(ptr != align_to(ptr, 2))
1616-
trap_if(ptr + worst_case_size > len(cx.opts.memory))
16171612
encoded = src.encode('utf-16-le')
16181613
cx.opts.memory[ptr : ptr+len(encoded)] = encoded
16191614
if len(encoded) < worst_case_size:
16201615
ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded))
1621-
trap_if(ptr != align_to(ptr, 2))
1622-
trap_if(ptr + len(encoded) > len(cx.opts.memory))
16231616
code_units = int(len(encoded) / 2)
16241617
return (ptr, code_units)
16251618

16261619
def store_string_to_latin1_or_utf16(cx, src, src_code_units):
16271620
assert(src_code_units <= REALLOC_I32_MAX)
16281621
ptr = cx.allocate(2, src_code_units)
1629-
trap_if(ptr != align_to(ptr, 2))
1630-
trap_if(ptr + src_code_units > len(cx.opts.memory))
16311622
dst_byte_length = 0
16321623
for usv in src:
16331624
if ord(usv) < (1 << 8):
@@ -1637,31 +1628,23 @@ def store_string_to_latin1_or_utf16(cx, src, src_code_units):
16371628
worst_case_size = 2 * src_code_units
16381629
assert(worst_case_size <= REALLOC_I32_MAX)
16391630
ptr = cx.reallocate(ptr, src_code_units, 2, worst_case_size)
1640-
trap_if(ptr != align_to(ptr, 2))
1641-
trap_if(ptr + worst_case_size > len(cx.opts.memory))
16421631
for j in range(dst_byte_length-1, -1, -1):
16431632
cx.opts.memory[ptr + 2*j] = cx.opts.memory[ptr + j]
16441633
cx.opts.memory[ptr + 2*j + 1] = 0
16451634
encoded = src.encode('utf-16-le')
16461635
cx.opts.memory[ptr+2*dst_byte_length : ptr+len(encoded)] = encoded[2*dst_byte_length : ]
16471636
if worst_case_size > len(encoded):
16481637
ptr = cx.reallocate(ptr, worst_case_size, 2, len(encoded))
1649-
trap_if(ptr != align_to(ptr, 2))
1650-
trap_if(ptr + len(encoded) > len(cx.opts.memory))
16511638
tagged_code_units = int(len(encoded) / 2) | utf16_tag(cx.opts.memory.ptr_type())
16521639
return (ptr, tagged_code_units)
16531640
if dst_byte_length < src_code_units:
16541641
ptr = cx.reallocate(ptr, src_code_units, 2, dst_byte_length)
1655-
trap_if(ptr != align_to(ptr, 2))
1656-
trap_if(ptr + dst_byte_length > len(cx.opts.memory))
16571642
return (ptr, dst_byte_length)
16581643

16591644
def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units):
16601645
src_byte_length = 2 * src_code_units
16611646
assert(src_byte_length <= REALLOC_I32_MAX)
16621647
ptr = cx.allocate(2, src_byte_length)
1663-
trap_if(ptr != align_to(ptr, 2))
1664-
trap_if(ptr + src_byte_length > len(cx.opts.memory))
16651648
encoded = src.encode('utf-16-le')
16661649
cx.opts.memory[ptr : ptr+len(encoded)] = encoded
16671650
if any(ord(c) >= (1 << 8) for c in src):
@@ -1670,8 +1653,7 @@ def store_probably_utf16_to_latin1_or_utf16(cx, src, src_code_units):
16701653
latin1_size = int(len(encoded) / 2)
16711654
for i in range(latin1_size):
16721655
cx.opts.memory[ptr + i] = cx.opts.memory[ptr + 2*i]
1673-
ptr = cx.reallocate(ptr, src_byte_length, 1, latin1_size)
1674-
trap_if(ptr + latin1_size > len(cx.opts.memory))
1656+
ptr = cx.reallocate(ptr, src_byte_length, 2, latin1_size)
16751657
return (ptr, latin1_size)
16761658

16771659
def lower_error_context(cx, v):
@@ -1690,8 +1672,6 @@ def store_list_into_range(cx, v, elem_type):
16901672
byte_length = len(v) * elem_size(elem_type, cx.opts.memory.ptr_type())
16911673
assert(byte_length <= REALLOC_I32_MAX)
16921674
ptr = cx.allocate(alignment(elem_type, cx.opts.memory.ptr_type()), byte_length)
1693-
trap_if(ptr != align_to(ptr, alignment(elem_type, cx.opts.memory.ptr_type())))
1694-
trap_if(ptr + byte_length > len(cx.opts.memory))
16951675
store_list_into_valid_range(cx, v, ptr, elem_type)
16961676
return (ptr, len(v))
16971677

@@ -2059,9 +2039,9 @@ def lower_flat_values(cx, max_flat, vs, ts, out_param = None):
20592039
flat_vals = [ptr]
20602040
else:
20612041
ptr = out_param.next(cx.opts.memory.ptr_type())
2042+
trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type())))
2043+
trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory))
20622044
flat_vals = []
2063-
trap_if(ptr != align_to(ptr, alignment(tuple_type, cx.opts.memory.ptr_type())))
2064-
trap_if(ptr + elem_size(tuple_type, cx.opts.memory.ptr_type()) > len(cx.opts.memory))
20652045
store(cx, tuple_value, tuple_type, ptr)
20662046
else:
20672047
flat_vals = []

0 commit comments

Comments
 (0)