How to set binary-flag in Zip-file with rubyzip? - ruby

I received a complain about a zip file I created with rubyzip 1.2.0:
The text flag for text.pdf corrupted the pdf after unpacking.
I create the zip under windows, the recipient works with Unix/Linux.
You can see the flag with zipinfo (or unzip -Z with windows).
unzip -Z -l test.zip results with:
Archive: test.zip
Zip file size: 1666 bytes, number of entries: 2
-rw---- 5.2 fat 1521 t- 730 defN 16-Sep-30 23:37 test.dtx
-rw---- 5.2 fat 1521 t- 730 defN 16-Sep-30 23:37 test.pdf
2 files, 3042 bytes uncompressed, 1460 bytes compressed: 52.0%
+
+--- This is the t-flag
This is the related testcode:
require "zip"
###add here my patch####
Zip::File.open('test.zip', Zip::File::CREATE) do |zipfile|
%w{
test.dtx
test.pdf
}.each{|filename|
file = begin
#I use __FILE__, so you can run this example out of the box.
#My original code uses the dtx and pdf file.
zipfile.add(filename, __FILE__) #Zip::ZipEntryExistsError if already in zip
rescue Zip::EntryExistsError
zipfile.replace(filename, __FILE__)
end
#This is part of my work around
file.internal_file_attributes = 0 if filename =~ /pdf$/ and file.respond_to?(:internal_file_attributes)
}
end #Zip::ZipFile.open
I checked the source code of Zip::Entry and found the definition of
#internal_file_attributes = 1, but no possibility to influence this value.
Based on this information, I made a patch Zip::Entry like this:
module Zip
class Entry
#my work around to set #internal_file_attributes
attr_accessor :internal_file_attributes
end
end
When I add this patch in my test code above, then I get:
Archive: test.zip
Zip file size: 1726 bytes, number of entries: 2
-rw---- 5.2 fat 1666 t- 760 defN 16-Sep-30 23:40 test.dtx
-rw---- 5.2 fat 1666 b- 760 defN 16-Sep-30 23:40 test.pdf
2 files, 3332 bytes uncompressed, 1520 bytes compressed: 54.4%
+
+--- There is a b-flag for the pdf
So I found a work around for my problem - but is there another and better solution?
Is there a possibility to set the binary flag during adding the file?

Related

Oracle FORMS 12C - Generate password protected file from oracle forms application with CLIENT_TEXT_IO webutil

We have an application in Oracle forms. From a form, we generate a .TXT file with some data. Now we are looking for options to generate a password protected file (preferrably zip file as .TXT cannot be password protected directly)
We use CLIENT_TEXT_IO to write data into file and close.
Is it possible to generate password protected zip file with CLIENT_TEXT_IO webutil?
U_IN_FILE := CLIENT_TEXT_IO.FOPEN (:M_FILE_PATH || 'some data.TXT','w');
CLIENT_TEXT_IO.PUT_LINE(U_IN_FILE,'some data');
CLIENT_TEXT_IO.FCLOSE (U_IN_FILE);
I presume you'd do that in two steps:
create .txt file the way you're already doing it
use CLIENT_HOST to invoke command-line ZIP utility and create a password-protected ZIP file
For example, on my MS Windows, using 7-zip, it would look like this:
c:\Temp\ZIP>"C:\Program Files\7-Zip\7z" a zipped_file.7z test.txt -pMARCH18
7-Zip 19.00 (x64) : Copyright (c) 1999-2018 Igor Pavlov : 2019-02-21
Scanning the drive:
1 file, 66 bytes (1 KiB)
Creating archive: zipped_file.7z
Add new data to archive: 1 file, 66 bytes (1 KiB)
Files read from disk: 1
Archive size: 202 bytes (1 KiB)
Everything is Ok
c:\Temp\ZIP>
ZIP command itself, explained:
7z a zipped_file.7z test.txt -pMARCH18
7z - invokes the utility
a - add to archive
zipped_file.7z - ZIP file name
test.txt - this is the file I'm going to ZIP
-pMARCH18 - password is MARCH18
Regarding the error calling Winzip, refer to these MyOracleSupport Notes:
1568659.1
1547133.1
In short, you will need to escape some of the characters in your call.

Microsoft Custom Translator: "The document '._..._...txt' is not a valid text file as it contains one or more invalid characters"

When using the zip file format to combine two parallel files, after data file upload we get the error message:
The document '._{name}_{lang}.txt' is not a valid {type} file as it contains one or more invalid characters.
The issue is that MacOS includes system files in the ZIP archive, and Microsoft tries to read them as data files because of the language suffix and .txt extension.
unzip -l data1.zip
Archive: data1.zip
Length Date Time Name
--------- ---------- ----- ----
0 04-09-2020 00:57 data1/
108746839 04-08-2020 23:55 data1/data_en.txt
120 04-08-2020 23:55 __MACOSX/data1/._data_en.txt
126795036 04-08-2020 23:56 data1/data_de.txt
120 04-08-2020 23:56 __MACOSX/data1/._data_de.txt
--------- -------
235542115 5 files
The fix is to compress them in a way that they are not added, or just remove them:
zip -d data1.zip __MACOSX*
zip -d data1.zip __DS_Store*
See https://apple.stackexchange.com/questions/239578/compress-without-ds-store-and-macosx, Mac zip compress without __MACOSX folder?...
Thanks to #ScottG for debugging.

How to copy filename with tilde in Windows 7?

I have a DVD which should be burnt in year 2009. In a directory there are 2 files. File-1 is named abc~1.TXT with size 512 KB. File-2 is named abcdefg.txt with size 43 KB.
Now using Win7, when I try to copy file-1 to my hard-disk, it will actually copy the data content of file-2. The file name in hard-disk is the file name of file-1, but the size is 43 KB and the content is the same as file-2.
When I open file-1 in the DVD using notepad++, the content is the content of file-2. Also, look like there is not 512 KB.
I also try the copy command in CMD prompt, but no luck, same behavior.
I also try to use 7zip to zip file-1, again 43 KB (not 512 KB) is zipped inside the zip file.
I search the internet. Some tell me that file-1 may be the short file name situation working in Win NT.
My questions are :
How can I PROVE that file-1 is the short file name of file-2 ? In this case, how can I look at the CONTENT of this 512 KB ? There is no debug command in Win7 to look at the 512 KB byte-by-byte.
How about, if file-1 is NOT the short file name of file-2, how can I copy the TRUE CONTENT of file-1 (i.e. the 512 KB file content) to the hard-disk ?
Thanks in advance.
Alvin SIU

openssl on Windows does not recoginize my -extfile

When using OpenSSL 1.0.2l, I have the following command line:
openssl ca -out certs\cert.pem -days 1825 -config openssl.cnf -infiles requests\req.pem -extfile "v3.ext"
I have the v3.ext file in the current directory:
>dir v3.ext
Volume in drive C is OS
Volume Serial Number is 1E1A-0C21
Directory of C:\Users\[me]\.openssl
06/12/2017 10:58 AM 205 v3.ext
1 File(s) 205 bytes
0 Dir(s) 116,381,810,688 bytes free
When I run it, I get this error message:
-extfile: No such file or directory
8932:error:02001002:system library:fopen:No such file or directory:.\crypto\bio\bss_file.c:406:fopen('-extfile','rb')
8932:error:20074002:BIO routines:FILE_CTRL:system lib:.\crypto\bio\bss_file.c:408:
This is a Windows 10 box. Is anything wrong with my Extfile option?
Thanks
The "-extfile" option should be earlier in the list of options. From the ca man page (https://www.openssl.org/docs/man3.0/man1/openssl-ca.html):
-infiles
if present this should be the last option, all subsequent arguments are
assumed to the the names of files containing certificate requests.
So your "-extfile" argument is being taken as a request file.

How to determine compression method of a ZIP/RAR file

I have a few zip and rar files that I'm working with, and I'm trying to analyze the properties of how each file was compressed (compression level, compression algorithm (e.g. deflate, LZMA, BZip2), dictionary size, word size, etc.), and I haven't figured out a way to do this yet.
Is there any way to analyze the files to determine these properties, with software or otherwise?
Cheers and thanks!
This is a fairly old question, but I wanted to throw in my two cents anyway since some of the methods above weren't as easy for me to use.
You can also determine this with 7-Zip. After opening the archive there is a column for method of compression:
For ZIP - yes, zipinfo
For RAR, the headers are easily found with either 7Zip or WinRAR, read the attached documentation
Via 7-Zip (or p7zip) command line:
7z l -slt archive.file
If looking specifically for the compression method:
7z l -slt archive.file | grep -e '^---' -e '^Path =' -e '^Method ='
I suggest hachoir-wx to have a look at these files. How to install a Python package or you can try ActivePython with PyPM when using Windows. When you have the necessary hachoir packages installed, you can do something like this to run the GUI:
python C:\Python27\Scripts\hachoir-wx
It enables you to browse through the data fields of RAR and ZIP files. See this screenshot for an example.
For RAR files, have a look at the technote.txt file that is in the WinRAR installation directory. This gives detailed information of the RAR specification. You will probably be interested in these:
HEAD_FLAGS Bit flags: 2 bytes
0x10 - information from previous files is used (solid flag)
bits 7 6 5 (for RAR 2.0 and later)
0 0 0 - dictionary size 64 KB
0 0 1 - dictionary size 128 KB
0 1 0 - dictionary size 256 KB
0 1 1 - dictionary size 512 KB
1 0 0 - dictionary size 1024 KB
1 0 1 - dictionary size 2048 KB
1 1 0 - dictionary size 4096 KB
1 1 1 - file is directory
Dictionary size can be found in the WinRAR GUI too.
METHOD Packing method 1 byte
0x30 - storing
0x31 - fastest compression
0x32 - fast compression
0x33 - normal compression
0x34 - good compression
0x35 - best compression
And Wikipedia also knows this:
The RAR compression utility is proprietary, with a closed algorithm. RAR is owned by Alexander L. Roshal, the elder brother of Eugene Roshal. Version 3 of RAR is based on Lempel-Ziv (LZSS) and prediction by partial matching (PPM) compression, specifically the PPMd implementation of PPMII by Dmitry Shkarin.
For ZIP files I would start by having a look at the specifications and the ZIP Wikipedia page. These are probably interesting:
general purpose bit flag: (2 bytes)
compression method: (2 bytes)
For the ZIP files, there is a command zipinfo.
The zipfile python module can be used to get info about the zipfile.
The ZipInfo class provides information like filename, compress_type, compress_size, file_size etc...
Python snippet to get filename and the compress type of files in a zip archive
import zipfile
with zipfile.ZipFile(path_to_zipfile, 'r') as zip:
for info in zip.infolist():
print(f'filename: {info.filename}')
print(f'compress type: {info.compress_type}')
This would list all the filenames and their corresponding compression type(integer), which can be used to look up the compression method.
You can get a lot more info about the files using infolist().
The python module linked in the accepted answer is not available, zipfile module might help
The type is easy, just look at the file headers (PK and Rar).
As for the rest, I doubt that information is available in the compressed content.

Resources