Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use go-jose/go-jose #1502

Open
Cyb3r-Jak3 opened this issue Jan 18, 2023 · 4 comments
Open

Unable to use go-jose/go-jose #1502

Cyb3r-Jak3 opened this issue Jan 18, 2023 · 4 comments
Labels
area/core bug Something isn't working

Comments

@Cyb3r-Jak3
Copy link

Cyb3r-Jak3 commented Jan 18, 2023

The following program sample.go triggers an unexpected result

package main

import (
	"fmt"

	"github.com/go-jose/go-jose/v3"
)

func main() {
	fmt.Println(jose.A128GCM)
}

Expected result

go run main.go
A128GCM

Got

yaegi ./main.go
go-jose/go-jose/v3/json/encode.go:650:48: cannot use type *json.encodeState as type io.Writer

Yaegi Version

v0.14.3

Additional Notes

No response

@mvertes mvertes added bug Something isn't working area/core labels Feb 9, 2023
@jmanero
Copy link

jmanero commented Feb 17, 2023

It looks like the interpreter may not be handling embedding in an unexported type. This it the json.encodeState type from go-jose:

// An encodeState encodes JSON into a bytes.Buffer.
type encodeState struct {
	bytes.Buffer // accumulated output
	scratch      [64]byte
}

bytes.Buffer should implement io.Writer

@ssbeatty
Copy link
Contributor

ssbeatty commented Mar 15, 2023

Struct embedding doesn't seem to work very well at the moment
In this code

package main

import (
	"bytes"
	"reflect"
)

func main() {
	tt := reflect.StructOf([]reflect.StructField{
		{Name: "Buffer", Type: reflect.TypeOf(bytes.Buffer{}), Anonymous: true},
	})

	if _, present := tt.MethodByName("Write"); present {
		println("tt has Write func")
	} else {
		println("tt has not Write func")
	}

	bt := reflect.StructOf([]reflect.StructField{
		{Name: "Buffer", Type: reflect.TypeOf(&bytes.Buffer{}), Anonymous: true},
	})

	if _, present := bt.MethodByName("Write"); present {
		println("bt has Write func")
	} else {
		println("bt has not Write func")
	}
}


// ouput
// tt has not Write func
// bt has Write func

When the field type passed into reflect.StructOf is pointer/non-pointer, the number of methods that reflect.Type can obtain is different

So in

if dest.Kind() == reflect.Interface && src.Implements(dest) {

Is it more reasonable to change to the following code

	if dest.Kind() == reflect.Interface {
		if src.Kind() == reflect.Pointer {
			return src.Elem().Implements(dest)
		} else {
			return src.Implements(dest)
		}
	}

With this modification, the following code will work fine

// An encodeState encodes JSON into a bytes.Buffer.
type encodeState struct {
	*bytes.Buffer // accumulated output
	scratch      [64]byte
}

But if a structure is directly embedded, and the methods of this structure all contain pointers, there is nothing can do

Maybe reflect.PtrTo(rtype).Implements(typ) can implement

@taliesins
Copy link

@Cyb3r-Jak3 you may be interested in looking at: https://github.com/taliesins/traefik-plugin-oidc/tree/main/jwt

We hacked it to work with yaegi

@Cyb3r-Jak3
Copy link
Author

@taliesins Thanks! I will take a look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/core bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants