apply TODO to rename "cannot obfuscate" APIs

They have been exclusively about reflect for over a year now.
Make that clearer, and update the docs as well.
pull/755/head
Daniel Martí 2 years ago
parent e079c0af43
commit d108f21846

@ -1272,11 +1272,14 @@ type pkgCache struct {
// unless we were smart enough to detect which arguments get used as %#v or %T. // unless we were smart enough to detect which arguments get used as %#v or %T.
ReflectAPIs map[funcFullName]map[int]bool ReflectAPIs map[funcFullName]map[int]bool
// CannotObfuscate is filled with the fully qualified names from each // ReflectObjects is filled with the fully qualified names from each
// package that we cannot obfuscate. // package that we cannot obfuscate due to reflection.
// The included objects are named types and their fields,
// since it is those names being obfuscated that could break the use of reflect.
//
// This record is necessary for knowing what names from imported packages // This record is necessary for knowing what names from imported packages
// weren't obfuscated, so we can obfuscate their local uses accordingly. // weren't obfuscated, so we can obfuscate their local uses accordingly.
CannotObfuscate map[objectString]struct{} ReflectObjects map[objectString]struct{}
// EmbeddedAliasFields records which embedded fields use a type alias. // EmbeddedAliasFields records which embedded fields use a type alias.
// They are the only instance where a type alias matters for obfuscation, // They are the only instance where a type alias matters for obfuscation,
@ -1292,7 +1295,7 @@ var curPkgCache = pkgCache{
"reflect.TypeOf": {0: true}, "reflect.TypeOf": {0: true},
"reflect.ValueOf": {0: true}, "reflect.ValueOf": {0: true},
}, },
CannotObfuscate: map[objectString]struct{}{}, ReflectObjects: map[objectString]struct{}{},
EmbeddedAliasFields: map[objectString]typeName{}, EmbeddedAliasFields: map[objectString]typeName{},
} }
@ -1797,7 +1800,7 @@ func (tf *transformer) transformGoFile(file *ast.File) *ast.File {
// and it's entirely unsupported, but try to accomodate for now. // and it's entirely unsupported, but try to accomodate for now.
// At least it's enough to leave the rtype and Value types intact. // At least it's enough to leave the rtype and Value types intact.
case "rtype", "Value": case "rtype", "Value":
tf.recursivelyRecordAsNotObfuscated(obj.Type()) tf.recursivelyRecordUsedForReflect(obj.Type())
return true return true
} }
case "crypto/x509/pkix": case "crypto/x509/pkix":
@ -1812,7 +1815,7 @@ func (tf *transformer) transformGoFile(file *ast.File) *ast.File {
} }
// The package that declared this object did not obfuscate it. // The package that declared this object did not obfuscate it.
if recordedAsNotObfuscated(obj) { if usedForReflect(obj) {
return true return true
} }

@ -114,7 +114,7 @@ func (tf *transformer) checkMethodSignature(reflectParams map[int]bool, sig *typ
if ignore { if ignore {
reflectParams[i] = true reflectParams[i] = true
tf.recursivelyRecordAsNotObfuscated(param.Type()) tf.recursivelyRecordUsedForReflect(param.Type())
} }
} }
} }
@ -245,7 +245,7 @@ func (tf *transformer) recordArgReflected(val ssa.Value, visited map[ssa.Value]b
case *ssa.Alloc: case *ssa.Alloc:
/* fmt.Printf("recording val %v \n", *val.Referrers()) */ /* fmt.Printf("recording val %v \n", *val.Referrers()) */
tf.recursivelyRecordAsNotObfuscated(val.Type()) tf.recursivelyRecordUsedForReflect(val.Type())
for _, ref := range *val.Referrers() { for _, ref := range *val.Referrers() {
if idx, ok := ref.(*ssa.IndexAddr); ok { if idx, ok := ref.(*ssa.IndexAddr); ok {
@ -260,9 +260,9 @@ func (tf *transformer) recordArgReflected(val ssa.Value, visited map[ssa.Value]b
return relatedParam(val, visited) return relatedParam(val, visited)
case *ssa.Const: case *ssa.Const:
tf.recursivelyRecordAsNotObfuscated(val.Type()) tf.recursivelyRecordUsedForReflect(val.Type())
case *ssa.Global: case *ssa.Global:
tf.recursivelyRecordAsNotObfuscated(val.Type()) tf.recursivelyRecordUsedForReflect(val.Type())
// TODO: this might need similar logic to *ssa.Alloc, however // TODO: this might need similar logic to *ssa.Alloc, however
// reassigning a function param to a global variable and then reflecting // reassigning a function param to a global variable and then reflecting
@ -271,7 +271,7 @@ func (tf *transformer) recordArgReflected(val ssa.Value, visited map[ssa.Value]b
// this only finds the parameters who want to be found, // this only finds the parameters who want to be found,
// otherwise relatedParam is used for more in depth analysis // otherwise relatedParam is used for more in depth analysis
tf.recursivelyRecordAsNotObfuscated(val.Type()) tf.recursivelyRecordUsedForReflect(val.Type())
return val return val
} }
@ -341,13 +341,13 @@ func relatedParam(val ssa.Value, visited map[ssa.Value]bool) *ssa.Parameter {
return nil return nil
} }
// recursivelyRecordAsNotObfuscated calls recordAsNotObfuscated on any named // recursivelyRecordUsedForReflect calls recordUsedForReflect on any named
// types and fields under typ. // types and fields under typ.
// //
// Only the names declared in the current package are recorded. This is to ensure // Only the names declared in the current package are recorded. This is to ensure
// that reflection detection only happens within the package declaring a type. // that reflection detection only happens within the package declaring a type.
// Detecting it in downstream packages could result in inconsistencies. // Detecting it in downstream packages could result in inconsistencies.
func (tf *transformer) recursivelyRecordAsNotObfuscated(t types.Type) { func (tf *transformer) recursivelyRecordUsedForReflect(t types.Type) {
switch t := t.(type) { switch t := t.(type) {
case *types.Named: case *types.Named:
obj := t.Obj() obj := t.Obj()
@ -357,13 +357,13 @@ func (tf *transformer) recursivelyRecordAsNotObfuscated(t types.Type) {
if obj.Pkg() == nil || obj.Pkg() != tf.pkg { if obj.Pkg() == nil || obj.Pkg() != tf.pkg {
return // not from the specified package return // not from the specified package
} }
if recordedAsNotObfuscated(obj) { if usedForReflect(obj) {
return // prevent endless recursion return // prevent endless recursion
} }
recordAsNotObfuscated(obj) recordUsedForReflect(obj)
// Record the underlying type, too. // Record the underlying type, too.
tf.recursivelyRecordAsNotObfuscated(t.Underlying()) tf.recursivelyRecordUsedForReflect(t.Underlying())
case *types.Struct: case *types.Struct:
for i := 0; i < t.NumFields(); i++ { for i := 0; i < t.NumFields(); i++ {
@ -377,14 +377,14 @@ func (tf *transformer) recursivelyRecordAsNotObfuscated(t types.Type) {
} }
// Record the field itself, too. // Record the field itself, too.
recordAsNotObfuscated(field) recordUsedForReflect(field)
tf.recursivelyRecordAsNotObfuscated(field.Type()) tf.recursivelyRecordUsedForReflect(field.Type())
} }
case interface{ Elem() types.Type }: case interface{ Elem() types.Type }:
// Get past pointers, slices, etc. // Get past pointers, slices, etc.
tf.recursivelyRecordAsNotObfuscated(t.Elem()) tf.recursivelyRecordUsedForReflect(t.Elem())
} }
} }
@ -421,16 +421,11 @@ func recordedObjectString(obj types.Object) objectString {
return pkg.Path() + "." + obj.Name() return pkg.Path() + "." + obj.Name()
} }
// recordAsNotObfuscated records all the objects whose names we cannot obfuscate. // recordUsedForReflect records the objects whose names we cannot obfuscate due to reflection.
// An object is any named entity, such as a declared variable or type. // We currently record named types and fields.
// func recordUsedForReflect(obj types.Object) {
// As of June 2022, this only records types which are used in reflection.
// TODO(mvdan): If this is still the case in a year's time,
// we should probably rename "not obfuscated" and "cannot obfuscate" to be
// directly about reflection, e.g. "used in reflection".
func recordAsNotObfuscated(obj types.Object) {
if obj.Pkg().Path() != curPkg.ImportPath { if obj.Pkg().Path() != curPkg.ImportPath {
panic("called recordedAsNotObfuscated with a foreign object") panic("called recordUsedForReflect with a foreign object")
} }
objStr := recordedObjectString(obj) objStr := recordedObjectString(obj)
if objStr == "" { if objStr == "" {
@ -438,14 +433,14 @@ func recordAsNotObfuscated(obj types.Object) {
// do we need to record it at all? // do we need to record it at all?
return return
} }
curPkgCache.CannotObfuscate[objStr] = struct{}{} curPkgCache.ReflectObjects[objStr] = struct{}{}
} }
func recordedAsNotObfuscated(obj types.Object) bool { func usedForReflect(obj types.Object) bool {
objStr := recordedObjectString(obj) objStr := recordedObjectString(obj)
if objStr == "" { if objStr == "" {
return false return false
} }
_, ok := curPkgCache.CannotObfuscate[objStr] _, ok := curPkgCache.ReflectObjects[objStr]
return ok return ok
} }

Loading…
Cancel
Save