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