Example #1
0
func (s *ZipSuite) TestExtractSymlinkErrors(c *gc.C) {
	for i, test := range []struct {
		content []ft.Entry
		source  string
		error   string
	}{{
		content: []ft.Entry{
			ft.Dir{"dir", 0755},
			ft.Symlink{"dir/symlink", "/blah"},
		},
		source: "dir",
		error:  `cannot extract "dir/symlink": symlink "/blah" is absolute`,
	}, {
		content: []ft.Entry{
			ft.Dir{"dir", 0755},
			ft.Symlink{"dir/symlink", "../blah"},
		},
		source: "dir",
		error:  `cannot extract "dir/symlink": symlink "../blah" leads out of scope`,
	}, {
		content: []ft.Entry{
			ft.Symlink{"symlink", "blah"},
		},
		source: "symlink",
		error:  `cannot extract "symlink": symlink "blah" leads out of scope`,
	}} {
		c.Logf("test %d: %s", i, test.error)
		targetPath := c.MkDir()
		reader := s.makeZip(c, test.content...)
		err := zip.Extract(reader, targetPath, test.source)
		c.Check(err, gc.ErrorMatches, test.error)
	}
}
Example #2
0
// processUploadedArchive opens the given charm archive from path,
// inspects it to see if it has all files at the root of the archive
// or it has subdirs. It repackages the archive so it has all the
// files at the root dir, if necessary, replacing the original archive
// at path.
func (h *charmsHandler) processUploadedArchive(path string) error {
	// Open the archive as a zip.
	f, err := os.OpenFile(path, os.O_RDWR, 0644)
	if err != nil {
		return err
	}
	defer f.Close()
	fi, err := f.Stat()
	if err != nil {
		return err
	}
	zipr, err := zip.NewReader(f, fi.Size())
	if err != nil {
		return errors.Annotate(err, "cannot open charm archive")
	}

	// Find out the root dir prefix from the archive.
	rootDir, err := h.findArchiveRootDir(zipr)
	if err != nil {
		return errors.Annotate(err, "cannot read charm archive")
	}
	if rootDir == "." {
		// Normal charm, just use charm.ReadCharmArchive).
		return nil
	}

	// There is one or more subdirs, so we need extract it to a temp
	// dir and then read it as a charm dir.
	tempDir, err := ioutil.TempDir("", "charm-extract")
	if err != nil {
		return errors.Annotate(err, "cannot create temp directory")
	}
	defer os.RemoveAll(tempDir)
	if err := ziputil.Extract(zipr, tempDir, rootDir); err != nil {
		return errors.Annotate(err, "cannot extract charm archive")
	}
	dir, err := charm.ReadCharmDir(tempDir)
	if err != nil {
		return errors.Annotate(err, "cannot read extracted archive")
	}

	// Now repackage the dir as a bundle at the original path.
	if err := f.Truncate(0); err != nil {
		return err
	}
	if err := dir.ArchiveTo(f); err != nil {
		return err
	}
	return nil
}
Example #3
0
func (s *ZipSuite) TestExtractSingleFile(c *gc.C) {
	reader := s.makeZip(c,
		ft.Dir{"dir", 0755},
		ft.Dir{"dir/dir", 0755},
		ft.File{"dir/dir/some-file", "content 1", 0644},
		ft.File{"dir/dir/some-file-wtf", "content 2", 0644},
	)
	targetParent := c.MkDir()
	targetPath := filepath.Join(targetParent, "just-the-one-file")
	err := zip.Extract(reader, targetPath, "dir/dir/some-file")
	c.Assert(err, gc.IsNil)
	fileInfos, err := ioutil.ReadDir(targetParent)
	c.Check(err, gc.IsNil)
	c.Check(fileInfos, gc.HasLen, 1)
	ft.File{"just-the-one-file", "content 1", 0644}.Check(c, targetParent)
}
Example #4
0
func (s *ZipSuite) TestExtractDir(c *gc.C) {
	reader := s.makeZip(c,
		ft.File{"bad-file", "xxx", 0644},
		ft.Dir{"bad-dir", 0755},
		ft.Symlink{"bad-symlink", "bad-file"},
		ft.Dir{"some-dir", 0751},
		ft.File{"some-dir-bad-lol", "xxx", 0644},
		ft.File{"some-dir/some-file", "content 1", 0644},
		ft.File{"some-dir/another-file", "content 2", 0600},
		ft.Dir{"some-dir/another-dir", 0750},
		ft.Symlink{"some-dir/another-dir/some-symlink", "../some-file"},
	)
	targetParent := c.MkDir()
	targetPath := filepath.Join(targetParent, "random-dir")
	err := zip.Extract(reader, targetPath, "some-dir")
	c.Assert(err, gc.IsNil)

	for i, test := range []ft.Entry{
		ft.Dir{"random-dir", 0751},
		ft.File{"random-dir/some-file", "content 1", 0644},
		ft.File{"random-dir/another-file", "content 2", 0600},
		ft.Dir{"random-dir/another-dir", 0750},
		ft.Symlink{"random-dir/another-dir/some-symlink", "../some-file"},
	} {
		c.Logf("test %d: %#v", i, test)
		test.Check(c, targetParent)
	}

	fileInfos, err := ioutil.ReadDir(targetParent)
	c.Check(err, gc.IsNil)
	c.Check(fileInfos, gc.HasLen, 1)

	fileInfos, err = ioutil.ReadDir(targetPath)
	c.Check(err, gc.IsNil)
	c.Check(fileInfos, gc.HasLen, 3)
}
Example #5
0
func (s *ZipSuite) TestExtractSourceError(c *gc.C) {
	reader := s.makeZip(c, ft.Dir{"dir", 0755})
	err := zip.Extract(reader, c.MkDir(), "../lol")
	c.Assert(err, gc.ErrorMatches, `cannot extract files rooted at "../lol"`)
}