mirror of
https://github.com/Picocrypt/Picocrypt.git
synced 2025-05-17 15:58:32 +02:00
Compare commits
No commits in common. "47b65d6fe0f97ac4b9cc5935048e34eeb9e1d3bf" and "525ee4d591c6a87dd7e7584044dd5c8210fab859" have entirely different histories.
47b65d6fe0
...
525ee4d591
1 changed files with 40 additions and 48 deletions
|
@ -120,8 +120,7 @@ var splitSelected int32 = 1
|
||||||
var recombine bool
|
var recombine bool
|
||||||
var compress bool
|
var compress bool
|
||||||
var delete bool
|
var delete bool
|
||||||
var autoUnzip bool
|
var unpack bool
|
||||||
var sameLevel bool
|
|
||||||
var keep bool
|
var keep bool
|
||||||
var kept bool
|
var kept bool
|
||||||
|
|
||||||
|
@ -556,19 +555,8 @@ func draw() {
|
||||||
).Build()
|
).Build()
|
||||||
|
|
||||||
giu.Row(
|
giu.Row(
|
||||||
giu.Style().SetDisabled(!strings.HasSuffix(inputFile, ".zip.pcv")).To(
|
giu.Checkbox("Unpack .zip", &unpack),
|
||||||
giu.Checkbox("Auto unzip", &autoUnzip).OnChange(func() {
|
giu.Tooltip("Extract the decrypted .zip (overwrite files)"),
|
||||||
if !autoUnzip {
|
|
||||||
sameLevel = false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
giu.Tooltip("Extract .zip upon decryption (may overwrite)"),
|
|
||||||
),
|
|
||||||
giu.Dummy(-170, 0),
|
|
||||||
giu.Style().SetDisabled(!autoUnzip).To(
|
|
||||||
giu.Checkbox("Same level", &sameLevel),
|
|
||||||
giu.Tooltip("Extract .zip contents to same folder as volume"),
|
|
||||||
),
|
|
||||||
).Build()
|
).Build()
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
@ -2130,21 +2118,29 @@ func work() {
|
||||||
os.Remove(inputFile)
|
os.Remove(inputFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if mode == "decrypt" && !kept && autoUnzip {
|
if mode == "decrypt" && !kept && unpack {
|
||||||
showProgress = true
|
showProgress = true // Turn on the progress popup
|
||||||
popupStatus = "Unzipping..."
|
canCancel = true // Allow the user to cancel
|
||||||
|
progress = 0
|
||||||
|
progressInfo = ""
|
||||||
|
popupStatus = "Preparing to unpack..."
|
||||||
giu.Update()
|
giu.Update()
|
||||||
|
|
||||||
if err := unpackArchive(outputFile); err != nil {
|
err := unpackArchive(outputFile)
|
||||||
mainStatus = "Auto unzipping failed!"
|
if err != nil {
|
||||||
|
mainStatus = "Extraction failed: " + err.Error()
|
||||||
mainStatusColor = RED
|
mainStatusColor = RED
|
||||||
giu.Update()
|
giu.Update()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
os.Remove(outputFile)
|
// Turn off the progress UI
|
||||||
|
showProgress = false
|
||||||
|
canCancel = false
|
||||||
|
progress = 0
|
||||||
|
progressInfo = ""
|
||||||
|
popupStatus = ""
|
||||||
|
giu.Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// All done, reset the UI
|
// All done, reset the UI
|
||||||
oldKept := kept
|
oldKept := kept
|
||||||
resetUI()
|
resetUI()
|
||||||
|
@ -2242,8 +2238,7 @@ func resetUI() {
|
||||||
recombine = false
|
recombine = false
|
||||||
compress = false
|
compress = false
|
||||||
delete = false
|
delete = false
|
||||||
autoUnzip = false
|
unpack = false
|
||||||
sameLevel = false
|
|
||||||
keep = false
|
keep = false
|
||||||
kept = false
|
kept = false
|
||||||
|
|
||||||
|
@ -2366,31 +2361,33 @@ func sizeify(size int64) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func unpackArchive(zipPath string) error {
|
func unpackArchive(zipPath string) error {
|
||||||
|
// Open the .zip
|
||||||
reader, err := zip.OpenReader(zipPath)
|
reader, err := zip.OpenReader(zipPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer reader.Close()
|
defer reader.Close()
|
||||||
|
|
||||||
|
// Calculate total unpack size by summing each entry’s UncompressedSize64
|
||||||
var totalSize int64
|
var totalSize int64
|
||||||
for _, f := range reader.File {
|
for _, f := range reader.File {
|
||||||
totalSize += int64(f.UncompressedSize64)
|
totalSize += int64(f.UncompressedSize64)
|
||||||
}
|
}
|
||||||
|
|
||||||
var extractDir string
|
// Directory containing the .zip
|
||||||
if sameLevel {
|
extractDir := filepath.Dir(zipPath)
|
||||||
extractDir = filepath.Dir(zipPath)
|
|
||||||
} else {
|
|
||||||
extractDir = filepath.Join(filepath.Dir(zipPath), strings.TrimSuffix(filepath.Base(zipPath), ".zip"))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Setup progress tracking
|
||||||
var done int64
|
var done int64
|
||||||
startTime := time.Now()
|
startTime := time.Now()
|
||||||
|
|
||||||
for _, f := range reader.File {
|
// Iterate over each file in the archive
|
||||||
if strings.Contains(f.Name, "..") {
|
for i, f := range reader.File {
|
||||||
return errors.New("potentially malicious zip item path")
|
// If user clicked "Cancel" elsewhere, stop
|
||||||
|
if !working {
|
||||||
|
return errors.New("operation canceled by user")
|
||||||
}
|
}
|
||||||
|
|
||||||
outPath := filepath.Join(extractDir, f.Name)
|
outPath := filepath.Join(extractDir, f.Name)
|
||||||
|
|
||||||
// Make directory if current entry is a folder
|
// Make directory if current entry is a folder
|
||||||
|
@ -2398,21 +2395,9 @@ func unpackArchive(zipPath string) error {
|
||||||
if err := os.MkdirAll(outPath, f.Mode()); err != nil {
|
if err := os.MkdirAll(outPath, f.Mode()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, f := range reader.File {
|
|
||||||
if strings.Contains(f.Name, "..") {
|
|
||||||
return errors.New("potentially malicious zip item path")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Already handled above
|
|
||||||
if f.FileInfo().IsDir() {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
outPath := filepath.Join(extractDir, f.Name)
|
|
||||||
|
|
||||||
// Otherwise create necessary parent directories
|
// Otherwise create necessary parent directories
|
||||||
if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(outPath), 0755); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -2425,14 +2410,20 @@ func unpackArchive(zipPath string) error {
|
||||||
}
|
}
|
||||||
defer fileInArchive.Close()
|
defer fileInArchive.Close()
|
||||||
|
|
||||||
dstFile, err := os.Create(outPath)
|
// Create/overwrite the destination file
|
||||||
|
dstFile, err := os.OpenFile(outPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read from zip in chunks to update progress
|
// Read from zip in chunks to update progress
|
||||||
buffer := make([]byte, MiB)
|
buffer := make([]byte, MiB) // e.g., 1 MiB chunk
|
||||||
for {
|
for {
|
||||||
|
if !working {
|
||||||
|
dstFile.Close()
|
||||||
|
os.Remove(outPath) // remove partial extraction if canceled
|
||||||
|
return errors.New("operation canceled by user")
|
||||||
|
}
|
||||||
n, readErr := fileInArchive.Read(buffer)
|
n, readErr := fileInArchive.Read(buffer)
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
_, writeErr := dstFile.Write(buffer[:n])
|
_, writeErr := dstFile.Write(buffer[:n])
|
||||||
|
@ -2441,6 +2432,7 @@ func unpackArchive(zipPath string) error {
|
||||||
return writeErr
|
return writeErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update "done" and recalc progress, speed, eta
|
||||||
done += int64(n)
|
done += int64(n)
|
||||||
progress, speed, eta = statify(done, totalSize, startTime)
|
progress, speed, eta = statify(done, totalSize, startTime)
|
||||||
progressInfo = fmt.Sprintf("%d/%d", i+1, len(reader.File))
|
progressInfo = fmt.Sprintf("%d/%d", i+1, len(reader.File))
|
||||||
|
|
Loading…
Add table
Reference in a new issue