Support Windows-style ar files.
Apparently Windows' .lib files are also ar. Add tests.
Change-Id: Ie35f410268086b8fe6d4d1b491de3f30a46309dd
Reviewed-on: https://boringssl-review.googlesource.com/c/33348
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/util/ar/ar.go b/util/ar/ar.go
index ce5c65c..756caf5 100644
--- a/util/ar/ar.go
+++ b/util/ar/ar.go
@@ -102,7 +102,9 @@
}
filename := longFilenameTable[offset:]
- if i := bytes.IndexByte(filename, '/'); i < 0 {
+ // Windows terminates filenames with NUL characters,
+ // while sysv/GNU uses /.
+ if i := bytes.IndexAny(filename, "/\x00"); i < 0 {
return nil, errors.New("ar: unterminated filename in table")
} else {
filename = filename[:i]
diff --git a/util/ar/ar_test.go b/util/ar/ar_test.go
index f9e23ff..ef37d79 100644
--- a/util/ar/ar_test.go
+++ b/util/ar/ar_test.go
@@ -28,7 +28,7 @@
type arTest struct {
name string
in string
- out []string
+ out map[string]string
// allowPadding is true if the contents may have trailing newlines at end.
// On macOS, ar calls ranlib which pads all inputs up to eight bytes with
// newlines. Unlike ar's native padding up to two bytes, this padding is
@@ -48,8 +48,33 @@
}
var arTests = []arTest{
- {"linux", "libsample.a", []string{"foo.c.o", "bar.cc.o"}, false},
- {"mac", "libsample.a", []string{"foo.c.o", "bar.cc.o"}, true},
+ {
+ "linux",
+ "libsample.a",
+ map[string]string{
+ "foo.c.o": "foo.c.o",
+ "bar.cc.o": "bar.cc.o",
+ },
+ false,
+ },
+ {
+ "mac",
+ "libsample.a",
+ map[string]string{
+ "foo.c.o": "foo.c.o",
+ "bar.cc.o": "bar.cc.o",
+ },
+ true,
+ },
+ {
+ "windows",
+ "sample.lib",
+ map[string]string{
+ "CMakeFiles\\sample.dir\\foo.c.obj": "foo.c.obj",
+ "CMakeFiles\\sample.dir\\bar.cc.obj": "bar.cc.obj",
+ },
+ false,
+ },
}
func TestAR(t *testing.T) {
@@ -66,12 +91,10 @@
t.Fatalf("reading input failed: %s", err)
}
- expectedFiles := make(map[string]struct{})
- for _, file := range test.out {
- expectedFiles[file] = struct{}{}
- expected, err := ioutil.ReadFile(test.Path(file))
+ for file, contentsPath := range test.out {
+ expected, err := ioutil.ReadFile(test.Path(contentsPath))
if err != nil {
- t.Fatalf("error reading %s: %s", file, err)
+ t.Fatalf("error reading %s: %s", contentsPath, err)
}
got, ok := ret[file]
if test.allowPadding {
@@ -86,7 +109,7 @@
}
for file, _ := range ret {
- if _, ok := expectedFiles[file]; !ok {
+ if _, ok := test.out[file]; !ok {
t.Errorf("output contained unexpected file %q", file)
}
}
diff --git a/util/ar/testdata/windows/bar.cc.obj b/util/ar/testdata/windows/bar.cc.obj
new file mode 100644
index 0000000..4a315cd
--- /dev/null
+++ b/util/ar/testdata/windows/bar.cc.obj
Binary files differ
diff --git a/util/ar/testdata/windows/foo.c.obj b/util/ar/testdata/windows/foo.c.obj
new file mode 100644
index 0000000..9b4aad7
--- /dev/null
+++ b/util/ar/testdata/windows/foo.c.obj
Binary files differ
diff --git a/util/ar/testdata/windows/sample.lib b/util/ar/testdata/windows/sample.lib
new file mode 100644
index 0000000..efeebb2
--- /dev/null
+++ b/util/ar/testdata/windows/sample.lib
Binary files differ