-
Notifications
You must be signed in to change notification settings - Fork 24
/
checkfileextwdx.lua
203 lines (193 loc) · 6.55 KB
/
checkfileextwdx.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
-- checkfileextwdx.lua (cross-platform)
-- 2021.09.07
--[[
Checking that the file extension matches the file type (by the file signatures ("magic numbers"))
and returns some additional info.
List of fields:
- "Description" returns short description;
- "MIME-type" returns MIME-type of file;
- "MIME-type: alias(es)" returns alias if exists (if more than one then comma separated);
- "Ext" returns usual file extension;
- "Bad ext" returns "True", if the file extension is not correspond to the file format.
Notes about "Ext" and "Bad ext"
1) For example, JPEG: "Ext" returns "jpg", because it's usual file extension, but
for checking will use full list: "*.jpeg; *.jpg; *.jpe; *.jfif".
Current list:
- ASF video, Windows Media audio or Windows Media video (*.asf; *.wma; *.wmv)
- BMP image (*.bmp; *.dib; *.rle)
- CHM document (*.chm)
- DjVu document (*.djvu; *.djv)
- GIF image (*.gif)
- JPEG image (*.jpg; *.jpeg; *.jpe; *.jfif)
- MP3 audio (*.mp3)
- PDF document (*.pdf)
- PNG image (*.png)
- RTF document (Rich Text Format) (*.rtf)
- TIFF image (*.tif; *.tiff)
- WebP image (*.webp)
]]
local fields = {
{"Description", "", 8},
{"MIME-type", "", 8},
{"MIME-type: alias(es)", "", 8},
{"Ext", "", 8},
{"Bad ext", "", 6}
}
local ar = {}
local filename = ''
function ContentGetSupportedField(FieldIndex)
if fields[FieldIndex + 1] ~= nil then
return fields[FieldIndex + 1][1], fields[FieldIndex + 1][2], fields[FieldIndex + 1][3]
end
return "", "", 0
end
function ContentGetDefaultSortOrder(FieldIndex)
return 1; --or -1
end
function ContentGetDetectString()
return 'EXT="*"'
end
function ContentGetValue(FileName, FieldIndex, UnitIndex, flags)
if FieldIndex >= #fields then return nil end
if filename ~= FileName then
local at = SysUtils.FileGetAttr(FileName)
if at < 0 then return nil end
if math.floor(at / 0x00000004) % 2 ~= 0 then return nil end
if math.floor(at / 0x00000010) % 2 ~= 0 then return nil end
ar = {'', '', '', '', false}
local h = io.open(FileName, 'rb')
if h == nil then return nil end
local d = h:read(32)
h:close()
local e = string.lower(SysUtils.ExtractFileExt(FileName))
local d14h = BinToNumBE(d, 1, 4)
local d58h = BinToNumBE(d, 5, 8)
-- BMP
if IsBMP(d) == true then
ar[1] = 'BMP image'
ar[2] = 'image/bmp'
ar[3] = 'image/x-bmp, image/x-MS-bmp'
ar[4] = 'bmp'
if (e ~= '.bmp') and (e ~= '.dib') and (e ~= '.rle') then ar[5] = true end
-- CHM
elseif d14h == 0x49545346 then
ar[1] = 'CHM document, Microsoft Compiled HTML Help File'
ar[2] = 'application/vnd.ms-htmlhelp'
ar[3] = 'application/x-chm'
ar[4] = 'chm'
if e ~= '.chm' then ar[5] = true end
-- DjVu (AT&TFORM)
elseif (d14h == 0x41542654) and (d58h == 0x464f524d) and (string.sub(d, 13, 15) == 'DJV') then
ar[1] = 'DjVu document'
ar[2] = 'image/vnd.djvu'
ar[4] = 'djvu'
local t = string.sub(d, 16, 16)
if t == 'U' then
ar[3] = 'image/x-djvu, image/x.djvu'
elseif t == 'M' then
ar[3] = 'image/x-djvu, image/x.djvu, image/vnd.djvu+multipage'
end
if (e ~= '.djvu') and (e ~= '.djv') then ar[5] = true end
-- GIF
elseif d14h == 0x47494638 then
ar[1] = 'GIF image'
ar[2] = 'image/gif'
ar[4] = 'gif'
if e ~= '.gif' then ar[5] = true end
-- JPEG: ff d8 ff
elseif (string.byte(d, 1) == 0xff) and (string.byte(d, 2) == 0xd8) and (string.byte(d, 3) == 0xff) then
ar[1] = 'JPEG image'
ar[2] = 'image/jpeg'
ar[4] = 'jpg'
if (e ~= '.jpg') and (e ~= '.jpeg') and (e ~= '.jpe') and (e ~= '.jfif') then ar[5] = true end
-- MP3 and MP3 with ID3v2
elseif (string.sub(d, 1, 3) == 'ID3') or (BinToNumBE(d, 1, 2) == 0xfffb) then
ar[1] = 'MP3 audio'
ar[2] = 'audio/mpeg'
ar[3] = 'audio/x-mp3, audio/x-mpg, audio/x-mpeg, audio/mp3'
ar[4] = 'mp3'
if e ~= '.mp3' then ar[5] = true end
-- PDF
elseif string.sub(d, 1, 5) == '%PDF-' then
ar[1] = 'PDF document'
ar[2] = 'application/pdf'
ar[3] = 'application/x-pdf, image/pdf, application/acrobat, application/nappdf'
ar[4] = 'pdf'
if e ~= '.pdf' then ar[5] = true end
-- PNG
elseif (string.byte(d, 1) == 0x89) and (string.sub(d, 2, 4) == 'PNG') and (d58h == 0x0d0a1a0a) then
ar[1] = 'PNG image'
ar[2] = 'image/png'
ar[4] = 'png'
if e ~= '.png' then ar[5] = true end
-- RTF
elseif string.sub(d, 1, 5) == '{\rtf' then
ar[1] = 'RTF document (Rich Text Format)'
ar[2] = 'application/rtf'
ar[3] = 'text/rtf'
ar[4] = 'rtf'
if e ~= '.rtf' then ar[5] = true end
-- ASF, WMA, WMV
elseif (d14h == 0x3026b275) and (d58h == 0x8e66cf11) and (BinToNumBE(d, 9, 12) == 0xa6d900aa) and (BinToNumBE(d, 13, 16) == 0x0062ce6c) then
ar[1] = 'ASF video, Windows Media audio or Windows Media video'
if e == '.asf' then
ar[1] = 'ASF video'
ar[2] = 'application/vnd.ms-asf'
ar[3] = 'video/x-ms-wm, video/x-ms-asf, video/x-ms-asf-plugin'
ar[4] = 'asf'
elseif e == '.wma' then
ar[1] = 'Windows Media audio'
ar[2] = 'audio/x-ms-wma'
ar[3] = 'audio/wma'
ar[4] = 'wma'
elseif e == '.wmv' then
ar[1] = 'Windows Media video'
ar[2] = 'video/x-ms-wmv'
ar[4] = 'wmv'
else
ar[5] = true
end
-- TIFF
elseif (d14h == 0x49492a00) or (d14h == 0x4d4d002a) or (d14h == 0x49492b00) or (d14h == 0x4d4d002b) then
ar[1] = 'TIFF image'
ar[2] = 'image/tiff'
ar[4] = 'tif'
if (e ~= '.tif') and (e ~= '.tiff') then ar[5] = true end
-- RIFF
elseif d14s == 'RIFF' then
local t4 = string.sub(d, 9, 12)
-- WebP
if t4 == 'WEBP' then
ar[1] = 'Google WebP image'
ar[2] = 'image/webp'
ar[4] = 'webp'
if e ~= '.webp' then ar[5] = true end
end
end
filename = FileName
end
if ar[FieldIndex + 1] == '' then
return nil
else
return ar[FieldIndex + 1]
end
return nil
end
function BinToNumBE(d, n1, n2)
local r = ''
for i = n1, n2 do
r = r .. string.format('%02x', string.byte(d, i))
end
return tonumber('0x' .. r)
end
function IsBMP(d)
if (string.sub(d, 1, 2) == 'BM') and (BinToNumBE(d, 13, 14) == 0x0000) and (BinToNumBE(d, 16, 18) == 0x00) then
if (string.byte(d, 15) == 0x0c) and (BinToNumBE(d, 23, 24) == 0x0100) and (string.byte(d, 26) == 0x00) then
return true
end
if (BinToNumBE(d, 27, 28) == 0x0100) and (string.byte(d, 30) == 0x00) then
return true
end
end
return false
end