|
|
|
env GOPRIVATE=test/main
|
|
|
|
|
|
|
|
garble build
|
|
|
|
exec ./main
|
|
|
|
cmp stdout main.stdout
|
|
|
|
|
testdata: use longer Go filenames for binsubstr
Every now and then, a CI run would fail:
FAIL: testdata/scripts/reflect.txt:7: unexpected match for ["main.go"] in main
These were rare, and very hard to reproduce or debug.
My best guess is that, since "main.go" is a short string and we use
random eight-character obfuscated filenames ending with ".go", it was
possible that the random filename happened to end in "main" in some
cases.
Given the base64 encoding, the chances of a single suffix collision are
about 0.000006%. Note, however, that a single obfuscated build will most
likely obfuscate many filenames, especially for the tests obfuscating
multiple packages. For a single CI run with many tests across three OSs,
the chances of any collision are likely very low, but realistic.
All this has a simple fix: use longer filenames to match with. We choose
"garble_main.go" since it's long enough, but also because it's still
clear it's a "main" Go file, and it's very unlikely to cause conflicts
with filenames in upstream Go given the "garble_" prefix.
4 years ago
|
|
|
! binsubstr main$exe 'garble_main.go' 'test/main' 'importedpkg.' 'DownstreamObfuscated' 'SiblingObfuscated' 'IndirectObfuscated' 'IndirectNamedWithoutReflect' 'AliasIndirectNamedWithReflect' 'AliasIndirectNamedWithoutReflect'
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
binsubstr main$exe 'ReflectInDefined' 'ExportedField2' 'unexportedField2' 'IndirectUnobfuscated' 'IndirectNamedWithReflect'
|
|
|
|
|
|
|
|
[short] stop # no need to verify this with -short
|
|
|
|
|
|
|
|
# Check that the program works as expected without garble.
|
|
|
|
go build
|
|
|
|
exec ./main
|
|
|
|
cmp stdout main.stdout
|
|
|
|
|
|
|
|
-- go.mod --
|
|
|
|
module test/main
|
|
|
|
|
|
|
|
go 1.16
|
testdata: use longer Go filenames for binsubstr
Every now and then, a CI run would fail:
FAIL: testdata/scripts/reflect.txt:7: unexpected match for ["main.go"] in main
These were rare, and very hard to reproduce or debug.
My best guess is that, since "main.go" is a short string and we use
random eight-character obfuscated filenames ending with ".go", it was
possible that the random filename happened to end in "main" in some
cases.
Given the base64 encoding, the chances of a single suffix collision are
about 0.000006%. Note, however, that a single obfuscated build will most
likely obfuscate many filenames, especially for the tests obfuscating
multiple packages. For a single CI run with many tests across three OSs,
the chances of any collision are likely very low, but realistic.
All this has a simple fix: use longer filenames to match with. We choose
"garble_main.go" since it's long enough, but also because it's still
clear it's a "main" Go file, and it's very unlikely to cause conflicts
with filenames in upstream Go given the "garble_" prefix.
4 years ago
|
|
|
-- garble_main.go --
|
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"reflect"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"test/main/importedpkg"
|
|
|
|
"test/main/importedpkg2"
|
|
|
|
)
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
// Fields still work fine when they are not obfuscated.
|
|
|
|
fmt.Println(importedpkg.ReflectInDefinedVar.ExportedField2)
|
|
|
|
fmt.Println(importedpkg.ReflectInDefined{ExportedField2: 5})
|
|
|
|
|
|
|
|
// Type names are not obfuscated either, when reflection is used.
|
|
|
|
printfWithoutPackage("%T\n", importedpkg.ReflectTypeOf(2))
|
|
|
|
printfWithoutPackage("%T\n", importedpkg.ReflectTypeOfIndirect(4))
|
|
|
|
|
|
|
|
// More complex use of reflect.
|
|
|
|
v := importedpkg.ReflectValueOfVar
|
|
|
|
printfWithoutPackage("%#v\n", v)
|
|
|
|
method := reflect.ValueOf(&v).MethodByName("ExportedMethodName")
|
|
|
|
if method.IsValid() {
|
|
|
|
fmt.Println(method.Call(nil))
|
|
|
|
} else {
|
|
|
|
fmt.Println("method not found")
|
|
|
|
}
|
|
|
|
|
|
|
|
// Use of a common library using reflect, encoding/json.
|
|
|
|
// TODO: remove the TypeOf hint once we detect json.Marshal.
|
|
|
|
_ = reflect.TypeOf(EncodingT{})
|
|
|
|
enc, _ := json.Marshal(EncodingT{Foo: 3})
|
|
|
|
println(string(enc))
|
|
|
|
|
|
|
|
// Another complex case, involving embedding and another package.
|
|
|
|
outer := &importedpkg.EmbeddingOuter{}
|
|
|
|
outer.InnerField = 3
|
|
|
|
enc, _ = json.Marshal(outer)
|
|
|
|
println(string(enc))
|
|
|
|
|
|
|
|
// An edge case; the struct type is defined in a different package.
|
|
|
|
// Note that the struct type is unnamed, but it still has named fields.
|
|
|
|
// We only use reflection on it here, not the declaring package.
|
|
|
|
// As such, we should obfuscate the field name.
|
|
|
|
// Simply using the field name here used to cause build failures.
|
|
|
|
_ = reflect.TypeOf(importedpkg.UnnamedWithDownstreamReflect{})
|
|
|
|
fmt.Printf("%v\n", importedpkg.UnnamedWithDownstreamReflect{
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
DownstreamObfuscated: "downstream",
|
|
|
|
})
|
|
|
|
|
|
|
|
// An edge case; the struct type is defined in package importedpkg2.
|
|
|
|
// importedpkg2 does not use reflection on it, so it's not obfuscated there.
|
|
|
|
// importedpkg uses reflection on a type containing ReflectInSiblingImport.
|
|
|
|
// If our logic is incorrect, we might inconsistently obfuscate the type.
|
|
|
|
// We should not obfuscate it when building any package.
|
|
|
|
fmt.Printf("%v\n", importedpkg2.ReflectInSiblingImport{
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
SiblingObfuscated: "sibling",
|
|
|
|
})
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
|
obfuscate alias names like any other objects
Before this change, we would try to never obfuscate alias names. That
was far from ideal, as they can end up in field names via anonymous
fields.
Even then, we would sometimes still fail to build, because we would
inconsistently obfuscate alias names. For example, in the added test
case:
--- FAIL: TestScripts/syntax (0.23s)
testscript.go:397:
> env GOPRIVATE='test/main,private.source'
> garble build
[stderr]
# test/main/sub
Lv_a8gRD.go:15: undefined: KCvSpxmQ
To fix this problem, we set obj to be the TypeName corresponding to the
alias when it is used as an embedded field. We can then make the right
choice when obfuscating the name.
Right now, all aliases will be obfuscated. A TODO exists about not
obfuscating alias names when they're used as embedded fields in a struct
type in the same package, and that package is used for reflection -
since then, the alias name ends up as the field name.
With these changes, the protobuf module now builds.
5 years ago
|
|
|
// Using type aliases as both regular fields, and embedded fields.
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
var emb EmbeddingIndirect
|
|
|
|
emb.With.IndirectUnobfuscated = "indirect-with"
|
|
|
|
emb.Without.IndirectObfuscated = "indirect-without"
|
|
|
|
fmt.Printf("%v\n", emb)
|
|
|
|
printfWithoutPackage("%#v\n", emb.With)
|
obfuscate alias names like any other objects
Before this change, we would try to never obfuscate alias names. That
was far from ideal, as they can end up in field names via anonymous
fields.
Even then, we would sometimes still fail to build, because we would
inconsistently obfuscate alias names. For example, in the added test
case:
--- FAIL: TestScripts/syntax (0.23s)
testscript.go:397:
> env GOPRIVATE='test/main,private.source'
> garble build
[stderr]
# test/main/sub
Lv_a8gRD.go:15: undefined: KCvSpxmQ
To fix this problem, we set obj to be the TypeName corresponding to the
alias when it is used as an embedded field. We can then make the right
choice when obfuscating the name.
Right now, all aliases will be obfuscated. A TODO exists about not
obfuscating alias names when they're used as embedded fields in a struct
type in the same package, and that package is used for reflection -
since then, the alias name ends up as the field name.
With these changes, the protobuf module now builds.
5 years ago
|
|
|
|
|
|
|
// TODO: don't obfuscate the embedded field name here
|
|
|
|
// printfWithoutPackage("%#v\n", importedpkg.ReflectEmbeddingAlias{})
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
}
|
|
|
|
|
|
|
|
type EmbeddingIndirect struct {
|
|
|
|
// With field names, to test selectors above.
|
|
|
|
With importedpkg.AliasIndirectNamedWithReflect
|
|
|
|
Without importedpkg.AliasIndirectNamedWithoutReflect
|
|
|
|
|
|
|
|
// Embedding used to crash garble, too.
|
|
|
|
importedpkg.AliasIndirectNamedWithReflect
|
|
|
|
}
|
|
|
|
|
|
|
|
func printfWithoutPackage(format string, v interface{}) {
|
|
|
|
s := fmt.Sprintf(format, v)
|
|
|
|
if i := strings.IndexByte(s, '.'); i > 0 {
|
|
|
|
s = s[i+1:]
|
|
|
|
}
|
|
|
|
fmt.Print(s)
|
|
|
|
}
|
|
|
|
|
|
|
|
type EncodingT struct {
|
|
|
|
Foo int
|
|
|
|
}
|
|
|
|
|
|
|
|
type RecursiveStruct struct {
|
|
|
|
*RecursiveStruct
|
|
|
|
list []RecursiveStruct
|
|
|
|
}
|
|
|
|
|
|
|
|
// This could crash or hang if we don't deal with loops.
|
|
|
|
var _ = reflect.TypeOf(RecursiveStruct{})
|
|
|
|
|
|
|
|
-- importedpkg/imported.go --
|
|
|
|
package importedpkg
|
|
|
|
|
|
|
|
import (
|
|
|
|
"reflect"
|
|
|
|
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
"test/main/importedpkg/indirect"
|
|
|
|
"test/main/importedpkg2"
|
|
|
|
)
|
|
|
|
|
|
|
|
type ReflectTypeOf int
|
|
|
|
|
|
|
|
var _ = reflect.TypeOf(ReflectTypeOf(0))
|
|
|
|
|
|
|
|
type ReflectTypeOfIndirect int
|
|
|
|
|
|
|
|
var _ = reflect.TypeOf(new([]*ReflectTypeOfIndirect))
|
|
|
|
|
|
|
|
type ReflectValueOf struct {
|
|
|
|
ExportedField string
|
|
|
|
|
|
|
|
unexportedField string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (r *ReflectValueOf) ExportedMethodName() string { return "method: " + r.ExportedField }
|
|
|
|
|
|
|
|
var ReflectValueOfVar = ReflectValueOf{ExportedField: "abc"}
|
|
|
|
|
|
|
|
var _ = reflect.TypeOf(ReflectValueOfVar)
|
|
|
|
|
|
|
|
type ReflectInDefined struct {
|
|
|
|
ExportedField2 int
|
|
|
|
|
|
|
|
unexportedField2 int
|
|
|
|
|
|
|
|
importedpkg2.ReflectInSiblingImport
|
|
|
|
}
|
|
|
|
|
|
|
|
var ReflectInDefinedVar = ReflectInDefined{ExportedField2: 9000}
|
|
|
|
|
|
|
|
var _ = reflect.TypeOf(ReflectInDefinedVar)
|
|
|
|
|
|
|
|
var _ = reflect.TypeOf([]*struct{EmbeddingOuter}{})
|
|
|
|
|
|
|
|
type EmbeddingOuter struct {
|
|
|
|
EmbeddingInner
|
|
|
|
Anon struct {
|
|
|
|
AnonField int
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type EmbeddingInner struct {
|
|
|
|
InnerField int
|
|
|
|
}
|
|
|
|
|
|
|
|
type UnnamedWithDownstreamReflect = struct {
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
DownstreamObfuscated string
|
|
|
|
}
|
|
|
|
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
type (
|
|
|
|
AliasIndirectNamedWithReflect = indirect.IndirectNamedWithReflect
|
|
|
|
AliasIndirectNamedWithoutReflect = indirect.IndirectNamedWithoutReflect
|
|
|
|
)
|
|
|
|
|
obfuscate alias names like any other objects
Before this change, we would try to never obfuscate alias names. That
was far from ideal, as they can end up in field names via anonymous
fields.
Even then, we would sometimes still fail to build, because we would
inconsistently obfuscate alias names. For example, in the added test
case:
--- FAIL: TestScripts/syntax (0.23s)
testscript.go:397:
> env GOPRIVATE='test/main,private.source'
> garble build
[stderr]
# test/main/sub
Lv_a8gRD.go:15: undefined: KCvSpxmQ
To fix this problem, we set obj to be the TypeName corresponding to the
alias when it is used as an embedded field. We can then make the right
choice when obfuscating the name.
Right now, all aliases will be obfuscated. A TODO exists about not
obfuscating alias names when they're used as embedded fields in a struct
type in the same package, and that package is used for reflection -
since then, the alias name ends up as the field name.
With these changes, the protobuf module now builds.
5 years ago
|
|
|
var _ = reflect.TypeOf(ReflectEmbeddingAlias{})
|
|
|
|
|
|
|
|
type ReflectEmbeddingAlias struct {
|
|
|
|
ReflectEmbeddedAlias
|
|
|
|
}
|
|
|
|
|
|
|
|
type ReflectEmbeddedAlias = ReflectEmbeddingNamed
|
|
|
|
|
|
|
|
type ReflectEmbeddingNamed struct{}
|
|
|
|
|
|
|
|
-- importedpkg2/imported2.go --
|
|
|
|
package importedpkg2
|
|
|
|
|
|
|
|
type ReflectInSiblingImport struct {
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
SiblingObfuscated string
|
|
|
|
}
|
|
|
|
|
|
|
|
-- importedpkg/indirect/indirect.go --
|
|
|
|
package indirect
|
|
|
|
|
|
|
|
import "reflect"
|
|
|
|
|
|
|
|
var _ = reflect.TypeOf(IndirectNamedWithReflect{})
|
|
|
|
|
|
|
|
type IndirectNamedWithReflect struct {
|
|
|
|
IndirectUnobfuscated string
|
|
|
|
}
|
|
|
|
|
|
|
|
type IndirectNamedWithoutReflect struct {
|
|
|
|
IndirectObfuscated string
|
|
|
|
}
|
|
|
|
|
|
|
|
-- main.stdout --
|
|
|
|
9000
|
|
|
|
{5 0 {}}
|
|
|
|
ReflectTypeOf
|
|
|
|
ReflectTypeOfIndirect
|
|
|
|
ReflectValueOf{ExportedField:"abc", unexportedField:""}
|
|
|
|
[method: abc]
|
|
|
|
{downstream}
|
|
|
|
{sibling}
|
fix a number of issues involving types from indirect imports
obfuscatedTypesPackage is used to figure out if a name in a dependency
package was obfuscated or not. For example, if that package used
reflection on a named type, it wasn't obfuscated, so we must have the
same information to not obfuscate the same name downstream.
obfuscatedTypesPackage could return nil if the package was indirectly
imported, though. This can happen if a direct import has a function that
returns an indirect type, or if a direct import exposes a name that's a
type alias to an indirect type.
We sort of dealt with this in two pieces of code by checking for
obfPkg!=nil, but a third one did not have this check and caused a panic
in the added test case:
--- FAIL: TestScripts/reflect (0.81s)
testscript.go:397:
> env GOPRIVATE=test/main
> garble build
[stderr]
# test/main
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x20 pc=0x8a5e39]
More importantly though, the nil check only avoids panics. It doesn't
fix the root cause of the problem: that importcfg does not contain
indirectly imported packages. The added test case would still fail, as
we would obfuscate a type in the main package, but not in the indirectly
imported package where the type is defined.
To fix this, resurrect a bit of code from earlier garble versions, which
uses "go list -toolexec=garble" to fetch a package's export file. This
lets us fill the indirect import gaps in importcfg, working around the
problem entirely.
This solution is still not particularly great, so we add a TODO about
possibly rethinking this in the future. It does add some overhead and
complexity, though thankfully indirect imports should be uncommon.
This fixes a few panics while building the protobuf module.
5 years ago
|
|
|
{{indirect-with} {indirect-without} {}}
|
|
|
|
IndirectNamedWithReflect{IndirectUnobfuscated:"indirect-with"}
|