Skip to content
Snippets Groups Projects
Verified Commit b2d96812 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix secure access to structure with a constraint

parent 39dc25f9
No related branches found
No related tags found
No related merge requests found
get.go 0 → 100644
// Copyright 2022 schukai GmbH
// SPDX-License-Identifier: AGPL-3.0
package pathfinder
import (
"reflect"
"strings"
)
// This function returns the value of a field in a struct, given a path to the field.
func GetValue[D any](obj D, keyWithDots string) (any, error) {
keySlice := strings.Split(keyWithDots, ".")
v := reflect.ValueOf(obj)
for _, key := range keySlice[0 : len(keySlice)-1] {
for v.Kind() == reflect.Ptr {
if v.Kind() == reflect.Invalid {
return nil, newInvalidPathError(keyWithDots)
}
v = v.Elem()
}
if v.Kind() != reflect.Struct {
return nil, newUnsupportedTypePathError(keyWithDots, v.Type())
}
v = v.FieldByName(key)
}
if v.Kind() == reflect.Invalid {
return nil, newInvalidPathError(keyWithDots)
}
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
// non-supporter type at the top of the path
if v.Kind() != reflect.Struct {
return nil, newUnsupportedTypeAtTopOfPathError(keyWithDots, v.Type())
}
v = v.FieldByName(keySlice[len(keySlice)-1])
if !v.IsValid() {
return nil, newInvalidPathError(keyWithDots)
}
return v.Interface(), nil
}
...@@ -10,45 +10,6 @@ import ( ...@@ -10,45 +10,6 @@ import (
"strings" "strings"
) )
// This function returns the value of a field in a struct, given a path to the field.
func GetValue[D any](obj D, keyWithDots string) (any, error) {
keySlice := strings.Split(keyWithDots, ".")
v := reflect.ValueOf(obj)
for _, key := range keySlice[0 : len(keySlice)-1] {
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
if v.Kind() != reflect.Struct {
return nil, newUnsupportedTypePathError(keyWithDots, v.Type())
}
v = v.FieldByName(key)
}
if v.Kind() == reflect.Invalid {
return nil, newInvalidPathError(keyWithDots)
}
for v.Kind() == reflect.Ptr {
v = v.Elem()
}
// non-supporter type at the top of the path
if v.Kind() != reflect.Struct {
return nil, newUnsupportedTypeAtTopOfPathError(keyWithDots, v.Type())
}
v = v.FieldByName(keySlice[len(keySlice)-1])
if !v.IsValid() {
return nil, newInvalidPathError(keyWithDots)
}
return v.Interface(), nil
}
// This function sets the value of a field in a struct, given a path to the field. // This function sets the value of a field in a struct, given a path to the field.
func SetValue[D any](obj D, keyWithDots string, newValue any) error { func SetValue[D any](obj D, keyWithDots string, newValue any) error {
...@@ -57,6 +18,9 @@ func SetValue[D any](obj D, keyWithDots string, newValue any) error { ...@@ -57,6 +18,9 @@ func SetValue[D any](obj D, keyWithDots string, newValue any) error {
for _, key := range keySlice[0 : len(keySlice)-1] { for _, key := range keySlice[0 : len(keySlice)-1] {
for v.Kind() != reflect.Ptr { for v.Kind() != reflect.Ptr {
if v.Kind() == reflect.Invalid {
return newInvalidPathError(keyWithDots)
}
v = v.Addr() v = v.Addr()
} }
......
File moved
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment