Skip to content

interface conversion: interface {} is int, not string when trying to index slice type #346

@blotus

Description

@blotus

Hello,

When trying to upgrade expr from 1.9 to the latest version in crowdsec, some of our automated tests failed with the following error:

WARN[09-03-2023 00:17:41] runtime error : interface conversion: interface {} is int, not string (1:27)
 | "192.168.9.212" in results[0].Overflow.GetSources()
 | ..........................^

After some debugging, I managed to narrow down the issue and reproduce it with the following code:

package main

import (
	"fmt"

	"github.com/antonmedv/expr"
)

type EventsSlice []Event

func (b EventsSlice) Len() int {
	return 42
}

type Event struct {
	Foo string
}

func main() {
	env := map[string]interface{}{
		"results": EventsSlice{{"bar"}},
	}

	code := `results[0].Foo`

	program, err := expr.Compile(code, expr.Env(env))
	if err != nil {
		fmt.Printf("error compiling expression: %s\n", err)
		return
	}

	fmt.Printf("%s", program.Disassemble())

	output, err := expr.Run(program, env)
	if err != nil {
		fmt.Printf("error running expression: %s\n", err)
		return
	}

	fmt.Println(output)
}

and gives this output:

0	OpLoadFast	0	results
1	OpPush	1	0
2	OpFetch
3	OpFetchField	2	{Foo [0]}
error running expression: interface conversion: interface {} is int, not string (1:8)
 | results[0].Foo
 | .......^

It seems that if a slice type has a non-pointer receiver, you cannot index it (if you change the Len() definition to be a pointer receiver, expr has no issue using the variable).

This issue is probably related to #271, which you did not manage to reproduce at the time.

Go version: go version go1.20.1 linux/amd64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions