magikku 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.document +5 -0
- data/LICENSE +20 -0
- data/README.rdoc +18 -0
- data/Rakefile +61 -0
- data/VERSION +1 -0
- data/ext/magikku_native/extconf.rb +32 -0
- data/ext/magikku_native/magikku_native.c +412 -0
- data/lib/ffi/libmagic.rb +46 -0
- data/lib/magikku/convenience.rb +82 -0
- data/lib/magikku.rb +12 -0
- data/lib/magikku_ffi.rb +278 -0
- data/spec/magikku_behaviors.rb +288 -0
- data/spec/magikku_ffi_spec.rb +30 -0
- data/spec/magikku_spec.rb +10 -0
- data/spec/sample/fail_magicrules +1 -0
- data/spec/sample/rawtestdat.raw +2 -0
- data/spec/sample/ruby_magicrules +16 -0
- data/spec/sample/test.c +6 -0
- data/spec/sample/test.txt +3 -0
- data/spec/sample/test_magicrule +1 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +15 -0
- metadata +114 -0
data/lib/magikku_ffi.rb
ADDED
@@ -0,0 +1,278 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'ffi/libmagic'
|
3
|
+
|
4
|
+
require 'magikku/convenience'
|
5
|
+
|
6
|
+
# Note the implementation of this class may either be via FFI
|
7
|
+
# or via native C bindings depending on your installation and
|
8
|
+
# what version of ruby you are using.
|
9
|
+
class MagikkuFFI
|
10
|
+
extend MagikkuHelpers
|
11
|
+
|
12
|
+
# Defines various flags that can be passed when creating a magic scan object
|
13
|
+
# using Magikku.new or afterwards using Magikku.flags=
|
14
|
+
module Flags
|
15
|
+
# No flags
|
16
|
+
NONE = 0x000000
|
17
|
+
|
18
|
+
# Turn on debugging
|
19
|
+
DEBUG = 0x000001
|
20
|
+
|
21
|
+
# Follow symlinks
|
22
|
+
SYMLINK = 0x000002
|
23
|
+
|
24
|
+
# Check inside compressed files
|
25
|
+
COMPRESS = 0x000004
|
26
|
+
|
27
|
+
# Look at the contents of devices
|
28
|
+
DEVICES = 0x000008
|
29
|
+
|
30
|
+
# Return the MIME type
|
31
|
+
MIME_TYPE = 0x000010
|
32
|
+
|
33
|
+
# Return all matches
|
34
|
+
CONTINUE = 0x000020
|
35
|
+
|
36
|
+
# Print warnings to stderr
|
37
|
+
CHECK = 0x000040
|
38
|
+
|
39
|
+
# Restore access time on exit
|
40
|
+
PRESERVE_ATIME = 0x000080
|
41
|
+
|
42
|
+
# Don't translate unprintable chars
|
43
|
+
RAW = 0x000100
|
44
|
+
|
45
|
+
# Handle ENOENT etc as real errors
|
46
|
+
ERROR = 0x000200
|
47
|
+
|
48
|
+
# Return the MIME encoding
|
49
|
+
MIME_ENCODING = 0x000400
|
50
|
+
|
51
|
+
# alias for (MAGIC_MIME_TYPE|MAGIC_MIME_ENCODING)
|
52
|
+
MIME = (MIME_TYPE|MIME_ENCODING)
|
53
|
+
|
54
|
+
# Return the Apple creator and type
|
55
|
+
APPLE = 0x000800
|
56
|
+
|
57
|
+
# Don't check for compressed files
|
58
|
+
NO_CHECK_COMPRESS = 0x001000
|
59
|
+
|
60
|
+
# Don't check for tar files
|
61
|
+
NO_CHECK_TAR = 0x002000
|
62
|
+
|
63
|
+
# Don't check magic entries
|
64
|
+
NO_CHECK_SOFT = 0x004000
|
65
|
+
|
66
|
+
# Don't check application type
|
67
|
+
NO_CHECK_APPTYPE = 0x008000
|
68
|
+
|
69
|
+
# Don't check for elf details
|
70
|
+
NO_CHECK_ELF = 0x010000
|
71
|
+
|
72
|
+
# Don't check for text files
|
73
|
+
NO_CHECK_TEXT = 0x020000
|
74
|
+
|
75
|
+
# Don't check for cdf files
|
76
|
+
NO_CHECK_CDF = 0x040000
|
77
|
+
|
78
|
+
# Don't check tokens
|
79
|
+
NO_CHECK_TOKENS = 0x100000
|
80
|
+
|
81
|
+
# Don't check text encodings
|
82
|
+
NO_CHECK_ENCODING = 0x200000
|
83
|
+
|
84
|
+
# alias for NO_CHECK_TEXT
|
85
|
+
NO_CHECK_ASCII = NO_CHECK_TEXT
|
86
|
+
end
|
87
|
+
|
88
|
+
# Returns the default magic database path.
|
89
|
+
def self.path
|
90
|
+
FFI::Libmagic.magic_getpath(nil, 0)
|
91
|
+
end
|
92
|
+
|
93
|
+
# A base class for other Magikku error types
|
94
|
+
class MagikkuError < StandardError
|
95
|
+
end
|
96
|
+
|
97
|
+
# Raised when an error occurs during loading of a magic database.
|
98
|
+
class DbLoadError < MagikkuError
|
99
|
+
end
|
100
|
+
|
101
|
+
# Raised when an unexpected fatal error occurs initializing libmagic
|
102
|
+
class InitFatal < MagikkuError
|
103
|
+
end
|
104
|
+
|
105
|
+
# Raised when an error occurs during compiling of a magic database.
|
106
|
+
class CompileError < MagikkuError
|
107
|
+
end
|
108
|
+
|
109
|
+
# Raised when an error occurs when setting flags on a Magikku object.
|
110
|
+
class FlagError < MagikkuError
|
111
|
+
end
|
112
|
+
|
113
|
+
# Raised when an error occurs when setting flags on a Magikku object.
|
114
|
+
class ClosedError < MagikkuError
|
115
|
+
end
|
116
|
+
|
117
|
+
# Initializes a new libmagic data scanner
|
118
|
+
#
|
119
|
+
# @param [Hash,nil] params
|
120
|
+
# A hash of parameters or nil for defaults.
|
121
|
+
#
|
122
|
+
# @option params [Fixnum,nil] :flags
|
123
|
+
# Optional flags to magic (see MagikkuFFI::Flags).
|
124
|
+
# The flag values should be 'or'ed to gether with '|'.
|
125
|
+
# Default: NONE
|
126
|
+
#
|
127
|
+
# @option params [String, nil] :db
|
128
|
+
# Optional magicfile databases or un-compiled magic files.
|
129
|
+
# Default: the default system magic.mgc file.
|
130
|
+
#
|
131
|
+
# @see See MagikkuFFI::Flags and libmagic(3) manpage
|
132
|
+
# @see dbload()
|
133
|
+
def initialize(param = nil)
|
134
|
+
param ||= {}
|
135
|
+
raise(TypeError, "Invalid Type for params") if not param.is_a?(Hash)
|
136
|
+
|
137
|
+
flags = param[:flags] || Flags::NONE
|
138
|
+
raise(TypeError, "flags must be a Fixnum") if not flags.is_a?(Fixnum)
|
139
|
+
|
140
|
+
db = param[:db]
|
141
|
+
raise(TypeError, "db must be nil or a String") if db and not db.is_a?(String)
|
142
|
+
|
143
|
+
@_cookie = FFI::Libmagic.magic_open(flags)
|
144
|
+
if @_cookie.null?
|
145
|
+
raise(InitFatal, "magic_open(#{flags}) returned a null pointer")
|
146
|
+
end
|
147
|
+
|
148
|
+
if FFI::Libmagic.magic_load(_cookie, db) != 0
|
149
|
+
err = lasterror()
|
150
|
+
FFI::Libmagic.magic_close(_cookie)
|
151
|
+
raise(DbLoadError, "Error loading db: #{db.inspect} " << err)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Close the libmagic data scanner handle when you are finished with it
|
156
|
+
def close
|
157
|
+
FFI::Libmagic.magic_close(_cookie) unless @closed
|
158
|
+
|
159
|
+
@closed = true
|
160
|
+
return nil
|
161
|
+
end
|
162
|
+
|
163
|
+
def closed?
|
164
|
+
(@closed == true)
|
165
|
+
end
|
166
|
+
|
167
|
+
# Analyzes file contents against the magicfile database
|
168
|
+
#
|
169
|
+
# @param filename
|
170
|
+
# The path to a file to inspect
|
171
|
+
# @return [String]
|
172
|
+
# A textual description of the contents of the file
|
173
|
+
def file(filename)
|
174
|
+
File.stat(filename)
|
175
|
+
raise(TypeError, "filename must not be nil") if filename.nil?
|
176
|
+
FFI::Libmagic.magic_file(_cookie, filename)
|
177
|
+
end
|
178
|
+
|
179
|
+
# Analyzes a string buffer against the magicfile database
|
180
|
+
#
|
181
|
+
# @param filename
|
182
|
+
# The string buffer to inspect
|
183
|
+
# @return [String]
|
184
|
+
# A textual description of the contents the string
|
185
|
+
def string(str)
|
186
|
+
raise(TypeError, "wrong argument type #{str.class} (expected String)") unless str.is_a?(String)
|
187
|
+
p = FFI::MemoryPointer.new(str.size)
|
188
|
+
p.write_string_length(str, str.size)
|
189
|
+
FFI::Libmagic.magic_buffer(_cookie, p, str.size)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Used to load one or more magic databases.
|
193
|
+
#
|
194
|
+
# @param magicfiles
|
195
|
+
# One or more filenames seperated by colons. If nil, the default database
|
196
|
+
# is loaded.
|
197
|
+
# If uncompiled magic files are specified, they are compiled on the fly
|
198
|
+
# but they do not generate new .mgc files as with the compile method.
|
199
|
+
# Multiple files be specified by seperating them with colons.
|
200
|
+
#
|
201
|
+
# @raise [DbLoadError] if an error occurred loading the database(s)
|
202
|
+
def dbload(magicfiles)
|
203
|
+
if FFI::Libmagic.magic_load(_cookie, magicfiles) != 0
|
204
|
+
raise(DbLoadError, "Error loading db: #{magicfiles.inspect} " << lasterror())
|
205
|
+
else
|
206
|
+
return true
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
# Sets flags for the magic analyzer handle.
|
211
|
+
#
|
212
|
+
# @param flags
|
213
|
+
# Flags to to set for magic. See MagikkuFFI::Flags and libmagic(3) manpage.
|
214
|
+
# The flag values should be 'or'ed together with '|'.
|
215
|
+
# Using 0 will clear all flags.
|
216
|
+
def flags=(flags)
|
217
|
+
if FFI::Libmagic.magic_setflags(_cookie, flags) < 0
|
218
|
+
raise(FlagError, lasterror())
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
# Can be used to compile magic files. This does not load files, however. You must
|
223
|
+
# use dbload for that.
|
224
|
+
#
|
225
|
+
# Note: Errors and warnings may be displayed on stderr.
|
226
|
+
#
|
227
|
+
# @param [String,nil] filename
|
228
|
+
# A colon seperated list of filenames or a single filename.
|
229
|
+
# The compiled files created are generated in the current directory using
|
230
|
+
# the basename(1) of each file argument with ".mgc" appended to it.
|
231
|
+
# Directory names can be compiled, in which case the contents of the directory
|
232
|
+
# will be compiled together as a single .mgc file.
|
233
|
+
# nil compiles the default database.
|
234
|
+
#
|
235
|
+
# @return [true] if everything went well.
|
236
|
+
#
|
237
|
+
# @raise [CompileError] if an error occurred.
|
238
|
+
def compile(filenames)
|
239
|
+
if FFI::Libmagic.magic_compile(_cookie, filenames) != 0
|
240
|
+
raise(CompileError, "Error compiling #{filenames.inspect}: " << lasterror())
|
241
|
+
else
|
242
|
+
return true
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# Can be used to check the validity of magic files before compiling them.
|
247
|
+
# This is basically a dry-run that can be used before compiling magicfile
|
248
|
+
# databases.
|
249
|
+
#
|
250
|
+
# Note: Errors and warnings may be displayed on stderr.
|
251
|
+
#
|
252
|
+
# @param [String,nil] filename
|
253
|
+
# A colon seperated list of filenames or a single file. nil checks the
|
254
|
+
# default database.
|
255
|
+
#
|
256
|
+
# @return [true,false] Indicates whether the check was successful.
|
257
|
+
def check_syntax(filenames=nil)
|
258
|
+
return (FFI::Libmagic.magic_check(_cookie, filenames) == 0)
|
259
|
+
end
|
260
|
+
|
261
|
+
private
|
262
|
+
def _cookie
|
263
|
+
if @closed
|
264
|
+
raise(ClosedError, "This magic cookie is closed and can no longer be used")
|
265
|
+
else
|
266
|
+
@_cookie
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
def lasterror
|
271
|
+
FFI::Libmagic.magic_error(_cookie)
|
272
|
+
end
|
273
|
+
|
274
|
+
def lasterrno
|
275
|
+
FFI::Libmagic.magic_errno(_cookie)
|
276
|
+
end
|
277
|
+
|
278
|
+
end
|
@@ -0,0 +1,288 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
shared_examples_for "Magikku compiling interface" do
|
4
|
+
|
5
|
+
context "Initializing" do
|
6
|
+
it "should initialize cleanly without arguments" do
|
7
|
+
c=nil
|
8
|
+
lambda { c=@klass.new }.should_not raise_error
|
9
|
+
c.close if c
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should initialize cleanly when a flag argument is given" do
|
13
|
+
c=nil
|
14
|
+
lambda { c=@klass.new(:flags => @klass::Flags::NONE) }.should_not raise_error
|
15
|
+
c.close if c
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should initialize cleanly when a magicfile argument is given" do
|
19
|
+
c=nil
|
20
|
+
lambda { c=@klass.new(:db => @testrule) }.should_not raise_error
|
21
|
+
c.close
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should initialize cleanly when both arguments are given" do
|
25
|
+
c=nil
|
26
|
+
lambda {
|
27
|
+
c=@klass.new(:flags => @klass::Flags::NONE, :db => @testrule)
|
28
|
+
}.should_not raise_error
|
29
|
+
c.close if c
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
it "should raise an error when incorrect argument types are given" do
|
34
|
+
c=nil
|
35
|
+
lambda { c=@klass.new(nil) }.should_not raise_error()
|
36
|
+
c.close if c
|
37
|
+
c=nil
|
38
|
+
lambda { c=@klass.new(Object.new) }.should raise_error(TypeError)
|
39
|
+
c.close if c
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
it "should raise an error when the wrong argument count is given" do
|
44
|
+
c=nil
|
45
|
+
lambda { c=@klass.new(Hash.new,Object.new) }.should raise_error(ArgumentError)
|
46
|
+
c.close if c
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should raise an error when a nonexistant magic file is given" do
|
50
|
+
c=nil
|
51
|
+
lambda {
|
52
|
+
c=@klass.new(:db => sample_file('totallybogus'))
|
53
|
+
}.should raise_error(@klass::DbLoadError)
|
54
|
+
c.close if c
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should raise an error when a magic file format error occurs" do
|
58
|
+
c=nil
|
59
|
+
lambda {
|
60
|
+
c=@klass.new(:db => sample_file('fail_magicrules'))
|
61
|
+
}.should raise_error(@klass::DbLoadError)
|
62
|
+
c.close if c
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "An Instantiated Object" do
|
67
|
+
before :each do
|
68
|
+
@magic=@klass.new()
|
69
|
+
end
|
70
|
+
|
71
|
+
after :each do
|
72
|
+
@magic.close if not @magic.closed?
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should be able to identify file buffers" do
|
76
|
+
@magic.file(sample_file("test.txt")).should == "ASCII text"
|
77
|
+
@magic.file(sample_file("test.c")).should == "ASCII C program text"
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should be able to identify string buffers" do
|
81
|
+
@magic.string(File.read(sample_file("test.txt"))).should == "ASCII text"
|
82
|
+
@magic.string(File.read(sample_file("test.c"))).should == "ASCII C program text"
|
83
|
+
@magic.string("\x01\x02\x03\x04").should == "data"
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should be able to use flag options" do
|
87
|
+
@magic.flags = @klass::Flags::MIME
|
88
|
+
@magic.string(File.read(sample_file("test.txt"))).should == "text/plain; charset=us-ascii"
|
89
|
+
@magic.string(File.read(sample_file("test.c"))).should == "text/x-c; charset=us-ascii"
|
90
|
+
@magic.string("\x01\x02\x03\x04").should == "application/octet-stream; charset=binary"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should raise an error if a nonexistant file is specified to inspect" do
|
94
|
+
lambda{
|
95
|
+
@magic.file(sample_file('totallybogusfile'))
|
96
|
+
}.should raise_error(Errno::ENOENT)
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should raise an error when an incorrect object is passed to file()" do
|
100
|
+
lambda{ @magic.file(Object.new) }.should raise_error(TypeError)
|
101
|
+
lambda{ @magic.file(nil) }.should raise_error(TypeError)
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should raise an error when an incorrect object is passed to file()" do
|
105
|
+
lambda{ @magic.string(Object.new) }.should raise_error(TypeError)
|
106
|
+
lambda{ @magic.string(nil) }.should raise_error(TypeError)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "should be able to load magicrules databases" do
|
110
|
+
test_str="THISISARUBYMAGICTEST blah blah\nblah\x01\x02"
|
111
|
+
@magic.string(test_str).should_not == "RUBYMAGICTESTHIT"
|
112
|
+
@magic.dbload(sample_file('test_magicrule'))
|
113
|
+
@magic.string(test_str).should == "RUBYMAGICTESTHIT"
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should load the default magicrules database when nil is loaded" do
|
117
|
+
test_str="THISISARUBYMAGICTEST blah blah\nblah\x01\x02"
|
118
|
+
@magic.string(test_str).should_not == "RUBYMAGICTESTHIT"
|
119
|
+
@magic.string(test_str).should == "data"
|
120
|
+
@magic.dbload(nil)
|
121
|
+
@magic.string(test_str).should_not == "RUBYMAGICTESTHIT"
|
122
|
+
@magic.string(test_str).should == "data"
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should raise an error when loading an invalid filename" do
|
126
|
+
lambda{
|
127
|
+
@magic.dbload(sample_file('totallybogusfile'))
|
128
|
+
}.should raise_error(@klass::DbLoadError)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should raise an error when an incorrect object is passed to dbload()" do
|
132
|
+
lambda{
|
133
|
+
@magic.dbload(Object.new)
|
134
|
+
}.should raise_error(@argerror)
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should be able to be closed" do
|
138
|
+
lambda { @magic.close }.should_not raise_error
|
139
|
+
@magic.should be_closed
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should correctly indicate whether it is already closed" do
|
143
|
+
@magic.should_not be_closed
|
144
|
+
@magic.close
|
145
|
+
@magic.should be_closed
|
146
|
+
lambda { @magic.close }.should_not raise_error
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should not be usable after it is closed" do
|
150
|
+
@magic.close
|
151
|
+
lambda{
|
152
|
+
@magic.file(File.expand_path(__FILE__))
|
153
|
+
}.should raise_error(@klass::ClosedError)
|
154
|
+
|
155
|
+
lambda{
|
156
|
+
@magic.string("foo")
|
157
|
+
}.should raise_error(@klass::ClosedError)
|
158
|
+
|
159
|
+
lambda{
|
160
|
+
@magic.check_syntax(sample_file('fail_magicrules'))
|
161
|
+
}.should raise_error(@klass::ClosedError)
|
162
|
+
|
163
|
+
lambda{
|
164
|
+
@magic.compile(sample_file('fail_magicrules'))
|
165
|
+
}.should raise_error(@klass::ClosedError)
|
166
|
+
|
167
|
+
lambda{
|
168
|
+
@magic.check_syntax(sample_file('ruby_magicrules'))
|
169
|
+
}.should raise_error(@klass::ClosedError)
|
170
|
+
|
171
|
+
lambda{
|
172
|
+
@magic.compile(sample_file('ruby_magicrules'))
|
173
|
+
}.should raise_error(@klass::ClosedError)
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "Compiling And Convenience Methods" do
|
179
|
+
before :all do
|
180
|
+
@tmpdir = Dir.mktmpdir
|
181
|
+
end
|
182
|
+
|
183
|
+
before :each do
|
184
|
+
@origdir =Dir.pwd
|
185
|
+
Dir.chdir @tmpdir
|
186
|
+
|
187
|
+
@testrule = sample_file("ruby_magicrules")
|
188
|
+
@expect_mgc = "#{File.basename(@testrule)}.mgc"
|
189
|
+
|
190
|
+
File.should_not be_file(@expect_mgc)
|
191
|
+
end
|
192
|
+
|
193
|
+
after :each do
|
194
|
+
File.delete @expect_mgc if File.exists?(@expect_mgc)
|
195
|
+
Dir.chdir @origdir
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should work using the compile convenience class method" do
|
199
|
+
@klass.compile(@testrule).should == true
|
200
|
+
end
|
201
|
+
|
202
|
+
it "should work using an instantiated object" do
|
203
|
+
m=@klass.new
|
204
|
+
m.compile(@testrule).should == true
|
205
|
+
m.close
|
206
|
+
end
|
207
|
+
|
208
|
+
it "should raise an error when compiling an invalid filename" do
|
209
|
+
lambda{
|
210
|
+
@klass.compile(sample_file('totallnonexistantfile'))
|
211
|
+
}.should raise_error(@klass::CompileError)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should raise an error when compiling an syntactically incorrect filename" do
|
215
|
+
lambda{
|
216
|
+
@klass.compile(sample_file('fail_magicrules'))
|
217
|
+
}.should raise_error(@klass::CompileError)
|
218
|
+
end
|
219
|
+
|
220
|
+
it "should work using the check_syntax convenience class method" do
|
221
|
+
@klass.check_syntax(@testrule).should == true
|
222
|
+
File.should_not be_file(@expect_mgc)
|
223
|
+
@klass.check_syntax(@testrule).should == true
|
224
|
+
@klass.check_syntax(sample_file('fail_magicrules')).should == false
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should work when checking syntax using an instantiated object" do
|
228
|
+
m=@klass.new
|
229
|
+
m.check_syntax(@testrule).should == true
|
230
|
+
File.should_not be_file(@expect_mgc)
|
231
|
+
m.check_syntax(sample_file('fail_magicrules')).should == false
|
232
|
+
m.close
|
233
|
+
end
|
234
|
+
|
235
|
+
it "should return false when checking an invalid filename" do
|
236
|
+
@klass.check_syntax(sample_file('totallnonexistantfile')).should == false
|
237
|
+
m=@klass.new
|
238
|
+
m.check_syntax(sample_file('totallnonexistantfile')).should == false
|
239
|
+
m.close
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should check the default database when given a nil filename" do
|
243
|
+
@klass.check_syntax(nil).should == true
|
244
|
+
m=@klass.new
|
245
|
+
m.check_syntax(nil).should == true
|
246
|
+
m.close
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should return the default magic database with path()" do
|
250
|
+
@klass.path.should be_kind_of(String)
|
251
|
+
@klass.path.should_not be_empty
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should scan a file using the #{@klass}.file singleton method" do
|
255
|
+
@klass.file(sample_file('test.txt')).should == "ASCII text"
|
256
|
+
@klass.file(sample_file('test.c')).should == "ASCII C program text"
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should take initialization params as extra args to .file()" do
|
260
|
+
@klass.file(sample_file('test.txt'),
|
261
|
+
:flags => @klass::Flags::MIME).should == "text/plain; charset=us-ascii"
|
262
|
+
|
263
|
+
@klass.file(sample_file('rawtestdat.raw'), :db => nil).should == "data"
|
264
|
+
|
265
|
+
@klass.file(sample_file('rawtestdat.raw'), :db => sample_file('test_magicrule')).should == "RUBYMAGICTESTHIT"
|
266
|
+
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should scan a file using the #{@klass}.string singleton method" do
|
270
|
+
@klass.string(File.read(sample_file('test.txt'))).should == "ASCII text"
|
271
|
+
@klass.string(File.read(sample_file('test.c'))).should == "ASCII C program text"
|
272
|
+
end
|
273
|
+
|
274
|
+
it "should take initialization params as extra args to .string()" do
|
275
|
+
|
276
|
+
@klass.string(File.read(sample_file('test.txt')),
|
277
|
+
:flags => @klass::Flags::MIME).should == "text/plain; charset=us-ascii"
|
278
|
+
test_str="THISISARUBYMAGICTEST blah blah\nblah\x01\x02"
|
279
|
+
@klass.string(test_str).should_not == "RUBYMAGICTESTHIT"
|
280
|
+
|
281
|
+
@klass.string(test_str, :db => sample_file('test_magicrule')).should == "RUBYMAGICTESTHIT"
|
282
|
+
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'magikku_ffi'
|
3
|
+
|
4
|
+
if Magikku != MagikkuFFI
|
5
|
+
|
6
|
+
describe MagikkuFFI do
|
7
|
+
before :all do
|
8
|
+
@klass = MagikkuFFI
|
9
|
+
@argerror = ArgumentError
|
10
|
+
end
|
11
|
+
|
12
|
+
it_should_behave_like "Magikku compiling interface"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe MagikkuFFI::Flags do
|
16
|
+
context "Checking Values" do
|
17
|
+
Magikku::Flags.constants.each do |const|
|
18
|
+
it "should have the correct value for #{const}" do
|
19
|
+
Magikku::Flags.const_get(const).should == MagikkuFFI::Flags.const_get(const)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
else
|
25
|
+
describe "C Binding" do
|
26
|
+
it "was not compiled" do
|
27
|
+
pending "unable to test C bindings"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
bogus
|
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
#------------------------------------------------------------------------------
|
3
|
+
# $File: ruby,v 1.3 2009/09/19 16:28:12 christos Exp $
|
4
|
+
# ruby: file(1) magic for Ruby scripting language
|
5
|
+
# URL: http://www.ruby-lang.org/
|
6
|
+
# From: Reuben Thomas <rrt@sc3d.org>
|
7
|
+
|
8
|
+
# Ruby scripts
|
9
|
+
0 search/1/w #!\ /usr/bin/ruby Ruby script text executable
|
10
|
+
!:mime text/x-ruby
|
11
|
+
0 search/1/w #!\ /usr/local/bin/ruby Ruby script text executable
|
12
|
+
!:mime text/x-ruby
|
13
|
+
0 search/1 #!/usr/bin/env\ ruby Ruby script text executable
|
14
|
+
!:mime text/x-ruby
|
15
|
+
0 search/1 #!\ /usr/bin/env\ ruby Ruby script text executable
|
16
|
+
!:mime text/x-ruby
|
data/spec/sample/test.c
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0 string THISISARUBYMAGICTEST RUBYMAGICTESTHIT
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
require 'magikku'
|
4
|
+
require 'spec'
|
5
|
+
require 'spec/autorun'
|
6
|
+
|
7
|
+
require 'magikku_behaviors'
|
8
|
+
|
9
|
+
def sample_file(filename)
|
10
|
+
return File.expand_path(File.join(File.dirname(__FILE__), "sample", filename))
|
11
|
+
end
|
12
|
+
|
13
|
+
Spec::Runner.configure do |config|
|
14
|
+
|
15
|
+
end
|