magic_bytes 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +10 -0
  3. data/MIT_LICENSE.txt +20 -0
  4. data/README.md +14 -0
  5. data/Rakefile +47 -0
  6. data/lib/magic_bytes.rb +472 -0
  7. data/magic_bytes.gemspec +125 -0
  8. data/spec/fixtures/fixture-0x20001.eot +0 -0
  9. data/spec/fixtures/fixture-big-endian.tif +0 -0
  10. data/spec/fixtures/fixture-imovie.mp4 +0 -0
  11. data/spec/fixtures/fixture-isom.mp4 +0 -0
  12. data/spec/fixtures/fixture-isomv2.mp4 +0 -0
  13. data/spec/fixtures/fixture-little-endian.tif +0 -0
  14. data/spec/fixtures/fixture-otto.woff +0 -0
  15. data/spec/fixtures/fixture-otto.woff2 +0 -0
  16. data/spec/fixtures/fixture.7z +0 -0
  17. data/spec/fixtures/fixture.amr +0 -0
  18. data/spec/fixtures/fixture.ar +0 -0
  19. data/spec/fixtures/fixture.avi +0 -0
  20. data/spec/fixtures/fixture.bmp +0 -0
  21. data/spec/fixtures/fixture.bz2 +0 -0
  22. data/spec/fixtures/fixture.cab +0 -0
  23. data/spec/fixtures/fixture.cr2 +0 -0
  24. data/spec/fixtures/fixture.crx +0 -0
  25. data/spec/fixtures/fixture.deb +0 -0
  26. data/spec/fixtures/fixture.dmg +0 -0
  27. data/spec/fixtures/fixture.eot +0 -0
  28. data/spec/fixtures/fixture.epub +0 -0
  29. data/spec/fixtures/fixture.exe +0 -0
  30. data/spec/fixtures/fixture.flac +0 -0
  31. data/spec/fixtures/fixture.flv +0 -0
  32. data/spec/fixtures/fixture.gif +0 -0
  33. data/spec/fixtures/fixture.ico +0 -0
  34. data/spec/fixtures/fixture.jpg +0 -0
  35. data/spec/fixtures/fixture.jxr +0 -0
  36. data/spec/fixtures/fixture.m4a +0 -0
  37. data/spec/fixtures/fixture.m4v +0 -0
  38. data/spec/fixtures/fixture.mid +0 -0
  39. data/spec/fixtures/fixture.mkv +0 -0
  40. data/spec/fixtures/fixture.mov +0 -0
  41. data/spec/fixtures/fixture.mp3 +0 -0
  42. data/spec/fixtures/fixture.mp4 +0 -0
  43. data/spec/fixtures/fixture.mpg +0 -0
  44. data/spec/fixtures/fixture.msi +0 -0
  45. data/spec/fixtures/fixture.nes +0 -0
  46. data/spec/fixtures/fixture.ogg +0 -0
  47. data/spec/fixtures/fixture.opus +0 -0
  48. data/spec/fixtures/fixture.otf +0 -0
  49. data/spec/fixtures/fixture.pdf +0 -0
  50. data/spec/fixtures/fixture.png +0 -0
  51. data/spec/fixtures/fixture.ps +10 -0
  52. data/spec/fixtures/fixture.psd +0 -0
  53. data/spec/fixtures/fixture.rar +0 -0
  54. data/spec/fixtures/fixture.rpm +0 -0
  55. data/spec/fixtures/fixture.rtf +7 -0
  56. data/spec/fixtures/fixture.sqlite +0 -0
  57. data/spec/fixtures/fixture.swf +0 -0
  58. data/spec/fixtures/fixture.tar +0 -0
  59. data/spec/fixtures/fixture.tar.Z +0 -0
  60. data/spec/fixtures/fixture.tar.gz +0 -0
  61. data/spec/fixtures/fixture.tar.lz +0 -0
  62. data/spec/fixtures/fixture.tar.xz +0 -0
  63. data/spec/fixtures/fixture.ttf +0 -0
  64. data/spec/fixtures/fixture.wav +0 -0
  65. data/spec/fixtures/fixture.webm +0 -0
  66. data/spec/fixtures/fixture.webp +0 -0
  67. data/spec/fixtures/fixture.wmv +0 -0
  68. data/spec/fixtures/fixture.woff +0 -0
  69. data/spec/fixtures/fixture.woff2 +0 -0
  70. data/spec/fixtures/fixture.xpi +0 -0
  71. data/spec/fixtures/fixture.zip +0 -0
  72. data/spec/magic_bytes_spec.rb +102 -0
  73. metadata +199 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e4ba56d5cd2228b01a35c54c6c2e2192d47ed17d
4
+ data.tar.gz: ab1ec8aaedbe75604fdeef68be0d09fa27e2c702
5
+ SHA512:
6
+ metadata.gz: 3e2839aca9bd215da68122361b97ad6c488a95ebf1c2067d71f5d5dfda7114e7b90686b6eb28e7f256b3914a3d5550237af7f0336abfe3b138087c1554dd2536
7
+ data.tar.gz: 14724a04c4e03aa52c9a50e1586f9e00aa79befbcc24880b2bbf112b5c88a15f3d64a5a2365f07feec068fc023d1bdd5106f07b03dbf38e200151fc2350e12f9
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ group :development do
4
+ gem 'rspec', '~> 3.2.0'
5
+ gem "yard"
6
+ gem "bundler", "~> 1.0"
7
+ gem "jeweler"
8
+ gem 'coderay'
9
+ gem 'rake', '< 11'
10
+ end
data/MIT_LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009-2016 Julik Tarkhanov
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,14 @@
1
+ A pretty much line-for-line port of https://github.com/sindresorhus/file-type
2
+ Many thanks to Sindre Sorhus for putting this together.
3
+
4
+ The module has two methods: `detect` and `read_and_detect`. The former works on String
5
+ objects (when you already read stuff), the latter works on IO objects (or anything you
6
+ can #read from).
7
+
8
+ file_type = File.open('suspicious_file.bin', 'rb') do |f
9
+ MagicBytes.read_and_detect(f)
10
+ end
11
+ file_type.ext #=> 'msi', someone is uploading a Windows installer...
12
+
13
+ If the file type is unknown, the last-resort variant of `bin` as extension
14
+ and `binary/octet-stream` will be returned.
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ require_relative 'lib/magic_bytes'
16
+ Jeweler::Tasks.new do |gem|
17
+ # gem is a Gem::Specification... see http://guides.rubygems.org/specification-reference/ for more options
18
+ gem.version = MagicBytes::VERSION
19
+ gem.name = "magic_bytes"
20
+ gem.homepage = "https://github.com/julik/magic_bytes"
21
+ gem.license = "MIT"
22
+ gem.summary = %Q{Basic file type checks based on a few header bytes}
23
+ gem.description = %Q{Basic file type checks based on a few header bytes}
24
+ gem.email = "me@julik.nl"
25
+ gem.authors = ["Julik Tarkhanov"]
26
+ # dependencies defined in Gemfile
27
+ end
28
+ Jeweler::RubygemsDotOrgTasks.new
29
+
30
+ require 'rspec/core'
31
+ require 'rspec/core/rake_task'
32
+ RSpec::Core::RakeTask.new(:spec) do |spec|
33
+ spec.rspec_opts = ["-c"]
34
+ spec.pattern = FileList['spec/**/*_spec.rb']
35
+ end
36
+
37
+ task :default => :spec
38
+
39
+ require 'rdoc/task'
40
+ Rake::RDocTask.new do |rdoc|
41
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
42
+
43
+ rdoc.rdoc_dir = 'rdoc'
44
+ rdoc.title = "chunked_downloader #{version}"
45
+ rdoc.rdoc_files.include('README*')
46
+ rdoc.rdoc_files.include('lib/**/*.rb')
47
+ end
@@ -0,0 +1,472 @@
1
+ module MagicBytes
2
+ VERSION = '1.0.1'
3
+
4
+ class FileType < Struct.new(:ext, :mime)
5
+ end
6
+
7
+ extend self
8
+
9
+ # Performs detection from a given IO or File.
10
+ #
11
+ # @param io[#read] a readable object
12
+ # @return [Hash, nil] the hash of ext: and mime: or nil if the type could not be deduced
13
+ def read_and_detect(io)
14
+ n_bytes = 262 # The maximum length supported (needed for .tar archives)
15
+ detect(io.read(n_bytes))
16
+ end
17
+
18
+ # This is a line-for-line port of https://github.com/sindresorhus/file-type
19
+ # which is more than sufficient for our purposes
20
+ #
21
+ # @param header_bytes[String] the header bytes of the file
22
+ # @return [Hash, nil] the hash of ext: and mime: or nil if the type could not be deduced
23
+ def detect(header_bytes)
24
+ d = _detect(header_bytes)
25
+ FileType.new(d.fetch(:ext), d.fetch(:mime))
26
+ end
27
+
28
+ private
29
+
30
+ def _detect(header_bytes)
31
+ buf = header_bytes.unpack("C*")
32
+
33
+ if (buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF)
34
+ return {
35
+ ext: 'jpg',
36
+ mime: 'image/jpeg'
37
+ }
38
+ end
39
+
40
+ if (buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4E && buf[3] == 0x47)
41
+ return {
42
+ ext: 'png',
43
+ mime: 'image/png'
44
+ }
45
+ end
46
+
47
+ if (buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46)
48
+ return {
49
+ ext: 'gif',
50
+ mime: 'image/gif'
51
+ }
52
+ end
53
+
54
+ if (buf[8] == 0x57 && buf[9] == 0x45 && buf[10] == 0x42 && buf[11] == 0x50)
55
+ return {
56
+ ext: 'webp',
57
+ mime: 'image/webp'
58
+ }
59
+ end
60
+
61
+ # needs to be before `tif`
62
+ if (((buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0x2A && buf[3] == 0x0) || (buf[0] == 0x4D && buf[1] == 0x4D && buf[2] == 0x0 && buf[3] == 0x2A)) && buf[8] == 0x43 && buf[9] == 0x52)
63
+ return {
64
+ ext: 'cr2',
65
+ mime: 'image/x-canon-cr2'
66
+ }
67
+ end
68
+
69
+ if ((buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0x2A && buf[3] == 0x0) || (buf[0] == 0x4D && buf[1] == 0x4D && buf[2] == 0x0 && buf[3] == 0x2A))
70
+ return {
71
+ ext: 'tif',
72
+ mime: 'image/tiff'
73
+ }
74
+ end
75
+
76
+ if (buf[0] == 0x42 && buf[1] == 0x4D)
77
+ return {
78
+ ext: 'bmp',
79
+ mime: 'image/bmp'
80
+ }
81
+ end
82
+
83
+ if (buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0xBC)
84
+ return {
85
+ ext: 'jxr',
86
+ mime: 'image/vnd.ms-photo'
87
+ }
88
+ end
89
+
90
+ if (buf[0] == 0x38 && buf[1] == 0x42 && buf[2] == 0x50 && buf[3] == 0x53)
91
+ return {
92
+ ext: 'psd',
93
+ mime: 'image/vnd.adobe.photoshop'
94
+ }
95
+ end
96
+
97
+ # needs to be before `zip`
98
+ if (buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x3 && buf[3] == 0x4 && buf[30] == 0x6D && buf[31] == 0x69 && buf[32] == 0x6D && buf[33] == 0x65 && buf[34] == 0x74 && buf[35] == 0x79 && buf[36] == 0x70 && buf[37] == 0x65 && buf[38] == 0x61 && buf[39] == 0x70 && buf[40] == 0x70 && buf[41] == 0x6C && buf[42] == 0x69 && buf[43] == 0x63 && buf[44] == 0x61 && buf[45] == 0x74 && buf[46] == 0x69 && buf[47] == 0x6F && buf[48] == 0x6E && buf[49] == 0x2F && buf[50] == 0x65 && buf[51] == 0x70 && buf[52] == 0x75 && buf[53] == 0x62 && buf[54] == 0x2B && buf[55] == 0x7A && buf[56] == 0x69 && buf[57] == 0x70)
99
+ return {
100
+ ext: 'epub',
101
+ mime: 'application/epub+zip'
102
+ }
103
+ end
104
+
105
+ # needs to be before `zip`
106
+ # assumes signed.xpi from addons.mozilla.org
107
+ if (buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x3 && buf[3] == 0x4 && buf[30] == 0x4D && buf[31] == 0x45 && buf[32] == 0x54 && buf[33] == 0x41 && buf[34] == 0x2D && buf[35] == 0x49 && buf[36] == 0x4E && buf[37] == 0x46 && buf[38] == 0x2F && buf[39] == 0x6D && buf[40] == 0x6F && buf[41] == 0x7A && buf[42] == 0x69 && buf[43] == 0x6C && buf[44] == 0x6C && buf[45] == 0x61 && buf[46] == 0x2E && buf[47] == 0x72 && buf[48] == 0x73 && buf[49] == 0x61)
108
+ return {
109
+ ext: 'xpi',
110
+ mime: 'application/x-xpinstall'
111
+ }
112
+ end
113
+
114
+ if (buf[0] == 0x50 && buf[1] == 0x4B && (buf[2] == 0x3 || buf[2] == 0x5 || buf[2] == 0x7) && (buf[3] == 0x4 || buf[3] == 0x6 || buf[3] == 0x8))
115
+ return {
116
+ ext: 'zip',
117
+ mime: 'application/zip'
118
+ }
119
+ end
120
+
121
+ if (buf[257] == 0x75 && buf[258] == 0x73 && buf[259] == 0x74 && buf[260] == 0x61 && buf[261] == 0x72)
122
+ return {
123
+ ext: 'tar',
124
+ mime: 'application/x-tar'
125
+ }
126
+ end
127
+
128
+ if (buf[0] == 0x52 && buf[1] == 0x61 && buf[2] == 0x72 && buf[3] == 0x21 && buf[4] == 0x1A && buf[5] == 0x7 && (buf[6] == 0x0 || buf[6] == 0x1))
129
+ return {
130
+ ext: 'rar',
131
+ mime: 'application/x-rar-compressed'
132
+ }
133
+ end
134
+
135
+ if (buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x8)
136
+ return {
137
+ ext: 'gz',
138
+ mime: 'application/gzip'
139
+ }
140
+ end
141
+
142
+ if (buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68)
143
+ return {
144
+ ext: 'bz2',
145
+ mime: 'application/x-bzip2'
146
+ }
147
+ end
148
+
149
+ if (buf[0] == 0x37 && buf[1] == 0x7A && buf[2] == 0xBC && buf[3] == 0xAF && buf[4] == 0x27 && buf[5] == 0x1C)
150
+ return {
151
+ ext: '7z',
152
+ mime: 'application/x-7z-compressed'
153
+ }
154
+ end
155
+
156
+ if (buf[0] == 0x78 && buf[1] == 0x01)
157
+ return {
158
+ ext: 'dmg',
159
+ mime: 'application/x-apple-diskimage'
160
+ }
161
+ end
162
+
163
+ if (
164
+ (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && (buf[3] == 0x18 || buf[3] == 0x20) && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70) ||
165
+ (buf[0] == 0x33 && buf[1] == 0x67 && buf[2] == 0x70 && buf[3] == 0x35) ||
166
+ (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1C && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x6D && buf[9] == 0x70 && buf[10] == 0x34 && buf[11] == 0x32 && buf[16] == 0x6D && buf[17] == 0x70 && buf[18] == 0x34 && buf[19] == 0x31 && buf[20] == 0x6D && buf[21] == 0x70 && buf[22] == 0x34 && buf[23] == 0x32 && buf[24] == 0x69 && buf[25] == 0x73 && buf[26] == 0x6F && buf[27] == 0x6D) ||
167
+ (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1C && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x69 && buf[9] == 0x73 && buf[10] == 0x6F && buf[11] == 0x6D) ||
168
+ (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1c && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x6D && buf[9] == 0x70 && buf[10] == 0x34 && buf[11] == 0x32 && buf[12] == 0x0 && buf[13] == 0x0 && buf[14] == 0x0 && buf[15] == 0x0)
169
+ )
170
+ return {
171
+ ext: 'mp4',
172
+ mime: 'video/mp4'
173
+ }
174
+ end
175
+
176
+ if ((buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1C && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x4D && buf[9] == 0x34 && buf[10] == 0x56))
177
+ return {
178
+ ext: 'm4v',
179
+ mime: 'video/x-m4v'
180
+ }
181
+ end
182
+
183
+ if (buf[0] == 0x4D && buf[1] == 0x54 && buf[2] == 0x68 && buf[3] == 0x64)
184
+ return {
185
+ ext: 'mid',
186
+ mime: 'audio/midi'
187
+ }
188
+ end
189
+
190
+ # needs to be before the `webm`
191
+ if (buf[31] == 0x6D && buf[32] == 0x61 && buf[33] == 0x74 && buf[34] == 0x72 && buf[35] == 0x6f && buf[36] == 0x73 && buf[37] == 0x6B && buf[38] == 0x61)
192
+ return {
193
+ ext: 'mkv',
194
+ mime: 'video/x-matroska'
195
+ }
196
+ end
197
+
198
+ if (buf[0] == 0x1A && buf[1] == 0x45 && buf[2] == 0xDF && buf[3] == 0xA3)
199
+ return {
200
+ ext: 'webm',
201
+ mime: 'video/webm'
202
+ }
203
+ end
204
+
205
+ if (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x14 && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70)
206
+ return {
207
+ ext: 'mov',
208
+ mime: 'video/quicktime'
209
+ }
210
+ end
211
+
212
+ if (buf[0] == 0x52 && buf[1] == 0x49 && buf[2] == 0x46 && buf[3] == 0x46 && buf[8] == 0x41 && buf[9] == 0x56 && buf[10] == 0x49)
213
+ return {
214
+ ext: 'avi',
215
+ mime: 'video/x-msvideo'
216
+ }
217
+ end
218
+
219
+ if (buf[0] == 0x30 && buf[1] == 0x26 && buf[2] == 0xB2 && buf[3] == 0x75 && buf[4] == 0x8E && buf[5] == 0x66 && buf[6] == 0xCF && buf[7] == 0x11 && buf[8] == 0xA6 && buf[9] == 0xD9)
220
+ return {
221
+ ext: 'wmv',
222
+ mime: 'video/x-ms-wmv'
223
+ }
224
+ end
225
+
226
+ if (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x1 && buf[3] == 186) # buf[3].toString(16)[0] == 'b'
227
+ return {
228
+ ext: 'mpg',
229
+ mime: 'video/mpeg'
230
+ }
231
+ end
232
+
233
+ if ((buf[0] == 0x49 && buf[1] == 0x44 && buf[2] == 0x33) || (buf[0] == 0xFF && buf[1] == 0xfb))
234
+ return {
235
+ ext: 'mp3',
236
+ mime: 'audio/mpeg'
237
+ }
238
+ end
239
+
240
+ if ((buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x4D && buf[9] == 0x34 && buf[10] == 0x41) || (buf[0] == 0x4D && buf[1] == 0x34 && buf[2] == 0x41 && buf[3] == 0x20))
241
+ return {
242
+ ext: 'm4a',
243
+ mime: 'audio/m4a'
244
+ }
245
+ end
246
+
247
+ # needs to be before `ogg`
248
+ if (buf[28] == 0x4F && buf[29] == 0x70 && buf[30] == 0x75 && buf[31] == 0x73 && buf[32] == 0x48 && buf[33] == 0x65 && buf[34] == 0x61 && buf[35] == 0x64)
249
+ return {
250
+ ext: 'opus',
251
+ mime: 'audio/opus'
252
+ }
253
+ end
254
+
255
+ if (buf[0] == 0x4F && buf[1] == 0x67 && buf[2] == 0x67 && buf[3] == 0x53)
256
+ return {
257
+ ext: 'ogg',
258
+ mime: 'audio/ogg'
259
+ }
260
+ end
261
+
262
+ if (buf[0] == 0x66 && buf[1] == 0x4C && buf[2] == 0x61 && buf[3] == 0x43)
263
+ return {
264
+ ext: 'flac',
265
+ mime: 'audio/x-flac'
266
+ }
267
+ end
268
+
269
+ if (buf[0] == 0x52 && buf[1] == 0x49 && buf[2] == 0x46 && buf[3] == 0x46 && buf[8] == 0x57 && buf[9] == 0x41 && buf[10] == 0x56 && buf[11] == 0x45)
270
+ return {
271
+ ext: 'wav',
272
+ mime: 'audio/x-wav'
273
+ }
274
+ end
275
+
276
+ if (buf[0] == 0x23 && buf[1] == 0x21 && buf[2] == 0x41 && buf[3] == 0x4D && buf[4] == 0x52 && buf[5] == 0x0A)
277
+ return {
278
+ ext: 'amr',
279
+ mime: 'audio/amr'
280
+ }
281
+ end
282
+
283
+ if (buf[0] == 0x25 && buf[1] == 0x50 && buf[2] == 0x44 && buf[3] == 0x46)
284
+ return {
285
+ ext: 'pdf',
286
+ mime: 'application/pdf'
287
+ }
288
+ end
289
+
290
+ if (buf[0] == 0x4D && buf[1] == 0x5A)
291
+ return {
292
+ ext: 'exe',
293
+ mime: 'application/x-msdownload'
294
+ }
295
+ end
296
+
297
+ if ((buf[0] == 0x43 || buf[0] == 0x46) && buf[1] == 0x57 && buf[2] == 0x53)
298
+ return {
299
+ ext: 'swf',
300
+ mime: 'application/x-shockwave-flash'
301
+ }
302
+ end
303
+
304
+ if (buf[0] == 0x7B && buf[1] == 0x5C && buf[2] == 0x72 && buf[3] == 0x74 && buf[4] == 0x66)
305
+ return {
306
+ ext: 'rtf',
307
+ mime: 'application/rtf'
308
+ }
309
+ end
310
+
311
+ if (
312
+ (buf[0] == 0x77 && buf[1] == 0x4F && buf[2] == 0x46 && buf[3] == 0x46) &&
313
+ (
314
+ (buf[4] == 0x00 && buf[5] == 0x01 && buf[6] == 0x00 && buf[7] == 0x00) ||
315
+ (buf[4] == 0x4F && buf[5] == 0x54 && buf[6] == 0x54 && buf[7] == 0x4F)
316
+ )
317
+ )
318
+ return {
319
+ ext: 'woff',
320
+ mime: 'application/font-woff'
321
+ }
322
+ end
323
+
324
+ if (
325
+ (buf[0] == 0x77 && buf[1] == 0x4F && buf[2] == 0x46 && buf[3] == 0x32) &&
326
+ (
327
+ (buf[4] == 0x00 && buf[5] == 0x01 && buf[6] == 0x00 && buf[7] == 0x00) ||
328
+ (buf[4] == 0x4F && buf[5] == 0x54 && buf[6] == 0x54 && buf[7] == 0x4F)
329
+ )
330
+ )
331
+ return {
332
+ ext: 'woff2',
333
+ mime: 'application/font-woff'
334
+ }
335
+ end
336
+
337
+ if (
338
+ (buf[34] == 0x4C && buf[35] == 0x50) &&
339
+ (
340
+ (buf[8] == 0x00 && buf[9] == 0x00 && buf[10] == 0x01) ||
341
+ (buf[8] == 0x01 && buf[9] == 0x00 && buf[10] == 0x02) ||
342
+ (buf[8] == 0x02 && buf[9] == 0x00 && buf[10] == 0x02)
343
+ )
344
+ )
345
+ return {
346
+ ext: 'eot',
347
+ mime: 'application/octet-stream'
348
+ }
349
+ end
350
+
351
+ if (buf[0] == 0x00 && buf[1] == 0x01 && buf[2] == 0x00 && buf[3] == 0x00 && buf[4] == 0x00)
352
+ return {
353
+ ext: 'ttf',
354
+ mime: 'application/font-sfnt'
355
+ }
356
+ end
357
+
358
+ if (buf[0] == 0x4F && buf[1] == 0x54 && buf[2] == 0x54 && buf[3] == 0x4F && buf[4] == 0x00)
359
+ return {
360
+ ext: 'otf',
361
+ mime: 'application/font-sfnt'
362
+ }
363
+ end
364
+
365
+ if (buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 && buf[3] == 0x00)
366
+ return {
367
+ ext: 'ico',
368
+ mime: 'image/x-icon'
369
+ }
370
+ end
371
+
372
+ if (buf[0] == 0x46 && buf[1] == 0x4C && buf[2] == 0x56 && buf[3] == 0x01)
373
+ return {
374
+ ext: 'flv',
375
+ mime: 'video/x-flv'
376
+ }
377
+ end
378
+
379
+ if (buf[0] == 0x25 && buf[1] == 0x21)
380
+ return {
381
+ ext: 'ps',
382
+ mime: 'application/postscript'
383
+ }
384
+ end
385
+
386
+ if (buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A && buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00)
387
+ return {
388
+ ext: 'xz',
389
+ mime: 'application/x-xz'
390
+ }
391
+ end
392
+
393
+ if (buf[0] == 0x53 && buf[1] == 0x51 && buf[2] == 0x4C && buf[3] == 0x69)
394
+ return {
395
+ ext: 'sqlite',
396
+ mime: 'application/x-sqlite3'
397
+ }
398
+ end
399
+
400
+ if (buf[0] == 0x4E && buf[1] == 0x45 && buf[2] == 0x53 && buf[3] == 0x1A)
401
+ return {
402
+ ext: 'nes',
403
+ mime: 'application/x-nintendo-nes-rom'
404
+ }
405
+ end
406
+
407
+ if (buf[0] == 0x43 && buf[1] == 0x72 && buf[2] == 0x32 && buf[3] == 0x34)
408
+ return {
409
+ ext: 'crx',
410
+ mime: 'application/x-google-chrome-extension'
411
+ }
412
+ end
413
+
414
+ if (
415
+ (buf[0] == 0x4D && buf[1] == 0x53 && buf[2] == 0x43 && buf[3] == 0x46) ||
416
+ (buf[0] == 0x49 && buf[1] == 0x53 && buf[2] == 0x63 && buf[3] == 0x28)
417
+ )
418
+ return {
419
+ ext: 'cab',
420
+ mime: 'application/vnd.ms-cab-compressed'
421
+ }
422
+ end
423
+
424
+ # needs to be before `ar`
425
+ if (buf[0] == 0x21 && buf[1] == 0x3C && buf[2] == 0x61 && buf[3] == 0x72 && buf[4] == 0x63 && buf[5] == 0x68 && buf[6] == 0x3E && buf[7] == 0x0A && buf[8] == 0x64 && buf[9] == 0x65 && buf[10] == 0x62 && buf[11] == 0x69 && buf[12] == 0x61 && buf[13] == 0x6E && buf[14] == 0x2D && buf[15] == 0x62 && buf[16] == 0x69 && buf[17] == 0x6E && buf[18] == 0x61 && buf[19] == 0x72 && buf[20] == 0x79)
426
+ return {
427
+ ext: 'deb',
428
+ mime: 'application/x-deb'
429
+ }
430
+ end
431
+
432
+ if (buf[0] == 0x21 && buf[1] == 0x3C && buf[2] == 0x61 && buf[3] == 0x72 && buf[4] == 0x63 && buf[5] == 0x68 && buf[6] == 0x3E)
433
+ return {
434
+ ext: 'ar',
435
+ mime: 'application/x-unix-archive'
436
+ }
437
+ end
438
+
439
+ if (buf[0] == 0xED && buf[1] == 0xAB && buf[2] == 0xEE && buf[3] == 0xDB)
440
+ return {
441
+ ext: 'rpm',
442
+ mime: 'application/x-rpm'
443
+ }
444
+ end
445
+
446
+ if (
447
+ (buf[0] == 0x1F && buf[1] == 0xA0) ||
448
+ (buf[0] == 0x1F && buf[1] == 0x9D)
449
+ )
450
+ return {
451
+ ext: 'Z',
452
+ mime: 'application/x-compress'
453
+ }
454
+ end
455
+
456
+ if (buf[0] == 0x4C && buf[1] == 0x5A && buf[2] == 0x49 && buf[3] == 0x50)
457
+ return {
458
+ ext: 'lz',
459
+ mime: 'application/x-lzip'
460
+ }
461
+ end
462
+
463
+ if (buf[0] == 0xD0 && buf[1] == 0xCF && buf[2] == 0x11 && buf[3] == 0xE0 && buf[4] == 0xA1 && buf[5] == 0xB1 && buf[6] == 0x1A && buf[7] == 0xE1)
464
+ return {
465
+ ext: 'msi',
466
+ mime: 'application/x-msi'
467
+ }
468
+ end
469
+
470
+ return {ext: 'bin', mime: 'binary/octet-stream'}
471
+ end
472
+ end
@@ -0,0 +1,125 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+ # stub: magic_bytes 1.0.1 ruby lib
6
+
7
+ Gem::Specification.new do |s|
8
+ s.name = "magic_bytes"
9
+ s.version = "1.0.1"
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.require_paths = ["lib"]
13
+ s.authors = ["Julik Tarkhanov"]
14
+ s.date = "2016-05-28"
15
+ s.description = "Basic file type checks based on a few header bytes"
16
+ s.email = "me@julik.nl"
17
+ s.extra_rdoc_files = [
18
+ "README.md"
19
+ ]
20
+ s.files = [
21
+ "Gemfile",
22
+ "MIT_LICENSE.txt",
23
+ "README.md",
24
+ "Rakefile",
25
+ "lib/magic_bytes.rb",
26
+ "magic_bytes.gemspec",
27
+ "spec/fixtures/fixture-0x20001.eot",
28
+ "spec/fixtures/fixture-big-endian.tif",
29
+ "spec/fixtures/fixture-imovie.mp4",
30
+ "spec/fixtures/fixture-isom.mp4",
31
+ "spec/fixtures/fixture-isomv2.mp4",
32
+ "spec/fixtures/fixture-little-endian.tif",
33
+ "spec/fixtures/fixture-otto.woff",
34
+ "spec/fixtures/fixture-otto.woff2",
35
+ "spec/fixtures/fixture.7z",
36
+ "spec/fixtures/fixture.amr",
37
+ "spec/fixtures/fixture.ar",
38
+ "spec/fixtures/fixture.avi",
39
+ "spec/fixtures/fixture.bmp",
40
+ "spec/fixtures/fixture.bz2",
41
+ "spec/fixtures/fixture.cab",
42
+ "spec/fixtures/fixture.cr2",
43
+ "spec/fixtures/fixture.crx",
44
+ "spec/fixtures/fixture.deb",
45
+ "spec/fixtures/fixture.dmg",
46
+ "spec/fixtures/fixture.eot",
47
+ "spec/fixtures/fixture.epub",
48
+ "spec/fixtures/fixture.exe",
49
+ "spec/fixtures/fixture.flac",
50
+ "spec/fixtures/fixture.flv",
51
+ "spec/fixtures/fixture.gif",
52
+ "spec/fixtures/fixture.ico",
53
+ "spec/fixtures/fixture.jpg",
54
+ "spec/fixtures/fixture.jxr",
55
+ "spec/fixtures/fixture.m4a",
56
+ "spec/fixtures/fixture.m4v",
57
+ "spec/fixtures/fixture.mid",
58
+ "spec/fixtures/fixture.mkv",
59
+ "spec/fixtures/fixture.mov",
60
+ "spec/fixtures/fixture.mp3",
61
+ "spec/fixtures/fixture.mp4",
62
+ "spec/fixtures/fixture.mpg",
63
+ "spec/fixtures/fixture.msi",
64
+ "spec/fixtures/fixture.nes",
65
+ "spec/fixtures/fixture.ogg",
66
+ "spec/fixtures/fixture.opus",
67
+ "spec/fixtures/fixture.otf",
68
+ "spec/fixtures/fixture.pdf",
69
+ "spec/fixtures/fixture.png",
70
+ "spec/fixtures/fixture.ps",
71
+ "spec/fixtures/fixture.psd",
72
+ "spec/fixtures/fixture.rar",
73
+ "spec/fixtures/fixture.rpm",
74
+ "spec/fixtures/fixture.rtf",
75
+ "spec/fixtures/fixture.sqlite",
76
+ "spec/fixtures/fixture.swf",
77
+ "spec/fixtures/fixture.tar",
78
+ "spec/fixtures/fixture.tar.Z",
79
+ "spec/fixtures/fixture.tar.gz",
80
+ "spec/fixtures/fixture.tar.lz",
81
+ "spec/fixtures/fixture.tar.xz",
82
+ "spec/fixtures/fixture.ttf",
83
+ "spec/fixtures/fixture.wav",
84
+ "spec/fixtures/fixture.webm",
85
+ "spec/fixtures/fixture.webp",
86
+ "spec/fixtures/fixture.wmv",
87
+ "spec/fixtures/fixture.woff",
88
+ "spec/fixtures/fixture.woff2",
89
+ "spec/fixtures/fixture.xpi",
90
+ "spec/fixtures/fixture.zip",
91
+ "spec/magic_bytes_spec.rb"
92
+ ]
93
+ s.homepage = "https://github.com/julik/magic_bytes"
94
+ s.licenses = ["MIT"]
95
+ s.rubygems_version = "2.2.2"
96
+ s.summary = "Basic file type checks based on a few header bytes"
97
+
98
+ if s.respond_to? :specification_version then
99
+ s.specification_version = 4
100
+
101
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
102
+ s.add_development_dependency(%q<rspec>, ["~> 3.2.0"])
103
+ s.add_development_dependency(%q<yard>, [">= 0"])
104
+ s.add_development_dependency(%q<bundler>, ["~> 1.0"])
105
+ s.add_development_dependency(%q<jeweler>, [">= 0"])
106
+ s.add_development_dependency(%q<coderay>, [">= 0"])
107
+ s.add_development_dependency(%q<rake>, ["< 11"])
108
+ else
109
+ s.add_dependency(%q<rspec>, ["~> 3.2.0"])
110
+ s.add_dependency(%q<yard>, [">= 0"])
111
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
112
+ s.add_dependency(%q<jeweler>, [">= 0"])
113
+ s.add_dependency(%q<coderay>, [">= 0"])
114
+ s.add_dependency(%q<rake>, ["< 11"])
115
+ end
116
+ else
117
+ s.add_dependency(%q<rspec>, ["~> 3.2.0"])
118
+ s.add_dependency(%q<yard>, [">= 0"])
119
+ s.add_dependency(%q<bundler>, ["~> 1.0"])
120
+ s.add_dependency(%q<jeweler>, [">= 0"])
121
+ s.add_dependency(%q<coderay>, [">= 0"])
122
+ s.add_dependency(%q<rake>, ["< 11"])
123
+ end
124
+ end
125
+
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ %!PS
2
+
3
+ /Courier % name the desired font
4
+ 20 selectfont % choose the size in points and establish
5
+ % the font as the current one
6
+ 72 500 moveto % position the current point at
7
+ % coordinates 72, 500 (the origin is at the
8
+ % lower-left corner of the page)
9
+ (Hello world!) show % stroke the text in parentheses
10
+ showpage % print all on the page
Binary file
Binary file
Binary file
@@ -0,0 +1,7 @@
1
+ {\rtf1\ansi\ansicpg1252\cocoartf1265\cocoasubrtf210
2
+ {\fonttbl\f0\fswiss\fcharset0 Helvetica;}
3
+ {\colortbl;\red255\green255\blue255;}
4
+ \paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0
5
+ \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural
6
+
7
+ \f0\fs24 \cf0 Test RTF file}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,102 @@
1
+ require_relative '../lib/magic_bytes'
2
+
3
+ def get_extension(ext, name='fixture')
4
+ path = File.join(__dir__, 'fixtures', "#{name}.#{ext}")
5
+ file_type = File.open(path, 'r'){|f| MagicBytes.read_and_detect(f) }
6
+ end
7
+
8
+ describe 'MagicBytes.read_and_detect' do
9
+ describe 'with the original tests from the JS version' do
10
+ extensions = [
11
+ 'jpg',
12
+ 'png',
13
+ 'gif',
14
+ 'webp',
15
+ 'cr2',
16
+ 'tif',
17
+ 'bmp',
18
+ 'jxr',
19
+ 'psd',
20
+ 'zip',
21
+ 'tar',
22
+ 'rar',
23
+ 'gz',
24
+ 'bz2',
25
+ '7z',
26
+ 'dmg',
27
+ 'mp4',
28
+ 'm4v',
29
+ 'mid',
30
+ 'mkv',
31
+ 'webm',
32
+ 'mov',
33
+ 'avi',
34
+ 'wmv',
35
+ 'mpg',
36
+ 'mp3',
37
+ 'm4a',
38
+ 'ogg',
39
+ 'opus',
40
+ 'flac',
41
+ 'wav',
42
+ 'amr',
43
+ 'pdf',
44
+ 'epub',
45
+ 'exe',
46
+ 'swf',
47
+ 'rtf',
48
+ 'woff',
49
+ 'woff2',
50
+ 'eot',
51
+ 'ttf',
52
+ 'otf',
53
+ 'ico',
54
+ 'flv',
55
+ 'ps',
56
+ 'xz',
57
+ 'sqlite',
58
+ 'nes',
59
+ 'crx',
60
+ 'xpi',
61
+ 'cab',
62
+ 'deb',
63
+ 'ar',
64
+ 'rpm',
65
+ 'Z',
66
+ 'lz',
67
+ 'msi'
68
+ ]
69
+
70
+ names = {
71
+ woff2: ['fixture', 'fixture-otto'],
72
+ woff: ['fixture', 'fixture-otto'],
73
+ eot: ['fixture', 'fixture-0x20001'],
74
+ mp4: ['fixture-imovie', 'fixture-isom', 'fixture-isomv2'],
75
+ tif: ['fixture-big-endian', 'fixture-little-endian'],
76
+ gz: ['fixture.tar'],
77
+ xz: ['fixture.tar'],
78
+ lz: ['fixture.tar'],
79
+ Z: ['fixture.tar']
80
+ }
81
+
82
+ extensions.each do | extension |
83
+ if fixture_names = names[extension.to_sym]
84
+ fixture_names.each do |fixture_name|
85
+ it "recognizes #{fixture_name} as #{extension}" do
86
+ detected_type = get_extension(extension, fixture_name)
87
+ expect(detected_type.ext).to eq(extension)
88
+ expect(detected_type.mime).not_to be_nil
89
+ expect(detected_type.mime).not_to be_empty
90
+ end
91
+ end
92
+ else
93
+ it "recognizes #{extension} as such" do
94
+ detected_type = get_extension(extension)
95
+ expect(detected_type.ext).to eq(extension)
96
+ expect(detected_type.mime).not_to be_nil
97
+ expect(detected_type.mime).not_to be_empty
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
metadata ADDED
@@ -0,0 +1,199 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: magic_bytes
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Julik Tarkhanov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 3.2.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 3.2.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: yard
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: jeweler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: coderay
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "<"
88
+ - !ruby/object:Gem::Version
89
+ version: '11'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "<"
95
+ - !ruby/object:Gem::Version
96
+ version: '11'
97
+ description: Basic file type checks based on a few header bytes
98
+ email: me@julik.nl
99
+ executables: []
100
+ extensions: []
101
+ extra_rdoc_files:
102
+ - README.md
103
+ files:
104
+ - Gemfile
105
+ - MIT_LICENSE.txt
106
+ - README.md
107
+ - Rakefile
108
+ - lib/magic_bytes.rb
109
+ - magic_bytes.gemspec
110
+ - spec/fixtures/fixture-0x20001.eot
111
+ - spec/fixtures/fixture-big-endian.tif
112
+ - spec/fixtures/fixture-imovie.mp4
113
+ - spec/fixtures/fixture-isom.mp4
114
+ - spec/fixtures/fixture-isomv2.mp4
115
+ - spec/fixtures/fixture-little-endian.tif
116
+ - spec/fixtures/fixture-otto.woff
117
+ - spec/fixtures/fixture-otto.woff2
118
+ - spec/fixtures/fixture.7z
119
+ - spec/fixtures/fixture.amr
120
+ - spec/fixtures/fixture.ar
121
+ - spec/fixtures/fixture.avi
122
+ - spec/fixtures/fixture.bmp
123
+ - spec/fixtures/fixture.bz2
124
+ - spec/fixtures/fixture.cab
125
+ - spec/fixtures/fixture.cr2
126
+ - spec/fixtures/fixture.crx
127
+ - spec/fixtures/fixture.deb
128
+ - spec/fixtures/fixture.dmg
129
+ - spec/fixtures/fixture.eot
130
+ - spec/fixtures/fixture.epub
131
+ - spec/fixtures/fixture.exe
132
+ - spec/fixtures/fixture.flac
133
+ - spec/fixtures/fixture.flv
134
+ - spec/fixtures/fixture.gif
135
+ - spec/fixtures/fixture.ico
136
+ - spec/fixtures/fixture.jpg
137
+ - spec/fixtures/fixture.jxr
138
+ - spec/fixtures/fixture.m4a
139
+ - spec/fixtures/fixture.m4v
140
+ - spec/fixtures/fixture.mid
141
+ - spec/fixtures/fixture.mkv
142
+ - spec/fixtures/fixture.mov
143
+ - spec/fixtures/fixture.mp3
144
+ - spec/fixtures/fixture.mp4
145
+ - spec/fixtures/fixture.mpg
146
+ - spec/fixtures/fixture.msi
147
+ - spec/fixtures/fixture.nes
148
+ - spec/fixtures/fixture.ogg
149
+ - spec/fixtures/fixture.opus
150
+ - spec/fixtures/fixture.otf
151
+ - spec/fixtures/fixture.pdf
152
+ - spec/fixtures/fixture.png
153
+ - spec/fixtures/fixture.ps
154
+ - spec/fixtures/fixture.psd
155
+ - spec/fixtures/fixture.rar
156
+ - spec/fixtures/fixture.rpm
157
+ - spec/fixtures/fixture.rtf
158
+ - spec/fixtures/fixture.sqlite
159
+ - spec/fixtures/fixture.swf
160
+ - spec/fixtures/fixture.tar
161
+ - spec/fixtures/fixture.tar.Z
162
+ - spec/fixtures/fixture.tar.gz
163
+ - spec/fixtures/fixture.tar.lz
164
+ - spec/fixtures/fixture.tar.xz
165
+ - spec/fixtures/fixture.ttf
166
+ - spec/fixtures/fixture.wav
167
+ - spec/fixtures/fixture.webm
168
+ - spec/fixtures/fixture.webp
169
+ - spec/fixtures/fixture.wmv
170
+ - spec/fixtures/fixture.woff
171
+ - spec/fixtures/fixture.woff2
172
+ - spec/fixtures/fixture.xpi
173
+ - spec/fixtures/fixture.zip
174
+ - spec/magic_bytes_spec.rb
175
+ homepage: https://github.com/julik/magic_bytes
176
+ licenses:
177
+ - MIT
178
+ metadata: {}
179
+ post_install_message:
180
+ rdoc_options: []
181
+ require_paths:
182
+ - lib
183
+ required_ruby_version: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ requirements: []
194
+ rubyforge_project:
195
+ rubygems_version: 2.2.2
196
+ signing_key:
197
+ specification_version: 4
198
+ summary: Basic file type checks based on a few header bytes
199
+ test_files: []