Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  zip_test.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright 2018 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package zip

import (
 "bytes"
 "encoding/hex"
 "hash/crc32"
 "io"
 "os"
 "reflect"
 "syscall"
 "testing"

 "android/soong/third_party/zip"

 "github.com/google/blueprint/pathtools"
)

var (
 fileA        = []byte("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
 fileB        = []byte("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB")
 fileC        = []byte("CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC")
 fileEmpty    = []byte("")
 fileManifest = []byte("Manifest-Version: 1.0\nCreated-By: soong_zip\n\n")

 sha256FileA = "d53eda7a637c99cc7fb566d96e9fa109bf15c478410a3f5eb4d4c4e26cd081f6"
 sha256FileB = "430c56c5818e62bcb6d478901ef86284e97714c138f3c86aa14fd6a84b7ce5d3"
 sha256FileC = "31c5ab6111f1d6aa13c2c4e92bb3c0f7c76b61b42d141af1e846eb7f6586a51c"

 fileCustomManifest  = []byte("Custom manifest: true\n")
 customManifestAfter = []byte("Manifest-Version: 1.0\nCreated-By: soong_zip\nCustom manifest: true\n\n")
)

var mockFs = pathtools.MockFs(map[string][]byte{
 "a/a/a":               fileA,
 "a/a/b":               fileB,
 "a/a/c -> ../../c":    nil,
 "dangling -> missing": nil,
 "a/a/d -> b":          nil,
 "c":                   fileC,
 "d/a/a":               nil,
 "l_nl":                []byte("a/a/a\na/a/b\nc\n\\[\n"),
 "l_sp":                []byte("a/a/a a/a/b c \\["),
 "l2":                  []byte("missing\n"),
 "rsp":                 []byte("'a/a/a'\na/a/b\n'@'\n'foo'\\''bar'\n'['"),
 "@ -> c":              nil,
 "foo'bar -> c":        nil,
 "manifest.txt":        fileCustomManifest,
 "[":                   fileEmpty,
})

func fh(name string, contents []byte, method uint16) zip.FileHeader {
 return zip.FileHeader{
  Name:               name,
  Method:             method,
  CRC32:              crc32.ChecksumIEEE(contents),
  UncompressedSize64: uint64(len(contents)),
  ExternalAttrs:      (syscall.S_IFREG | 0644) << 16,
 }
}

func fhWithSHA256(name string, contents []byte, method uint16, sha256 string) zip.FileHeader {
 h := fh(name, contents, method)
 // The extra field contains 38 bytes, including 2 bytes of header ID, 2 bytes
 // of size, 2 bytes of signature, and 32 bytes of checksum data block.
 var extra [38]byte
 // The first 6 bytes contains Sha256HeaderID (0x4967), size (unit(34)) and
 // Sha256HeaderSignature (0x9514)
 copy(extra[0:], []byte{1037334020149})
 sha256Bytes, _ := hex.DecodeString(sha256)
 copy(extra[6:], sha256Bytes)
 h.Extra = append(h.Extra, extra[:]...)
 return h
}

func fhManifest(contents []byte) zip.FileHeader {
 return zip.FileHeader{
  Name:               "META-INF/MANIFEST.MF",
  Method:             zip.Store,
  CRC32:              crc32.ChecksumIEEE(contents),
  UncompressedSize64: uint64(len(contents)),
  ExternalAttrs:      (syscall.S_IFREG | 0644) << 16,
 }
}

func fhLink(name string, to string) zip.FileHeader {
 return zip.FileHeader{
  Name:               name,
  Method:             zip.Store,
  CRC32:              crc32.ChecksumIEEE([]byte(to)),
  UncompressedSize64: uint64(len(to)),
  ExternalAttrs:      (syscall.S_IFLNK | 0777) << 16,
 }
}

type fhDirOptions struct {
 extra []byte
}

func fhDir(name string, opts fhDirOptions) zip.FileHeader {
 return zip.FileHeader{
  Name:               name,
  Method:             zip.Store,
  CRC32:              crc32.ChecksumIEEE(nil),
  UncompressedSize64: 0,
  ExternalAttrs:      (syscall.S_IFDIR|0755)<<16 | 0x10,
  Extra:              opts.extra,
 }
}

func fileArgsBuilder() *FileArgsBuilder {
 return &FileArgsBuilder{
  fs: mockFs,
 }
}

func TestZip(t *testing.T) {
 testCases := []struct {
  name               string
  args               *FileArgsBuilder
  compressionLevel   int
  emulateJar         bool
  nonDeflatedFiles   map[string]bool
  dirEntries         bool
  manifest           string
  storeSymlinks      bool
  ignoreMissingFiles bool
  sha256Checksum     bool

  files []zip.FileHeader
  err   error
 }{
  {
   name: "empty args",
   args: fileArgsBuilder(),

   files: []zip.FileHeader{},
  },
  {
   name: "files",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b").
    File("c").
    File(`\[`),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("[", fileEmpty, zip.Store),
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
    fh("c", fileC, zip.Deflate),
   },
  },
  {
   name: "files glob",
   args: fileArgsBuilder().
    SourcePrefixToStrip("a").
    File("a/**/*"),
   compressionLevel: 9,
   storeSymlinks:    true,

   files: []zip.FileHeader{
    fh("a/a", fileA, zip.Deflate),
    fh("a/b", fileB, zip.Deflate),
    fhLink("a/c", "../../c"),
    fhLink("a/d", "b"),
   },
  },
  {
   name: "dir",
   args: fileArgsBuilder().
    SourcePrefixToStrip("a").
    Dir("a"),
   compressionLevel: 9,
   storeSymlinks:    true,

   files: []zip.FileHeader{
    fh("a/a", fileA, zip.Deflate),
    fh("a/b", fileB, zip.Deflate),
    fhLink("a/c", "../../c"),
    fhLink("a/d", "b"),
   },
  },
  {
   name: "stored files",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b").
    File("c"),
   compressionLevel: 0,

   files: []zip.FileHeader{
    fh("a/a/a", fileA, zip.Store),
    fh("a/a/b", fileB, zip.Store),
    fh("c", fileC, zip.Store),
   },
  },
  {
   name: "symlinks in zip",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b").
    File("a/a/c").
    File("a/a/d"),
   compressionLevel: 9,
   storeSymlinks:    true,

   files: []zip.FileHeader{
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
    fhLink("a/a/c", "../../c"),
    fhLink("a/a/d", "b"),
   },
  },
  {
   name: "follow symlinks",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b").
    File("a/a/c").
    File("a/a/d"),
   compressionLevel: 9,
   storeSymlinks:    false,

   files: []zip.FileHeader{
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
    fh("a/a/c", fileC, zip.Deflate),
    fh("a/a/d", fileB, zip.Deflate),
   },
  },
  {
   name: "dangling symlinks",
   args: fileArgsBuilder().
    File("dangling"),
   compressionLevel: 9,
   storeSymlinks:    true,

   files: []zip.FileHeader{
    fhLink("dangling", "missing"),
   },
  },
  {
   name: "list",
   args: fileArgsBuilder().
    List("l_nl"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("[", fileEmpty, zip.Store),
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
    fh("c", fileC, zip.Deflate),
   },
  },
  {
   name: "list",
   args: fileArgsBuilder().
    List("l_sp"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("[", fileEmpty, zip.Store),
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
    fh("c", fileC, zip.Deflate),
   },
  },
  {
   name: "rsp",
   args: fileArgsBuilder().
    RspFile("rsp"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("@", fileC, zip.Deflate),
    fh("[", fileEmpty, zip.Store),
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
    fh("foo'bar", fileC, zip.Deflate),
   },
  },
  {
   name: "prefix in zip",
   args: fileArgsBuilder().
    PathPrefixInZip("foo").
    File("a/a/a").
    File("a/a/b").
    File("c"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("foo/a/a/a", fileA, zip.Deflate),
    fh("foo/a/a/b", fileB, zip.Deflate),
    fh("foo/c", fileC, zip.Deflate),
   },
  },
  {
   name: "relative root",
   args: fileArgsBuilder().
    SourcePrefixToStrip("a").
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("a/a", fileA, zip.Deflate),
    fh("a/b", fileB, zip.Deflate),
   },
  },
  {
   name: "multiple relative root",
   args: fileArgsBuilder().
    SourcePrefixToStrip("a").
    File("a/a/a").
    SourcePrefixToStrip("a/a").
    File("a/a/b"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("a/a", fileA, zip.Deflate),
    fh("b", fileB, zip.Deflate),
   },
  },
  {
   name: "emulate jar",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,
   emulateJar:       true,

   files: []zip.FileHeader{
    fhDir("META-INF/", fhDirOptions{extra: []byte{25420200}}),
    fhManifest(fileManifest),
    fhDir("a/", fhDirOptions{}),
    fhDir("a/a/", fhDirOptions{}),
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
   },
  },
  {
   name: "emulate jar with manifest",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,
   emulateJar:       true,
   manifest:         "manifest.txt",

   files: []zip.FileHeader{
    fhDir("META-INF/", fhDirOptions{extra: []byte{25420200}}),
    fhManifest(customManifestAfter),
    fhDir("a/", fhDirOptions{}),
    fhDir("a/a/", fhDirOptions{}),
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
   },
  },
  {
   name: "dir entries",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,
   dirEntries:       true,

   files: []zip.FileHeader{
    fhDir("a/", fhDirOptions{}),
    fhDir("a/a/", fhDirOptions{}),
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
   },
  },
  {
   name: "junk paths",
   args: fileArgsBuilder().
    JunkPaths(true).
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("a", fileA, zip.Deflate),
    fh("b", fileB, zip.Deflate),
   },
  },
  {
   name: "non deflated files",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,
   nonDeflatedFiles: map[string]bool{"a/a/a": true},

   files: []zip.FileHeader{
    fh("a/a/a", fileA, zip.Store),
    fh("a/a/b", fileB, zip.Deflate),
   },
  },
  {
   name: "ignore missing files",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b").
    File("missing"),
   compressionLevel:   9,
   ignoreMissingFiles: true,

   files: []zip.FileHeader{
    fh("a/a/a", fileA, zip.Deflate),
    fh("a/a/b", fileB, zip.Deflate),
   },
  },
  {
   name: "duplicate sources",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/a"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("a/a/a", fileA, zip.Deflate),
   },
  },
  {
   name: "generate SHA256 checksum",
   args: fileArgsBuilder().
    File("a/a/a").
    File("a/a/b").
    File("a/a/c").
    File("c"),
   compressionLevel: 9,
   sha256Checksum:   true,

   files: []zip.FileHeader{
    fhWithSHA256("a/a/a", fileA, zip.Deflate, sha256FileA),
    fhWithSHA256("a/a/b", fileB, zip.Deflate, sha256FileB),
    fhWithSHA256("a/a/c", fileC, zip.Deflate, sha256FileC),
    fhWithSHA256("c", fileC, zip.Deflate, sha256FileC),
   },
  },
  {
   name: "explicit path",
   args: fileArgsBuilder().
    ExplicitPathInZip("foo").
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("a/a/b", fileB, zip.Deflate),
    fh("foo", fileA, zip.Deflate),
   },
  },
  {
   name: "explicit path with prefix",
   args: fileArgsBuilder().
    PathPrefixInZip("prefix").
    ExplicitPathInZip("foo").
    File("a/a/a").
    File("a/a/b"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("prefix/a/a/b", fileB, zip.Deflate),
    fh("prefix/foo", fileA, zip.Deflate),
   },
  },
  {
   name: "explicit path with glob",
   args: fileArgsBuilder().
    ExplicitPathInZip("foo").
    File("a/a/a*").
    File("a/a/b"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("a/a/b", fileB, zip.Deflate),
    fh("foo", fileA, zip.Deflate),
   },
  },
  {
   name: "explicit path with junk paths",
   args: fileArgsBuilder().
    JunkPaths(true).
    ExplicitPathInZip("foo/bar").
    File("a/a/a*").
    File("a/a/b"),
   compressionLevel: 9,

   files: []zip.FileHeader{
    fh("b", fileB, zip.Deflate),
    fh("foo/bar", fileA, zip.Deflate),
   },
  },

  // errors
  {
   name: "error missing file",
   args: fileArgsBuilder().
    File("missing"),
   err: os.ErrNotExist,
  },
  {
   name: "error missing dir",
   args: fileArgsBuilder().
    Dir("missing"),
   err: os.ErrNotExist,
  },
  {
   name: "error missing file in list",
   args: fileArgsBuilder().
    List("l2"),
   err: os.ErrNotExist,
  },
  {
   name: "error incorrect relative root",
   args: fileArgsBuilder().
    SourcePrefixToStrip("b").
    File("a/a/a"),
   err: IncorrectRelativeRootError{},
  },
  {
   name: "error conflicting file",
   args: fileArgsBuilder().
    SourcePrefixToStrip("a").
    File("a/a/a").
    SourcePrefixToStrip("d").
    File("d/a/a"),
   err: ConflictingFileError{},
  },
  {
   name: "error explicit path conflicting",
   args: fileArgsBuilder().
    ExplicitPathInZip("foo").
    File("a/a/a").
    ExplicitPathInZip("foo").
    File("a/a/b"),
   err: ConflictingFileError{},
  },
  {
   name: "error explicit path conflicting glob",
   args: fileArgsBuilder().
    ExplicitPathInZip("foo").
    File("a/a/*"),
   err: ConflictingFileError{},
  },
 }

 for _, test := range testCases {
  t.Run(test.name, func(t *testing.T) {
   if test.args.Error() != nil {
    t.Fatal(test.args.Error())
   }

   args := ZipArgs{}
   args.FileArgs = test.args.FileArgs()
   args.CompressionLevel = test.compressionLevel
   args.EmulateJar = test.emulateJar
   args.AddDirectoryEntriesToZip = test.dirEntries
   args.NonDeflatedFiles = test.nonDeflatedFiles
   args.ManifestSourcePath = test.manifest
   args.StoreSymlinks = test.storeSymlinks
   args.IgnoreMissingFiles = test.ignoreMissingFiles
   args.Sha256Checksum = test.sha256Checksum
   args.Filesystem = mockFs
   args.Stderr = &bytes.Buffer{}

   buf := &bytes.Buffer{}
   err := zipTo(args, buf)

   if (err != nil) != (test.err != nil) {
    t.Fatalf("want error %v, got %v", test.err, err)
   } else if test.err != nil {
    if os.IsNotExist(test.err) {
     if !os.IsNotExist(err) {
      t.Fatalf("want error %v, got %v", test.err, err)
     }
    } else if _, wantRelativeRootErr := test.err.(IncorrectRelativeRootError); wantRelativeRootErr {
     if _, gotRelativeRootErr := err.(IncorrectRelativeRootError); !gotRelativeRootErr {
      t.Fatalf("want error %v, got %v", test.err, err)
     }
    } else if _, wantConflictingFileError := test.err.(ConflictingFileError); wantConflictingFileError {
     if _, gotConflictingFileError := err.(ConflictingFileError); !gotConflictingFileError {
      t.Fatalf("want error %v, got %v", test.err, err)
     }
    } else {
     t.Fatalf("want error %v, got %v", test.err, err)
    }
    return
   }

   br := bytes.NewReader(buf.Bytes())
   zr, err := zip.NewReader(br, int64(br.Len()))
   if err != nil {
    t.Fatal(err)
   }

   var files []zip.FileHeader
   for _, f := range zr.File {
    r, err := f.Open()
    if err != nil {
     t.Fatalf("error when opening %s: %s", f.Name, err)
    }

    crc := crc32.NewIEEE()
    len, err := io.Copy(crc, r)
    r.Close()
    if err != nil {
     t.Fatalf("error when reading %s: %s", f.Name, err)
    }

    if uint64(len) != f.UncompressedSize64 {
     t.Errorf("incorrect length for %s, want %d got %d", f.Name, f.UncompressedSize64, len)
    }

    if crc.Sum32() != f.CRC32 {
     t.Errorf("incorrect crc for %s, want %x got %x", f.Name, f.CRC32, crc)
    }

    files = append(files, f.FileHeader)
   }

   if len(files) != len(test.files) {
    t.Fatalf("want %d files, got %d", len(test.files), len(files))
   }

   for i := range files {
    want := test.files[i]
    got := files[i]

    if want.Name != got.Name {
     t.Errorf("incorrect file %d want %q got %q", i, want.Name, got.Name)
     continue
    }

    if want.UncompressedSize64 != got.UncompressedSize64 {
     t.Errorf("incorrect file %s length want %v got %v", want.Name,
      want.UncompressedSize64, got.UncompressedSize64)
    }

    if want.ExternalAttrs != got.ExternalAttrs {
     t.Errorf("incorrect file %s attrs want %x got %x", want.Name,
      want.ExternalAttrs, got.ExternalAttrs)
    }

    if want.CRC32 != got.CRC32 {
     t.Errorf("incorrect file %s crc want %v got %v", want.Name,
      want.CRC32, got.CRC32)
    }

    if want.Method != got.Method {
     t.Errorf("incorrect file %s method want %v got %v", want.Name,
      want.Method, got.Method)
    }

    if !bytes.Equal(want.Extra, got.Extra) {
     t.Errorf("incorrect file %s extra want %v got %v", want.Name,
      want.Extra, got.Extra)
    }
   }
  })
 }
}

func TestSrcJar(t *testing.T) {
 mockFs := pathtools.MockFs(map[string][]byte{
  "wrong_package.java":       []byte("package foo;"),
  "foo/correct_package.java": []byte("package foo;"),
  "src/no_package.java":      nil,
  "src2/parse_error.java":    []byte("error"),
 })

 want := []string{
  "foo/",
  "foo/correct_package.java",
  "foo/wrong_package.java",
  "no_package.java",
  "src2/",
  "src2/parse_error.java",
 }

 args := ZipArgs{}
 args.FileArgs = NewFileArgsBuilder().File("**/*.java").FileArgs()

 args.SrcJar = true
 args.AddDirectoryEntriesToZip = true
 args.Filesystem = mockFs
 args.Stderr = &bytes.Buffer{}

 buf := &bytes.Buffer{}
 err := zipTo(args, buf)
 if err != nil {
  t.Fatalf("got error %v", err)
 }

 br := bytes.NewReader(buf.Bytes())
 zr, err := zip.NewReader(br, int64(br.Len()))
 if err != nil {
  t.Fatal(err)
 }

 var got []string
 for _, f := range zr.File {
  r, err := f.Open()
  if err != nil {
   t.Fatalf("error when opening %s: %s", f.Name, err)
  }

  crc := crc32.NewIEEE()
  len, err := io.Copy(crc, r)
  r.Close()
  if err != nil {
   t.Fatalf("error when reading %s: %s", f.Name, err)
  }

  if uint64(len) != f.UncompressedSize64 {
   t.Errorf("incorrect length for %s, want %d got %d", f.Name, f.UncompressedSize64, len)
  }

  if crc.Sum32() != f.CRC32 {
   t.Errorf("incorrect crc for %s, want %x got %x", f.Name, f.CRC32, crc)
  }

  got = append(got, f.Name)
 }

 if !reflect.DeepEqual(want, got) {
  t.Errorf("want files %q, got %q", want, got)
 }
}

[Dauer der Verarbeitung: 0.26 Sekunden, vorverarbeitet 2026-06-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik