gnolang / gno

Gno: An interpreted, stack-based Go virtual machine to build succinct and composable apps + Gno.land: a blockchain for timeless code and fair open-source
https://gno.land/
Other
839 stars 342 forks source link

amino.WithTypes accepts types being given the same name #2326

Open grepsuzette opened 2 weeks ago

grepsuzette commented 2 weeks ago

amino.WithTypes admits types with the same name

This potential issue was uncovered in #2325.

Description

Quite simply, the following code does not panic:

package amino_test

import (
    "reflect"
    "testing"
    "github.com/stretchr/testify/assert"
    amino "github.com/gnolang/gno/tm2/pkg/amino"
    "github.com/gnolang/gno/tm2/pkg/amino/tests"
)

func TestDupNamesMustPanic(t *testing.T) {
    assert.Panics(t, func() {
        amino.NewPackage(
            reflect.TypeOf(tests.EmptyStruct{}).PkgPath(),
            "amino_test",
            amino.GetCallersDirname(),
        ).WithTypes(
            tests.EmptyStruct{}, "A",
            tests.PrimitivesStruct{}, "B",
            tests.ShortArraysStruct{}, "A", // Same name
        )
    }
}

Expected behaviour

Since codec_test.go has the following line a panic should be expected here:

// XXX Test registering duplicate names or concrete types not in a package.

Proposed solution

Existing code for WithTypes prepares a pkg.Types which can just be iterated before returning.

https://github.com/gnolang/gno/blob/5541e35b5cdaf50a71f10a14badd64728adfc2b4/tm2/pkg/amino/pkg/pkg.go#L126-L187

The following actually fixes the test in #2325:

        (...)
        pkg.Types = append(pkg.Types, lastType)
    }

    // APPENDED HERE -------------------------------------------------------
    // Forbid duplicate names
    for i, t := range pkg.Types {
        if t.Name == "" {
            continue
        }
        for j := i + 1; j < len(pkg.Types); j++ {
            if pkg.Types[j].Name == t.Name {
                panic(fmt.Errorf("type name %s is already registered", t.Name))
            }
        }
    } // ------------------------------------------------------------------------^^^
    return pkg
}