exercism / x86-64-assembly

Exercism exercises in x86-64 Assembly.
https://exercism.org/tracks/x86-64-assembly
MIT License
22 stars 18 forks source link

Prevent weird solutions to pass #163

Closed sudhackar closed 2 years ago

sudhackar commented 2 years ago

Look at this solution

section .text
global leap_year
leap_year:
    mov rsp,rbp
    pop rbp
    ret

This is possible because the test function has a frame of consistent size across all tests - 0

   0x0000000000000758 <+0>: push   rbp
   0x0000000000000759 <+1>: mov    rbp,rsp
   0x000000000000075c <+4>: mov    edi,0x7df
   0x0000000000000761 <+9>: call   0x9a0 <leap_year>
   0x0000000000000766 <+14>:    test   eax,eax
   0x0000000000000768 <+16>:    je     0x77b <test_year_not_divisible_by_4_in_common_year+35>
   0x000000000000076a <+18>:    mov    esi,0xe
   0x000000000000076f <+23>:    lea    rdi,[rip+0x2712]        # 0x2e88
   0x0000000000000776 <+30>:    call   0x2aa6 <UnityFail>
   0x000000000000077b <+35>:    nop
   0x000000000000077c <+36>:    pop    rbp
   0x000000000000077d <+37>:    ret

and the back trace is

[#0] 0x5555555549a0 → leap_year()
[#1] 0x555555554766 → test_year_not_divisible_by_4_in_common_year()
[#2] 0x555555556ca4 → UnityDefaultTestRun(Func=0x555555554758 <test_year_not_divisible_by_4_in_common_year>, FuncName=0x555555556ec8 "test_year_not_divisible_by_4_in_common_year", FuncLineNum=0x3b)
[#3] 0x5555555548d6 → main()

The above function just cleanly returns to the parent of the test UnityDefaultTestRun which makes the testcase safe as UnityFail has not been called.

I know a change in this direction would need a lot of work or not match with what we are trying to solve here, but I'm posting this issue nonetheless

bergjohan commented 2 years ago

This is an interesting case, however, I don't think it's worth spending time trying to prevent it. I'll refer to the comments in #151

sudhackar commented 2 years ago

Thanks