Skip to content

Commit

Permalink
Merge pull request #142 from nabbar/pkg_archive
Browse files Browse the repository at this point in the history
Package Archive:
- Security : clean destination pathfile before use it (prevent down under current output path)
- Fix : do not update link / symlink if the source / destination are same
- Fix : do not create link / symlink for windows OS (need a shortcut process by ole call)

Other
- Bump dependencies
- Fix #128 
- Fix #129 
- Fix #130 
- Fix #131
  • Loading branch information
nabbar authored Oct 28, 2022
2 parents db6fd4f + da68aa4 commit cdc829a
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 103 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
Expand All @@ -53,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
Expand All @@ -67,4 +67,4 @@ jobs:
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2
8 changes: 4 additions & 4 deletions archive/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,28 +64,28 @@ func ExtractFile(src, dst libiot.FileProgress, fileNameContain, fileNameRegex st
// #nosec
}

if err := libbz2.GetFile(src, tmp); err == nil {
if err = libbz2.GetFile(src, tmp); err == nil {
//logger.DebugLevel.Log("try another archive...")
return ExtractFile(tmp, dst, fileNameContain, fileNameRegex)
} else if err.IsCodeError(libbz2.ErrorIOCopy) {
return err
}

if err := libgzp.GetFile(src, tmp); err == nil {
if err = libgzp.GetFile(src, tmp); err == nil {
//logger.DebugLevel.Log("try another archive...")
return ExtractFile(tmp, dst, fileNameContain, fileNameRegex)
} else if !err.IsCodeError(libgzp.ErrorGZReader) {
return err
}

if err := libtar.GetFile(src, tmp, fileNameContain, fileNameRegex); err == nil {
if err = libtar.GetFile(src, tmp, fileNameContain, fileNameRegex); err == nil {
//logger.DebugLevel.Log("try another archive...")
return ExtractFile(tmp, dst, fileNameContain, fileNameRegex)
} else if !err.IsCodeError(libtar.ErrorTarNext) {
return err
}

if err := libzip.GetFile(src, tmp, fileNameContain, fileNameRegex); err == nil {
if err = libzip.GetFile(src, tmp, fileNameContain, fileNameRegex); err == nil {
//logger.DebugLevel.Log("try another archive...")
return ExtractFile(tmp, dst, fileNameContain, fileNameRegex)
} else if !err.IsCodeError(libzip.ErrorZipOpen) {
Expand Down
117 changes: 85 additions & 32 deletions archive/tar/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@ import (
"io"
"os"
"path"
"syscall"
"path/filepath"
"runtime"
"strings"

"github.com/nabbar/golib/archive/archive"
"github.com/nabbar/golib/errors"
"github.com/nabbar/golib/ioutils"
libarc "github.com/nabbar/golib/archive/archive"
liberr "github.com/nabbar/golib/errors"
libiut "github.com/nabbar/golib/ioutils"
)

func GetFile(src, dst ioutils.FileProgress, filenameContain, filenameRegex string) errors.Error {
func GetFile(src, dst libiut.FileProgress, filenameContain, filenameRegex string) liberr.Error {

if _, e := src.Seek(0, io.SeekStart); e != nil {
return ErrorFileSeek.ErrorParent(e)
Expand All @@ -59,14 +61,14 @@ func GetFile(src, dst ioutils.FileProgress, filenameContain, filenameRegex strin
continue
}

f := archive.NewFileFullPath(h.Name)
f := libarc.NewFileFullPath(h.Name)

//nolint #nosec
/* #nosec */
if f.MatchingFullPath(filenameContain) || f.RegexFullPath(filenameRegex) {
if _, e := dst.ReadFrom(r); e != nil {
if _, e = dst.ReadFrom(r); e != nil {
return ErrorIOCopy.ErrorParent(e)
} else if _, e := dst.Seek(0, io.SeekStart); e != nil {
} else if _, e = dst.Seek(0, io.SeekStart); e != nil {
return ErrorFileSeek.ErrorParent(e)
} else {
return nil
Expand All @@ -75,7 +77,7 @@ func GetFile(src, dst ioutils.FileProgress, filenameContain, filenameRegex strin
}
}

func GetAll(src io.ReadSeeker, outputFolder string, defaultDirPerm os.FileMode) errors.Error {
func GetAll(src io.ReadSeeker, outputFolder string, defaultDirPerm os.FileMode) liberr.Error {

if _, e := src.Seek(0, io.SeekStart); e != nil {
return ErrorFileSeek.ErrorParent(e)
Expand All @@ -93,16 +95,16 @@ func GetAll(src io.ReadSeeker, outputFolder string, defaultDirPerm os.FileMode)

//nolint #nosec
/* #nosec */
if err := writeContent(r, h, path.Join(outputFolder, h.Name), defaultDirPerm); err != nil {
if err := writeContent(r, h, path.Join(outputFolder, path.Clean(h.Name)), defaultDirPerm); err != nil {
return err
}
}
}

func writeContent(r io.Reader, h *tar.Header, out string, defaultDirPerm os.FileMode) (err errors.Error) {
func writeContent(r io.Reader, h *tar.Header, out string, defaultDirPerm os.FileMode) (err liberr.Error) {
var (
inf = h.FileInfo()
dst ioutils.FileProgress
dst libiut.FileProgress
)

if e := dirIsExistOrCreate(path.Dir(out), defaultDirPerm); e != nil {
Expand All @@ -121,34 +123,26 @@ func writeContent(r io.Reader, h *tar.Header, out string, defaultDirPerm os.File
if h.Typeflag&tar.TypeDir == tar.TypeDir {
err = dirIsExistOrCreate(out, h.FileInfo().Mode())
return
} else if err = notDirExistCannotClean(out); err != nil {
} else if err = notDirExistCannotClean(out, h.Typeflag, h.Linkname); err != nil {
return
} else if h.Typeflag&tar.TypeLink == tar.TypeLink {
e := os.Link(h.Linkname, out)
if e != nil {
err = ErrorLinkCreate.ErrorParent(e)
}
return
return createLink(out, path.Clean(h.Linkname), false)
} else if h.Typeflag&tar.TypeSymlink == tar.TypeSymlink {
e := os.Symlink(h.Linkname, out)
if e != nil {
err = ErrorSymLinkCreate.ErrorParent(e)
}
return
return createLink(out, path.Clean(h.Linkname), true)
}

if dst, err = ioutils.NewFileProgressPathWrite(out, true, true, inf.Mode()); err != nil {
if dst, err = libiut.NewFileProgressPathWrite(out, true, true, inf.Mode()); err != nil {
return ErrorFileOpen.Error(err)
} else if _, e := io.Copy(dst, r); e != nil {
return ErrorIOCopy.ErrorParent(e)
} else if e := dst.Close(); e != nil {
} else if e = dst.Close(); e != nil {
return ErrorFileClose.ErrorParent(e)
}

return nil
}

func dirIsExistOrCreate(dirname string, dirPerm os.FileMode) errors.Error {
func dirIsExistOrCreate(dirname string, dirPerm os.FileMode) liberr.Error {
if i, e := os.Stat(dirname); e != nil && os.IsNotExist(e) {
if e = os.MkdirAll(dirname, dirPerm); e != nil {
return ErrorDirCreate.ErrorParent(e)
Expand All @@ -162,20 +156,79 @@ func dirIsExistOrCreate(dirname string, dirPerm os.FileMode) errors.Error {
return nil
}

func notDirExistCannotClean(filename string) errors.Error {
func notDirExistCannotClean(filename string, flag byte, targetLink string) liberr.Error {
if strings.EqualFold(runtime.GOOS, "windows") {
if flag&tar.TypeLink == tar.TypeLink {
return nil
} else if flag&tar.TypeSymlink == tar.TypeSymlink {
return nil
}
}

if _, e := os.Stat(filename); e != nil && os.IsNotExist(e) {
return nil
} else if e != nil {
return ErrorDestinationStat.ErrorParent(e)
} else if e = os.Remove(filename); e != nil {
err := ErrorDestinationRemove.ErrorParent(e)

if e = syscall.Rmdir(filename); e != nil {
err.AddParentError(ErrorDestinationIsDir.ErrorParent(e))
} else if flag&tar.TypeLink == tar.TypeLink || flag&tar.TypeSymlink == tar.TypeSymlink {
if hasFSLink(filename) && compareLinkTarget(filename, targetLink) {
return nil
}
}

if e := os.Remove(filename); e != nil {
err := ErrorDestinationRemove.ErrorParent(e)
return err
}

return nil
}

func hasFSLink(path string) bool {
link, _ := filepath.EvalSymlinks(path)

if link != "" {
return true
}

return false
}

func createLink(link, target string, sym bool) liberr.Error {
if strings.EqualFold(runtime.GOOS, "windows") {
return nil
}

if _, e := os.Stat(link); e != nil && !os.IsNotExist(e) {
return ErrorDestinationStat.ErrorParent(e)
} else if e == nil {
return nil
} else if compareLinkTarget(link, target) {
return nil
}

if sym {
err := os.Symlink(path.Clean(target), path.Clean(link))
if err != nil {
return ErrorLinkCreate.ErrorParent(err)
}
} else {
err := os.Link(path.Clean(target), path.Clean(link))
if err != nil {
return ErrorLinkCreate.ErrorParent(err)
}
}

return nil
}

func compareLinkTarget(link, target string) bool {
var l string

l, _ = filepath.EvalSymlinks(link)

if l == "" {
return false
}

return strings.EqualFold(path.Clean(l), path.Clean(target))
}
31 changes: 17 additions & 14 deletions archive/zip/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,28 @@ import (

func GetFile(src, dst ioutils.FileProgress, filenameContain, filenameRegex string) errors.Error {
var (
r *zip.Reader
i os.FileInfo
e error
arc *zip.Reader
inf os.FileInfo
err error
)

if _, e = src.Seek(0, io.SeekStart); e != nil {
return ErrorFileSeek.ErrorParent(e)
} else if _, e = dst.Seek(0, io.SeekStart); e != nil {
return ErrorFileSeek.ErrorParent(e)
} else if i, e = src.FileStat(); e != nil {
return ErrorFileStat.ErrorParent(e)
} else if r, e = zip.NewReader(src, i.Size()); e != nil {
return ErrorZipOpen.ErrorParent(e)
if _, err = src.Seek(0, io.SeekStart); err != nil {
return ErrorFileSeek.ErrorParent(err)
} else if _, err = dst.Seek(0, io.SeekStart); err != nil {
return ErrorFileSeek.ErrorParent(err)
} else if inf, err = src.FileStat(); err != nil {
return ErrorFileStat.ErrorParent(err)
} else if arc, err = zip.NewReader(src, inf.Size()); err != nil {
return ErrorZipOpen.ErrorParent(err)
}

for _, f := range r.File {
for _, f := range arc.File {
if f.Mode()&os.ModeType == os.ModeType {
continue
}

z := archive.NewFileFullPath(f.Name)

if z.MatchingFullPath(filenameContain) || z.RegexFullPath(filenameRegex) {
if f == nil {
continue
Expand Down Expand Up @@ -119,7 +120,7 @@ func GetAll(src ioutils.FileProgress, outputFolder string, defaultDirPerm os.Fil

//nolint #nosec
/* #nosec */
if err := writeContent(f, path.Join(outputFolder, f.Name), defaultDirPerm); err != nil {
if err := writeContent(f, path.Join(outputFolder, path.Clean(f.Name)), defaultDirPerm); err != nil {
return err
}
}
Expand Down Expand Up @@ -157,6 +158,8 @@ func writeContent(f *zip.File, out string, defaultDirPerm os.FileMode) (err erro
if inf.IsDir() {
err = dirIsExistOrCreate(out, inf.Mode())
return
} else if inf.Mode()&os.ModeSymlink == os.ModeSymlink {
return nil
} else if err = notDirExistCannotClean(out); err != nil {
return
}
Expand All @@ -169,7 +172,7 @@ func writeContent(f *zip.File, out string, defaultDirPerm os.FileMode) (err erro

//nolint #nosec
/* #nosec */
if _, e := io.Copy(dst, r); e != nil {
if _, e = io.Copy(dst, r); e != nil {
return ErrorIOCopy.ErrorParent(e)
} else if e = dst.Close(); e != nil {
return ErrorFileClose.ErrorParent(e)
Expand Down
Loading

0 comments on commit cdc829a

Please sign in to comment.