|
10 | 10 | from ethereum_test_tools.vm.opcode import Opcodes as Op
|
11 | 11 |
|
12 | 12 | from .. import EOF_FORK_NAME
|
13 |
| -from .helpers import slot_code_worked, value_code_worked |
| 13 | +from .helpers import slot_code_worked, slot_stack_canary, value_canary_written, value_code_worked |
14 | 14 |
|
15 | 15 | REFERENCE_SPEC_GIT_PATH = "EIPS/eip-6206.md"
|
16 | 16 | REFERENCE_SPEC_VERSION = "2f365ea0cd58faa6e26013ea77ce6d538175f7d0"
|
@@ -235,39 +235,64 @@ def test_jumpf_stack_size_1024_at_push(
|
235 | 235 | )
|
236 | 236 |
|
237 | 237 |
|
| 238 | +@pytest.mark.parametrize( |
| 239 | + ("stack_height", "failure"), |
| 240 | + ( |
| 241 | + pytest.param(1021, False, id="no_overflow"), |
| 242 | + pytest.param(1022, True, id="rule_overflow"), |
| 243 | + pytest.param(1023, True, id="execution_overflow"), |
| 244 | + ), |
| 245 | +) |
238 | 246 | def test_jumpf_stack_overflow(
|
| 247 | + stack_height: int, |
| 248 | + failure: bool, |
239 | 249 | eof_state_test: EOFStateTestFiller,
|
240 | 250 | ):
|
241 |
| - """Test stack overflowing 1024 items in JUMPF target function""" |
| 251 | + """ |
| 252 | + Test stack overflowing 1024 items in JUMPF target function |
| 253 | +
|
| 254 | + `no_overflow` - the stack does not overflow at JUMPF call, executes to end |
| 255 | + `rule_overflow` - reserved stack overflows, but execution would not overflow |
| 256 | + `execution_overflow` - execution would overflow (but still blocked by reserved stack rule) |
| 257 | + """ |
242 | 258 | eof_state_test(
|
243 | 259 | data=Container(
|
244 | 260 | sections=[
|
245 | 261 | Section.Code(
|
246 |
| - code=Op.PUSH0 * 1023 |
| 262 | + code=Op.PUSH0 * stack_height |
247 | 263 | + Op.CALLF[1]
|
248 |
| - + Op.POP * 1023 |
| 264 | + + Op.POP * stack_height |
249 | 265 | + Op.SSTORE(slot_code_worked, value_code_worked)
|
250 | 266 | + Op.RETURN(0, 0),
|
251 |
| - max_stack_height=1023, |
| 267 | + max_stack_height=stack_height, |
252 | 268 | ),
|
253 | 269 | Section.Code(
|
254 |
| - # Stack has 1023 items |
| 270 | + # Stack has stack_height items |
255 | 271 | Op.JUMPF[2],
|
256 | 272 | code_inputs=0,
|
257 | 273 | code_outputs=0,
|
258 | 274 | max_stack_height=0,
|
259 | 275 | ),
|
260 | 276 | Section.Code(
|
261 |
| - Op.PUSH0 + Op.PUSH0 + |
262 |
| - # Runtime stack overflow |
263 |
| - Op.POP + Op.POP + Op.RETF, |
| 277 | + Op.CALLDATALOAD(0) |
| 278 | + + Op.ISZERO |
| 279 | + + Op.RJUMPI[6] |
| 280 | + + Op.PUSH0 * 3 |
| 281 | + + Op.POP * 3 |
| 282 | + + Op.SSTORE(slot_stack_canary, value_canary_written) |
| 283 | + + Op.RETF, |
264 | 284 | code_inputs=0,
|
265 | 285 | code_outputs=0,
|
266 |
| - max_stack_height=2, |
| 286 | + max_stack_height=3, |
267 | 287 | ),
|
268 | 288 | ],
|
269 | 289 | ),
|
270 |
| - container_post=Account(storage={slot_code_worked: 0}), |
| 290 | + container_post=Account( |
| 291 | + storage={ |
| 292 | + slot_code_worked: 0 if failure else value_code_worked, |
| 293 | + slot_stack_canary: 0 if failure else value_canary_written, |
| 294 | + } |
| 295 | + ), |
271 | 296 | )
|
272 | 297 |
|
273 | 298 |
|
|
0 commit comments