Skip to content

Commit

Permalink
security(engine)!: restrict execution of halt/1
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamel committed Nov 24, 2024
1 parent 7935f05 commit 3a63e6e
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 16 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ The following customizations have been made to adapt the original `ichiban/prolo
- Removed support for trigonometric functions (`sin`, `cos`, `tan`, `asin`, `acos`, `atan`).
- Introduced VM hooks for enhanced Prolog execution control.
- Added support for the `Dict` term.
- `halt/0` and `halt/1` are forbidden and will throw an error.

## License

Expand Down
4 changes: 3 additions & 1 deletion engine/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -1960,7 +1960,9 @@ func PeekChar(vm *VM, streamOrAlias, char Term, k Cont, env *Env) *Promise {
}
}

var osExit = os.Exit
var osExit = func(_ int) {
panic("halt/1 is not allowed")
}

// Halt exits the process with exit code of n.
func Halt(_ *VM, n Term, k Cont, env *Env) *Promise {
Expand Down
21 changes: 6 additions & 15 deletions engine/builtin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func TestCall(t *testing.T) {
panic(errors.New("told you"))
})
vm.Register0(NewAtom("do_not_call_exception"), func(*VM, Cont, *Env) *Promise {
panic(Exception{NewAtom("error").Apply(NewAtom("panic_error"), NewAtom("told you"))})
panic(Exception{NewAtom("error").Apply(NewAtom("panic_error").Apply(NewAtom("told you")))})
})
vm.Register0(NewAtom("do_not_call_misc_error"), func(*VM, Cont, *Env) *Promise {
panic(42)
Expand Down Expand Up @@ -5527,20 +5527,11 @@ func TestPeekChar(t *testing.T) {

func Test_Halt(t *testing.T) {
t.Run("ok", func(t *testing.T) {
var exitCalled bool
osExit = func(code int) {
assert.Equal(t, 2, code)
exitCalled = true
}
defer func() {
osExit = os.Exit
}()

ok, err := Halt(nil, Integer(2), Success, nil).Force(context.Background())
assert.NoError(t, err)
assert.True(t, ok)

assert.True(t, exitCalled)
ok, err := Delay(func(ctx context.Context) *Promise {
return Halt(nil, Integer(2), Success, nil)
}).Force(context.Background())
assert.EqualError(t, err, "error(panic_error(halt/1 is not allowed))")
assert.False(t, ok)
})

t.Run("n is a variable", func(t *testing.T) {
Expand Down

0 comments on commit 3a63e6e

Please sign in to comment.