phpserialize icon indicating copy to clipboard operation
phpserialize copied to clipboard

Cannot unmarshal to interface{}

Open mitar opened this issue 2 years ago • 8 comments

It seems the following is not supported:

var d interface{}
err := phpserialize.Unmarshal(m, &d)

I wonder why? It would be nice to be able to just infer type? Especially given that there is typing information in PHP serialized string.

mitar avatar Feb 03 '22 09:02 mitar

Indeed. I'm happy to accept a pull request for this.

elliotchance avatar Feb 04 '22 01:02 elliotchance

I am not sure if I understand the PHP format well enough to contribute this myself.

mitar avatar Feb 10 '22 23:02 mitar

Within Unmarshal you can replace these lines:

	default:
		return errors.New("can not unmarshal type: " + value.Kind().String())

With:

	default:
		v, _, err := consumeNext(data, 0)
		if err != nil {
			return err
		}

		value.Set(reflect.ValueOf(v))
		return nil

Add a few unit tests to be sure.

elliotchance avatar Feb 13 '22 12:02 elliotchance

	var i map[string]interface{}

	if err = phpserialize.Unmarshal([]byte(syscache.Data), &i); err == nil {

		return ""
	}

panic: reflect.Set: value of type map[interface {}]interface {} is not assignable to type map[string]interface {} [recovered] panic: reflect.Set: value of type map[interface {}]interface {} is not assignable to type map[string]interface {}

studyzhanglei avatar Feb 17 '22 03:02 studyzhanglei

panic: reflect.Set: value of type map[interface {}]interface {} is not assignable to type map[string]interface {}

The error message is pretty clear, you cannot use map[string]interface{} you have to use map[interface{}]interface{}. You will need to create the string-indexed map yourself.

elliotchance avatar Feb 20 '22 17:02 elliotchance

panic: reflect.Set: value of type map[interface {}]interface {} is not assignable to type map[string]interface {}

The error message is pretty clear, you cannot use map[string]interface{} you have to use map[interface{}]interface{}. You will need to create the string-indexed map yourself.

Thanks, i overlooked that.

studyzhanglei avatar Feb 21 '22 03:02 studyzhanglei

Sure, I got panic like this: reflect.Set: value of type []interface {} is not assignable to type []string /root/go/pkg/mod/go.opentelemetry.io/otel/[email protected]/trace/span.go:383 (0x1040564) /root/go/pkg/mod/go.opentelemetry.io/otel/[email protected]/trace/span.go:421 (0x10404cc) /usr/local/go/src/runtime/panic.go:914 (0x43d05e) /usr/local/go/src/reflect/value.go:3307 (0x4db5c8) /usr/local/go/src/reflect/value.go:2260 (0x4d7645) /root/go/pkg/mod/github.com/elliotchance/[email protected]/unserialize.go:188 (0x1124535)

Even I must replace make([]string{}, 0) to make([]interface{}, 0), but then I have to item.(string) get the value for string. So, If you define the slice type into function phpserialize.Unmarshal, the items of slice must be type interface.

whisky-rye avatar Dec 11 '23 07:12 whisky-rye

@mysticzhong I'm happy to accept a PR if you want to support that, otherwise casting is the way to go.

elliotchance avatar Dec 12 '23 18:12 elliotchance