I made a small script that zips a file and then encrypts that file:
#-- cut from proc --
set outfile [open $out wb]
set ind [string last \/ $in]
set in [string range $in [expr $ind + 1] end]
zipfile::mkzip::mkzip $in.zip $in
set infile [open $in.zip rb]
if {[catch {blowfish::blowfish -mode $mode -key $key -iv $iv -out $outfile -in $infile} msg]} {
tk_messageBox -message "Error message: $msg"
continue
}
close $infile; close $outfile
#-- end of cut --
To decipher and unzip:
#-- cut from proc --
set outfile [open $out.zip wb]
set infile [open $in rb]
if {[catch {blowfish::blowfish -dir decrypt -mode $mode -key $key -iv $iv -out $outfile -in $infile} msg]} {
tk_messageBox -message "Error message: $msg"
close $outfile
continue
}
close $infile; close $outfile
if {[zipfile::decode::iszip $out.zip] < 1} {
tk_messageBox -message "bad zip file"
file delete -force $out.zip
return
}
zipfile::decode::unzipfile $out.zip $final
file delete -force $out.zip
#-- end of cut --
Now, all works fine, except if the deciphered zip file is bad, meaning that we've used a bad password or mode. I would've thought that catch {blowfish line would get me an error, but apparently blowfish doesn't care, and will just blow garbage into the output file with the .zip extension. In any case, in the case of the bad zip file, the script is not releasing the zip file, and will give me a permission error when trying to delete it. If the zip file is a good file, it will happily unzip and be deleted. I would presume that blowfish has the file locked but won't give an error or let it go. Any help nailing down what I'm doing wrong would be appreciated.
Update: Run the same script on a Linux os at home, and it works. At work on Win10 was the bad behavior, I should've noted that initially.
I've found the
problembug. It's inzipfile::decode::LocateEnd(called byiszipand others), which doesn't close the open file handle to the zip file if it throws an error. I'm not quite what all of the conditions are under which it throws an error, but one is definitely when the ZIP index can't be found. Which would be OK… except that the handle's open and on Windows that means that the file can't be deleted (because having a file open locks its directory entry; Unixes don't typically work that way).It's definitely a bug.
Fortunately it's using a normal Tcl channel, not some kind of complicated C thing, so we can work around it.
In Tcl 8.6, you can do it a bit nicer: