Browse Source

avoid go/printer from breaking imports

We obfuscate import paths in import declarations like:

	"domain.com/somepkg"

by replacing them with the obfuscated package path:

	somepkg "HPS4Mskq"

Note how we add a name to the import if there wasn't one,
so that references like somepkg.Foo keep working in the code.

This could break in some edge cases involving comments between imports
in the Go code, because go/printer is somewhat brittle with positions:

	> garble build -tags buildtag
	[stderr]
	# test/main/importedpkg
	:16: syntax error: missing import path
	exit status 2
	exit status 2

To prevent that, ensure the name has a reasonable position.

This was preventing github.com/gorilla/websocket from being obufscated.
It is a fairly popular library in Go, but we don't add it to
scripts/check-third-party.sh for now as wireguard already gives us
coverage over networking and cryptography.
Daniel Martí 5 months ago
parent
commit
8d36e1d80e
2 changed files with 32 additions and 1 deletions
  1. 4 1
      main.go
  2. 28 0
      testdata/scripts/imports.txt

+ 4 - 1
main.go

@@ -1740,7 +1740,10 @@ func (tf *transformer) transformGo(file *ast.File) *ast.File {
 		newPath := lpkg.obfuscatedImportPath()
 		imp.Path.Value = strconv.Quote(newPath)
 		if imp.Name == nil {
-			imp.Name = &ast.Ident{Name: lpkg.Name}
+			imp.Name = &ast.Ident{
+				NamePos: imp.Path.ValuePos, // ensure it ends up on the same line
+				Name:    lpkg.Name,
+			}
 		}
 		return true
 	}

+ 28 - 0
testdata/scripts/imports.txt

@@ -151,6 +151,34 @@ type NormalStruct struct {
 	normalUnexportedField int
 }
 
+-- importedpkg/commented_imports.go --
+package importedpkg
+
+// The import group below used to trigger a bug in go/printer
+// where a named import could end up across two lines:
+//
+//   indirect
+//   "HPS4Mskq"
+//
+// resulting in a subsequent parsing failure:
+//
+//   syntax error: missing import path
+
+import (
+	// first comment
+
+	"test/main/importedpkg/another"
+
+	// second comment
+	"test/main/importedpkg/indirect"
+)
+
+var _ indirect.Indirect
+var _ = another.Blank
+-- importedpkg/another/pkg.go --
+package another
+
+const Blank = 3
 -- importedpkg/indirect/indirect.go --
 package indirect