From 2f29c5b262e3a303602fb0dd6f93a5690eac7167 Mon Sep 17 00:00:00 2001 From: Zxilly Date: Sun, 16 Jun 2024 17:33:27 +0800 Subject: [PATCH] feat: add strict type check for dwarf struct field Signed-off-by: Zxilly --- internal/dwarf/dwarf.go | 2 +- internal/dwarf/read.go | 10 +++++----- internal/dwarf/utils.go | 15 ++++++++++++--- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/internal/dwarf/dwarf.go b/internal/dwarf/dwarf.go index 8c2d64b28c..8e789780d4 100644 --- a/internal/dwarf/dwarf.go +++ b/internal/dwarf/dwarf.go @@ -45,7 +45,7 @@ func SizeForDWARFVar( }}, uint64(typ.Size()), nil } else if structTyp.StructName == "[]uint8" { // check byte slice, normally it comes from embed - dataAddr, size, err := readSlice(structTyp, readMemory) + dataAddr, size, err := readSlice(structTyp, readMemory, "*uint8") if err != nil || size == 0 { return nil, uint64(typ.Size()), err } diff --git a/internal/dwarf/read.go b/internal/dwarf/read.go index 25dac984fd..1797ba9aa2 100644 --- a/internal/dwarf/read.go +++ b/internal/dwarf/read.go @@ -36,7 +36,7 @@ func readIntTo64(data []byte) int64 { type MemoryReader func(addr, size uint64) ([]byte, error) func readString(structTyp *dwarf.StructType, readMemory MemoryReader) (addr uint64, size uint64, err error) { - err = checkField(structTyp, "str", "len") + err = checkField(structTyp, fieldPattern{"str", "*uint8"}, fieldPattern{"len", "int"}) if err != nil { return 0, 0, err } @@ -63,8 +63,8 @@ func readString(structTyp *dwarf.StructType, readMemory MemoryReader) (addr uint return ptr, uint64(strLen), nil } -func readSlice(typ *dwarf.StructType, readMemory MemoryReader) (addr uint64, size uint64, err error) { - err = checkField(typ, "array", "len", "cap") +func readSlice(typ *dwarf.StructType, readMemory MemoryReader, memberTyp string) (addr uint64, size uint64, err error) { + err = checkField(typ, fieldPattern{"array", memberTyp}, fieldPattern{"len", "int"}, fieldPattern{"cap", "int"}) if err != nil { return 0, 0, err } @@ -100,7 +100,7 @@ func readSlice(typ *dwarf.StructType, readMemory MemoryReader) (addr uint64, siz } func readEmbedFS(typ *dwarf.StructType, readMemory MemoryReader) ([]Content, error) { - err := checkField(typ, "files") + err := checkField(typ, fieldPattern{"files", "*struct []embed.file"}) if err != nil { return nil, err } @@ -127,7 +127,7 @@ func readEmbedFS(typ *dwarf.StructType, readMemory MemoryReader) ([]Content, err addr = ptr } return readMemory(addr, size) - }) + }, "*embed.file") if err != nil { return nil, err diff --git a/internal/dwarf/utils.go b/internal/dwarf/utils.go index bacf114112..99e00b2fcc 100644 --- a/internal/dwarf/utils.go +++ b/internal/dwarf/utils.go @@ -5,14 +5,23 @@ import ( "fmt" ) -func checkField(typ *dwarf.StructType, fields ...string) error { +type fieldPattern struct { + name string + typ string +} + +func checkField(typ *dwarf.StructType, fields ...fieldPattern) error { if len(typ.Field) != len(fields) { return fmt.Errorf("%s struct has %d fields", typ.StructName, len(typ.Field)) } for i, field := range fields { - if typ.Field[i].Name != field { - return fmt.Errorf("%s struct has wrong field name", typ.StructName) + if typ.Field[i].Name != field.name { + return fmt.Errorf("field %d name is %s, expect %s", i, typ.Field[i].Name, field.name) + } + + if typ.Field[i].Type.String() != field.typ { + return fmt.Errorf("field %d type is %s, expect %s", i, typ.Field[i].Type.String(), field.typ) } }