ruby-filemagic 0.5.2 → 0.6.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.
- checksums.yaml +4 -4
- data/ChangeLog +12 -0
- data/README +3 -2
- data/Rakefile +17 -15
- data/ext/filemagic/filemagic.c +93 -165
- data/ext/filemagic/filemagic.h +65 -15
- data/lib/filemagic.rb +37 -7
- data/lib/filemagic/version.rb +2 -2
- data/test/filemagic_test.rb +22 -12
- metadata +29 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1403f497e908d066aeaeb6d235b1b947de376a3f
|
4
|
+
data.tar.gz: 546e5fa1ac73f1a69ebee0f9347ffc2171ebe65d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1ea4401b1fcc93e015d4e7049928bc95381013f4e915f0e3a02ca30476d5f3a0454408b8da9ac875bf62427e6237630ac4cd8db2025347a86dae7ae04a65f004
|
7
|
+
data.tar.gz: 616165278b30cd859741a4a76dc752b6a798f5ac93951e294e0f4a5aaf228648f977d98899f165ccf28dfcc275cf087e6a7353f90f0511db32cfe4a60a04cde5
|
data/ChangeLog
CHANGED
@@ -2,6 +2,18 @@
|
|
2
2
|
|
3
3
|
= Revision history for ruby-filemagic
|
4
4
|
|
5
|
+
== 0.6.0 [2014-05-16]
|
6
|
+
|
7
|
+
* Required Ruby version >= 1.9.3.
|
8
|
+
* New method FileMagic#list (+magic_list+).
|
9
|
+
* New method FileMagic#load (+magic_load+).
|
10
|
+
* New method FileMagic.path (+magic_getpath+).
|
11
|
+
* New method FileMagic.magic_version.
|
12
|
+
* New method FileMagic.flags.
|
13
|
+
* New flag +no_check_builtin+.
|
14
|
+
* Tests print libmagic version and path.
|
15
|
+
* Internal refactoring.
|
16
|
+
|
5
17
|
== 0.5.2 [2014-04-24]
|
6
18
|
|
7
19
|
* Use MAGIC_VERSION if available.
|
data/README
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
== VERSION
|
4
4
|
|
5
|
-
This documentation refers to filemagic version 0.
|
5
|
+
This documentation refers to filemagic version 0.6.0
|
6
6
|
|
7
7
|
|
8
8
|
== DESCRIPTION
|
@@ -43,9 +43,10 @@ Travis
|
|
43
43
|
== LINKS
|
44
44
|
|
45
45
|
Homepage:: http://www.darwinsys.com/file/
|
46
|
-
Documentation:: https://blackwinter.github.
|
46
|
+
Documentation:: https://blackwinter.github.com/ruby-filemagic
|
47
47
|
Source code:: https://github.com/blackwinter/ruby-filemagic
|
48
48
|
RubyGem:: https://rubygems.org/gems/ruby-filemagic
|
49
|
+
Travis CI:: https://travis-ci.org/blackwinter/ruby-filemagic
|
49
50
|
|
50
51
|
|
51
52
|
== AUTHORS
|
data/Rakefile
CHANGED
@@ -4,21 +4,23 @@ begin
|
|
4
4
|
require 'hen'
|
5
5
|
|
6
6
|
Hen.lay! {{
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
13
|
-
:
|
14
|
-
:
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
}
|
7
|
+
gem: {
|
8
|
+
name: %q{ruby-filemagic},
|
9
|
+
version: FileMagic::VERSION,
|
10
|
+
summary: 'Ruby bindings to the magic(4) library',
|
11
|
+
authors: ['Travis Whitton', 'Jens Wille'],
|
12
|
+
email: 'jens.wille@gmail.com',
|
13
|
+
license: %q{Ruby},
|
14
|
+
homepage: :blackwinter,
|
15
|
+
extra_files: FileList['info/*'].to_a,
|
16
|
+
dependencies: %w[],
|
17
|
+
extension: {
|
18
|
+
name: 'ruby_filemagic',
|
19
|
+
ext_name: 'filemagic',
|
20
|
+
cross_compile: false
|
21
|
+
},
|
22
|
+
|
23
|
+
required_ruby_version: '>= 1.9.3'
|
22
24
|
}
|
23
25
|
}}
|
24
26
|
rescue LoadError => err
|
data/ext/filemagic/filemagic.c
CHANGED
@@ -1,28 +1,62 @@
|
|
1
|
-
|
1
|
+
#include "filemagic.h"
|
2
2
|
|
3
|
-
|
3
|
+
/* Returns the magic path */
|
4
|
+
static VALUE
|
5
|
+
rb_magic_getpath(VALUE klass) {
|
6
|
+
return rb_str_new2(magic_getpath(NULL, 0));
|
7
|
+
}
|
4
8
|
|
5
|
-
|
6
|
-
|
9
|
+
/* Converts flags to integer */
|
10
|
+
static VALUE
|
11
|
+
rb_magic_flags(VALUE klass, VALUE flags) {
|
12
|
+
VALUE map = rb_const_get(cFileMagic, rb_intern("FLAGS_BY_SYM")), f, g;
|
13
|
+
int i = MAGIC_NONE, j;
|
7
14
|
|
8
|
-
|
9
|
-
|
15
|
+
if (TYPE(flags) != T_ARRAY) {
|
16
|
+
rb_raise(rb_eTypeError,
|
17
|
+
"wrong argument type %s (expected Array)",
|
18
|
+
rb_obj_classname(flags));
|
19
|
+
}
|
10
20
|
|
11
|
-
|
12
|
-
|
21
|
+
for (j = 0; j < RARRAY_LEN(flags); j++) {
|
22
|
+
f = rb_ary_entry(flags, j);
|
13
23
|
|
14
|
-
|
24
|
+
switch (TYPE(f)) {
|
25
|
+
case T_SYMBOL:
|
26
|
+
if (RTEST(g = rb_hash_aref(map, f))) {
|
27
|
+
f = g;
|
28
|
+
/* fall through */
|
29
|
+
}
|
30
|
+
else {
|
31
|
+
f = rb_funcall(f, rb_intern("inspect"), 0);
|
32
|
+
rb_raise(rb_eArgError, "%s: %s",
|
33
|
+
NIL_P(g) ? "no such flag" : "flag not available",
|
34
|
+
StringValueCStr(f));
|
15
35
|
|
16
|
-
|
36
|
+
break;
|
37
|
+
}
|
38
|
+
case T_FIXNUM:
|
39
|
+
i |= NUM2INT(f);
|
40
|
+
break;
|
41
|
+
default:
|
42
|
+
rb_raise(rb_eTypeError,
|
43
|
+
"wrong argument type %s (expected Fixnum or Symbol)",
|
44
|
+
rb_obj_classname(f));
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
return INT2FIX(i);
|
49
|
+
}
|
17
50
|
|
18
51
|
/* FileMagic.new */
|
19
52
|
static VALUE
|
20
|
-
rb_magic_new(int argc, VALUE *argv, VALUE
|
53
|
+
rb_magic_new(int argc, VALUE *argv, VALUE klass) {
|
21
54
|
VALUE obj, args[2];
|
22
|
-
magic_t
|
55
|
+
magic_t ms;
|
23
56
|
|
24
57
|
if (rb_block_given_p()) {
|
25
|
-
rb_warn(
|
58
|
+
rb_warn(
|
59
|
+
"FileMagic.new() does not take a block; use FileMagic.open() instead");
|
26
60
|
}
|
27
61
|
|
28
62
|
if (argc > 0 && TYPE(args[1] = argv[argc - 1]) == T_HASH) {
|
@@ -32,22 +66,29 @@ rb_magic_new(int argc, VALUE *argv, VALUE class) {
|
|
32
66
|
args[1] = rb_hash_new();
|
33
67
|
}
|
34
68
|
|
35
|
-
args[0] =
|
69
|
+
args[0] = rb_magic_flags(klass, rb_ary_new4(argc, argv));
|
36
70
|
|
37
|
-
if ((
|
38
|
-
|
71
|
+
if ((ms = magic_open(NUM2INT(args[0]))) == NULL) {
|
72
|
+
rb_raise(rb_FileMagicError,
|
73
|
+
"failed to initialize magic cookie (%d)", errno || -1);
|
39
74
|
}
|
40
75
|
|
41
|
-
if (magic_load(
|
42
|
-
|
76
|
+
if (magic_load(ms, NULL) == -1) {
|
77
|
+
rb_raise(rb_FileMagicError,
|
78
|
+
"failed to load database: %s", magic_error(ms));
|
43
79
|
}
|
44
80
|
|
45
|
-
obj = Data_Wrap_Struct(
|
81
|
+
obj = Data_Wrap_Struct(klass, 0, rb_magic_free, ms);
|
46
82
|
rb_obj_call_init(obj, 2, args);
|
47
83
|
|
48
84
|
return obj;
|
49
85
|
}
|
50
86
|
|
87
|
+
static void
|
88
|
+
rb_magic_free(magic_t ms) {
|
89
|
+
magic_close(ms);
|
90
|
+
}
|
91
|
+
|
51
92
|
static VALUE
|
52
93
|
rb_magic_init(int argc, VALUE *argv, VALUE self) {
|
53
94
|
VALUE flags, options, keys, k, m;
|
@@ -58,16 +99,14 @@ rb_magic_init(int argc, VALUE *argv, VALUE self) {
|
|
58
99
|
options = rb_hash_new();
|
59
100
|
}
|
60
101
|
|
61
|
-
rb_iv_set(self, "
|
102
|
+
rb_iv_set(self, "iflags", flags);
|
62
103
|
rb_iv_set(self, "closed", Qfalse);
|
63
104
|
|
64
105
|
keys = rb_funcall(options, rb_intern("keys"), 0);
|
65
106
|
|
66
107
|
for (i = 0; i < RARRAY_LEN(keys); i++) {
|
67
|
-
k =
|
68
|
-
m =
|
69
|
-
rb_intern("+"), 1, rb_str_new2("=")
|
70
|
-
);
|
108
|
+
k = rb_ary_entry(keys, i);
|
109
|
+
m = rb_str_plus(rb_obj_as_string(k), rb_str_new2("="));
|
71
110
|
|
72
111
|
if (rb_respond_to(self, mid = rb_intern(StringValueCStr(m)))) {
|
73
112
|
rb_funcall(self, mid, 1, rb_hash_aref(options, k));
|
@@ -84,17 +123,17 @@ rb_magic_init(int argc, VALUE *argv, VALUE self) {
|
|
84
123
|
/* Frees resources allocated */
|
85
124
|
static VALUE
|
86
125
|
rb_magic_close(VALUE self) {
|
87
|
-
magic_t
|
126
|
+
magic_t ms;
|
88
127
|
|
89
128
|
if (RTEST(rb_magic_closed_p(self))) {
|
90
129
|
return Qnil;
|
91
130
|
}
|
92
131
|
|
93
|
-
|
94
|
-
|
132
|
+
GetMagicSet(self, ms);
|
133
|
+
rb_magic_free(ms);
|
95
134
|
|
96
135
|
/* This keeps rb_magic_free from trying to free closed objects */
|
97
|
-
|
136
|
+
DATA_PTR(self) = NULL;
|
98
137
|
|
99
138
|
rb_iv_set(self, "closed", Qtrue);
|
100
139
|
|
@@ -107,49 +146,17 @@ rb_magic_closed_p(VALUE self) {
|
|
107
146
|
}
|
108
147
|
|
109
148
|
/* Return a string describing file */
|
110
|
-
|
111
|
-
rb_magic_file(int argc, VALUE *argv, VALUE self) {
|
112
|
-
VALUE file, s;
|
113
|
-
const char *m;
|
114
|
-
magic_t cookie;
|
115
|
-
|
116
|
-
rb_scan_args(argc, argv, "11", &file, &s);
|
117
|
-
|
118
|
-
m = StringValuePtr(file);
|
119
|
-
GetMagicCookie(self, cookie);
|
120
|
-
|
121
|
-
if ((m = magic_file(cookie, m)) == NULL) {
|
122
|
-
rb_raise(rb_FileMagicError, "%s", magic_error(cookie));
|
123
|
-
}
|
124
|
-
|
125
|
-
return rb_magic_apply_simple(self, m, s);
|
126
|
-
}
|
149
|
+
RB_MAGIC_TYPE(file, FILE)
|
127
150
|
|
128
151
|
/* Return a string describing the string buffer */
|
129
|
-
|
130
|
-
rb_magic_buffer(int argc, VALUE *argv, VALUE self) {
|
131
|
-
VALUE buffer, s;
|
132
|
-
const char *m;
|
133
|
-
magic_t cookie;
|
134
|
-
|
135
|
-
rb_scan_args(argc, argv, "11", &buffer, &s);
|
136
|
-
|
137
|
-
m = StringValuePtr(buffer);
|
138
|
-
GetMagicCookie(self, cookie);
|
139
|
-
|
140
|
-
if ((m = magic_buffer(cookie, m, RSTRING_LEN(buffer))) == NULL) {
|
141
|
-
rb_raise(rb_FileMagicError, "%s", magic_error(cookie));
|
142
|
-
}
|
143
|
-
|
144
|
-
return rb_magic_apply_simple(self, m, s);
|
145
|
-
}
|
152
|
+
RB_MAGIC_TYPE(buffer, BUFFER)
|
146
153
|
|
147
154
|
/* Get the flags as array of symbols */
|
148
155
|
static VALUE
|
149
156
|
rb_magic_getflags(VALUE self) {
|
150
157
|
VALUE ary = rb_ary_new();
|
151
158
|
VALUE map = rb_const_get(cFileMagic, rb_intern("FLAGS_BY_INT"));
|
152
|
-
int i = NUM2INT(rb_attr_get(self, rb_intern("
|
159
|
+
int i = NUM2INT(rb_attr_get(self, rb_intern("iflags"))), j = 0;
|
153
160
|
|
154
161
|
while ((i -= j) > 0) {
|
155
162
|
j = pow(2, (int)(log(i) / log(2)));
|
@@ -159,117 +166,30 @@ rb_magic_getflags(VALUE self) {
|
|
159
166
|
return ary;
|
160
167
|
}
|
161
168
|
|
162
|
-
/* Set flags on the
|
169
|
+
/* Set flags on the ms object */
|
163
170
|
static VALUE
|
164
171
|
rb_magic_setflags(VALUE self, VALUE flags) {
|
165
|
-
|
166
|
-
magic_t cookie;
|
172
|
+
magic_t ms;
|
167
173
|
|
168
|
-
|
169
|
-
flags = rb_magic_flags_to_int(flags);
|
170
|
-
rb_iv_set(self, "_flags", flags);
|
174
|
+
GetMagicSet(self, ms);
|
171
175
|
|
172
|
-
|
173
|
-
|
176
|
+
rb_iv_set(self, "iflags",
|
177
|
+
flags = rb_magic_flags(CLASS_OF(self), rb_Array(flags)));
|
174
178
|
|
175
|
-
return INT2FIX(
|
179
|
+
return INT2FIX(magic_setflags(ms, NUM2INT(flags)));
|
176
180
|
}
|
177
181
|
|
178
|
-
/*
|
179
|
-
|
180
|
-
rb_magic_check(int argc, VALUE *argv, VALUE self) {
|
181
|
-
VALUE s;
|
182
|
-
const char *file;
|
183
|
-
int retval;
|
184
|
-
magic_t cookie;
|
182
|
+
/* Lists a magic database file */
|
183
|
+
RB_MAGIC_APPRENTICE(list)
|
185
184
|
|
186
|
-
|
185
|
+
/* Loads a magic database file */
|
186
|
+
RB_MAGIC_APPRENTICE(load)
|
187
187
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
return INT2FIX(retval);
|
192
|
-
}
|
188
|
+
/* Checks validity of a magic database file */
|
189
|
+
RB_MAGIC_APPRENTICE(check)
|
193
190
|
|
194
191
|
/* Compiles a magic database file */
|
195
|
-
|
196
|
-
rb_magic_compile(VALUE self, VALUE file) {
|
197
|
-
int retval;
|
198
|
-
const char *m;
|
199
|
-
magic_t cookie;
|
200
|
-
|
201
|
-
GetMagicCookie(self, cookie);
|
202
|
-
m = StringValuePtr(file);
|
203
|
-
retval = magic_compile(cookie, m);
|
204
|
-
|
205
|
-
return INT2FIX(retval);
|
206
|
-
}
|
207
|
-
|
208
|
-
static VALUE
|
209
|
-
rb_magic_flags_to_int(VALUE ary) {
|
210
|
-
VALUE map = rb_const_get(cFileMagic, rb_intern("FLAGS_BY_SYM"));
|
211
|
-
VALUE f, g;
|
212
|
-
int i = MAGIC_NONE, j;
|
213
|
-
|
214
|
-
for (j = 0; j < RARRAY_LEN(ary); j++) {
|
215
|
-
f = rb_ary_entry(ary, j);
|
216
|
-
|
217
|
-
switch (TYPE(f)) {
|
218
|
-
case T_SYMBOL:
|
219
|
-
if (RTEST(g = rb_hash_aref(map, f))) {
|
220
|
-
f = g;
|
221
|
-
/* fall through */
|
222
|
-
}
|
223
|
-
else {
|
224
|
-
f = rb_funcall(f, rb_intern("inspect"), 0);
|
225
|
-
rb_raise(rb_eArgError,
|
226
|
-
"%s: %s",
|
227
|
-
NIL_P(g) ? "no such flag" : "flag not available",
|
228
|
-
StringValueCStr(f)
|
229
|
-
);
|
230
|
-
break;
|
231
|
-
}
|
232
|
-
case T_FIXNUM:
|
233
|
-
i |= NUM2INT(f);
|
234
|
-
break;
|
235
|
-
default:
|
236
|
-
rb_raise(rb_eTypeError,
|
237
|
-
"wrong argument type %s (expected Fixnum or Symbol)",
|
238
|
-
rb_obj_classname(f)
|
239
|
-
);
|
240
|
-
}
|
241
|
-
}
|
242
|
-
|
243
|
-
return INT2FIX(i);
|
244
|
-
}
|
245
|
-
|
246
|
-
static VALUE
|
247
|
-
rb_magic_apply_simple(VALUE self, const char *m, VALUE s) {
|
248
|
-
VALUE str = rb_str_new2(m);
|
249
|
-
|
250
|
-
if (RTEST(NIL_P(s) ? rb_attr_get(self, rb_intern("@simplified")) : s)) {
|
251
|
-
rb_funcall(str, rb_intern("downcase!"), 0);
|
252
|
-
|
253
|
-
return rb_funcall(str, rb_intern("slice"), 2,
|
254
|
-
rb_const_get(cFileMagic, rb_intern("SIMPLE_RE")),
|
255
|
-
INT2FIX(1)
|
256
|
-
);
|
257
|
-
}
|
258
|
-
else {
|
259
|
-
return str;
|
260
|
-
}
|
261
|
-
}
|
262
|
-
|
263
|
-
/*
|
264
|
-
GC never seems to happen until the program terminates, but this is called
|
265
|
-
on any unclosed objects
|
266
|
-
*/
|
267
|
-
static void
|
268
|
-
rb_magic_free(magic_t cookie) {
|
269
|
-
magic_close(cookie);
|
270
|
-
}
|
271
|
-
|
272
|
-
#define RB_MAGIC_SET_VERSION(m, p) sprintf(version, "%d.%02d", m, p);
|
192
|
+
RB_MAGIC_APPRENTICE(compile)
|
273
193
|
|
274
194
|
void
|
275
195
|
Init_ruby_filemagic() {
|
@@ -284,7 +204,9 @@ Init_ruby_filemagic() {
|
|
284
204
|
|
285
205
|
rb_define_const(cFileMagic, "MAGIC_VERSION", rb_str_new2(version));
|
286
206
|
|
287
|
-
rb_define_singleton_method(cFileMagic, "
|
207
|
+
rb_define_singleton_method(cFileMagic, "path", rb_magic_getpath, 0);
|
208
|
+
rb_define_singleton_method(cFileMagic, "flags", rb_magic_flags, 1);
|
209
|
+
rb_define_singleton_method(cFileMagic, "new", rb_magic_new, -1);
|
288
210
|
|
289
211
|
rb_define_method(cFileMagic, "initialize", rb_magic_init, -1);
|
290
212
|
rb_define_method(cFileMagic, "close", rb_magic_close, 0);
|
@@ -293,8 +215,10 @@ Init_ruby_filemagic() {
|
|
293
215
|
rb_define_method(cFileMagic, "buffer", rb_magic_buffer, -1);
|
294
216
|
rb_define_method(cFileMagic, "flags", rb_magic_getflags, 0);
|
295
217
|
rb_define_method(cFileMagic, "flags=", rb_magic_setflags, 1);
|
218
|
+
rb_define_method(cFileMagic, "list", rb_magic_list, -1);
|
219
|
+
rb_define_method(cFileMagic, "load", rb_magic_load, -1);
|
296
220
|
rb_define_method(cFileMagic, "check", rb_magic_check, -1);
|
297
|
-
rb_define_method(cFileMagic, "compile", rb_magic_compile,
|
221
|
+
rb_define_method(cFileMagic, "compile", rb_magic_compile, -1);
|
298
222
|
|
299
223
|
rb_alias(cFileMagic, rb_intern("valid?"), rb_intern("check"));
|
300
224
|
|
@@ -369,6 +293,10 @@ Init_ruby_filemagic() {
|
|
369
293
|
#ifdef MAGIC_NO_CHECK_ENCODING
|
370
294
|
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_ENCODING", INT2FIX(MAGIC_NO_CHECK_ENCODING));
|
371
295
|
#endif
|
296
|
+
#if defined(MAGIC_NO_CHECK_BUILTIN) && MAGIC_VERSION > 514
|
297
|
+
/* defined in b5be901 (2010-01-28, 5.05), but broken until 38e0136 (2013-08-15, 5.15) */
|
298
|
+
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_BUILTIN", INT2FIX(MAGIC_NO_CHECK_BUILTIN));
|
299
|
+
#endif
|
372
300
|
#ifdef MAGIC_NO_CHECK_ASCII
|
373
301
|
rb_define_const(cFileMagic, "MAGIC_NO_CHECK_ASCII", INT2FIX(MAGIC_NO_CHECK_ASCII));
|
374
302
|
#endif
|
data/ext/filemagic/filemagic.h
CHANGED
@@ -3,46 +3,96 @@
|
|
3
3
|
|
4
4
|
#include "ruby.h"
|
5
5
|
#include <math.h>
|
6
|
+
#include <errno.h>
|
6
7
|
#include <magic.h>
|
7
8
|
#ifdef HAVE_FILE_PATCHLEVEL_H
|
8
9
|
#include <file/patchlevel.h>
|
9
10
|
#endif
|
10
11
|
|
11
|
-
|
12
|
-
#ifndef RSTRING_LEN
|
13
|
-
#define RSTRING_LEN(s) (RSTRING(s)->len)
|
14
|
-
#endif
|
15
|
-
#ifndef RARRAY_LEN
|
16
|
-
#define RARRAY_LEN(s) (RARRAY(s)->len)
|
17
|
-
#endif
|
18
|
-
|
19
|
-
#define GetMagicCookie(obj, cookie) {\
|
12
|
+
#define GetMagicSet(obj, ms) {\
|
20
13
|
if (RTEST(rb_magic_closed_p(obj))) {\
|
21
14
|
rb_raise(rb_eRuntimeError, "closed stream");\
|
22
15
|
}\
|
23
16
|
else {\
|
24
|
-
Data_Get_Struct((obj), struct magic_set, (
|
17
|
+
Data_Get_Struct((obj), struct magic_set, (ms));\
|
18
|
+
}\
|
19
|
+
}
|
20
|
+
|
21
|
+
#define RB_MAGIC_TYPE_FILE magic_file(ms, str)
|
22
|
+
#define RB_MAGIC_TYPE_BUFFER magic_buffer(ms, str, RSTRING_LEN(arg))
|
23
|
+
|
24
|
+
#define RB_MAGIC_TYPE(what, WHAT) \
|
25
|
+
static VALUE \
|
26
|
+
rb_magic_##what(int argc, VALUE *argv, VALUE self) {\
|
27
|
+
VALUE arg, simple, res;\
|
28
|
+
const char *str, *type;\
|
29
|
+
magic_t ms;\
|
30
|
+
\
|
31
|
+
rb_scan_args(argc, argv, "11", &arg, &simple);\
|
32
|
+
\
|
33
|
+
str = StringValuePtr(arg);\
|
34
|
+
GetMagicSet(self, ms);\
|
35
|
+
\
|
36
|
+
if ((type = RB_MAGIC_TYPE_##WHAT) == NULL) {\
|
37
|
+
rb_raise(rb_FileMagicError, "failed lookup: %s", magic_error(ms));\
|
38
|
+
}\
|
39
|
+
\
|
40
|
+
res = rb_str_new2(type);\
|
41
|
+
\
|
42
|
+
if (NIL_P(simple)) {\
|
43
|
+
simple = rb_attr_get(self, rb_intern("@simplified"));\
|
44
|
+
}\
|
45
|
+
\
|
46
|
+
if (RTEST(simple)) {\
|
47
|
+
rb_funcall(res, rb_intern("downcase!"), 0);\
|
48
|
+
\
|
49
|
+
return rb_funcall(res, rb_intern("slice"), 2,\
|
50
|
+
rb_const_get(cFileMagic, rb_intern("SIMPLE_RE")), INT2FIX(1));\
|
51
|
+
}\
|
52
|
+
else {\
|
53
|
+
return res;\
|
25
54
|
}\
|
26
55
|
}
|
27
56
|
|
57
|
+
#define RB_MAGIC_APPRENTICE(what) \
|
58
|
+
static VALUE \
|
59
|
+
rb_magic_##what(int argc, VALUE *argv, VALUE self) {\
|
60
|
+
VALUE str;\
|
61
|
+
const char *file;\
|
62
|
+
magic_t ms;\
|
63
|
+
\
|
64
|
+
file = rb_scan_args(argc, argv, "01", &str) == 1 ? StringValuePtr(str) : NULL;\
|
65
|
+
\
|
66
|
+
GetMagicSet(self, ms);\
|
67
|
+
\
|
68
|
+
return magic_##what(ms, file) ? Qfalse : Qtrue;\
|
69
|
+
}
|
70
|
+
|
71
|
+
#define RB_MAGIC_SET_VERSION(m, p) sprintf(version, "%d.%02d", m, p);
|
72
|
+
|
28
73
|
static VALUE cFileMagic, rb_FileMagicError;
|
29
74
|
|
75
|
+
static VALUE rb_magic_getpath(VALUE);
|
76
|
+
static VALUE rb_magic_flags(VALUE, VALUE);
|
77
|
+
|
30
78
|
static VALUE rb_magic_new(int, VALUE*, VALUE);
|
79
|
+
static void rb_magic_free(magic_t);
|
31
80
|
static VALUE rb_magic_init(int, VALUE*, VALUE);
|
32
81
|
|
33
82
|
static VALUE rb_magic_close(VALUE);
|
34
83
|
static VALUE rb_magic_closed_p(VALUE);
|
84
|
+
|
35
85
|
static VALUE rb_magic_file(int, VALUE*, VALUE);
|
36
86
|
static VALUE rb_magic_buffer(int, VALUE*, VALUE);
|
87
|
+
|
37
88
|
static VALUE rb_magic_getflags(VALUE);
|
38
89
|
static VALUE rb_magic_setflags(VALUE, VALUE);
|
39
|
-
static VALUE rb_magic_check(int, VALUE*, VALUE);
|
40
|
-
static VALUE rb_magic_compile(VALUE, VALUE);
|
41
90
|
|
42
|
-
static VALUE
|
43
|
-
static VALUE
|
91
|
+
static VALUE rb_magic_list(int, VALUE*, VALUE);
|
92
|
+
static VALUE rb_magic_load(int, VALUE*, VALUE);
|
93
|
+
static VALUE rb_magic_check(int, VALUE*, VALUE);
|
94
|
+
static VALUE rb_magic_compile(int, VALUE*, VALUE);
|
44
95
|
|
45
|
-
static void rb_magic_free(magic_t);
|
46
96
|
void Init_ruby_filemagic(void);
|
47
97
|
|
48
98
|
#endif /* FILEMAGIC_H */
|
data/lib/filemagic.rb
CHANGED
@@ -28,7 +28,12 @@ class FileMagic
|
|
28
28
|
:no_check_cdf, # Don't check for cdf files
|
29
29
|
:no_check_tokens, # Don't check ascii/tokens
|
30
30
|
:no_check_encoding, # Don't check text encodings
|
31
|
+
:no_check_builtin, # No built-in tests; only consult the magic file
|
32
|
+
|
33
|
+
# Defined for backwards compatibility (renamed)
|
31
34
|
:no_check_ascii, # MAGIC_NO_CHECK_TEXT
|
35
|
+
|
36
|
+
# Defined for backwards compatibility; do nothing
|
32
37
|
:no_check_fortran, # Don't check ascii/fortran
|
33
38
|
:no_check_troff # Don't check ascii/troff
|
34
39
|
].inject({}) { |flags, flag|
|
@@ -42,22 +47,22 @@ class FileMagic
|
|
42
47
|
# Extract "simple" MIME type.
|
43
48
|
SIMPLE_RE = %r{([.\w\/-]+)}
|
44
49
|
|
45
|
-
@fm =
|
46
|
-
fm.key?(key = flags.to_s) ? fm[key] : fm[key] = new(*flags)
|
47
|
-
}
|
50
|
+
@fm = {}
|
48
51
|
|
49
52
|
class << self
|
50
53
|
|
51
54
|
# Provide a "magic singleton".
|
52
55
|
def fm(*flags)
|
53
|
-
|
54
|
-
|
56
|
+
if fm = @fm[flags = flags(flags)]
|
57
|
+
return fm unless fm.closed?
|
58
|
+
end
|
59
|
+
|
60
|
+
@fm[flags] = new(flags)
|
55
61
|
end
|
56
62
|
|
57
63
|
# Clear our instance cache.
|
58
64
|
def clear!
|
59
|
-
@fm.each_value
|
60
|
-
@fm.clear
|
65
|
+
@fm.each_value(&:close).clear
|
61
66
|
end
|
62
67
|
|
63
68
|
# Just like #new, but takes an optional block, in which case #close
|
@@ -81,6 +86,31 @@ class FileMagic
|
|
81
86
|
open(:mime, *flags, &block)
|
82
87
|
end
|
83
88
|
|
89
|
+
def magic_version(default = MAGIC_VERSION)
|
90
|
+
default != '0' ? default :
|
91
|
+
user_magic_version ||
|
92
|
+
auto_magic_version ||
|
93
|
+
[default, 'unknown']
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def user_magic_version(key = 'MAGIC_VERSION')
|
99
|
+
[ENV[key], 'user-specified'] if ENV[key]
|
100
|
+
end
|
101
|
+
|
102
|
+
def auto_magic_version
|
103
|
+
require 'nuggets/file/which'
|
104
|
+
|
105
|
+
if cmd = File.which_command([
|
106
|
+
'dpkg-query -f \'${Version}\' -W libmagic-dev',
|
107
|
+
'file -v'
|
108
|
+
])
|
109
|
+
[%x{#{cmd}}[/\d+\.\d+/], 'auto-detected']
|
110
|
+
end
|
111
|
+
rescue LoadError
|
112
|
+
end
|
113
|
+
|
84
114
|
end
|
85
115
|
|
86
116
|
attr_writer :simplified
|
data/lib/filemagic/version.rb
CHANGED
data/test/filemagic_test.rb
CHANGED
@@ -3,15 +3,16 @@ require 'filemagic'
|
|
3
3
|
|
4
4
|
class TestFileMagic < Test::Unit::TestCase
|
5
5
|
|
6
|
-
magic_version = FileMagic
|
7
|
-
ENV['MAGIC_VERSION'] || begin
|
8
|
-
require 'nuggets/file/which'
|
9
|
-
%x{dpkg-query -f '${Version}' -W libmagic-dev} if File.which('dpkg-query')
|
10
|
-
rescue LoadError
|
11
|
-
end
|
12
|
-
|
6
|
+
magic_version, origin = FileMagic.magic_version
|
13
7
|
MAGIC_VERSION = magic_version.to_f
|
14
8
|
|
9
|
+
warn <<-EOT
|
10
|
+
|
11
|
+
libmagic version: #{MAGIC_VERSION}#{" (#{origin})" if origin}
|
12
|
+
magic file from #{FileMagic.path}
|
13
|
+
|
14
|
+
EOT
|
15
|
+
|
15
16
|
def test_file
|
16
17
|
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
17
18
|
|
@@ -25,7 +26,7 @@ class TestFileMagic < Test::Unit::TestCase
|
|
25
26
|
|
26
27
|
if File.symlink?(path_to('pylink'))
|
27
28
|
res = fm.file(path_to('pylink'))
|
28
|
-
assert_equal("symbolic link to `pyfile'", res)
|
29
|
+
assert_equal("symbolic link to `pyfile'", res.strip)
|
29
30
|
end
|
30
31
|
|
31
32
|
fm.close
|
@@ -60,7 +61,7 @@ class TestFileMagic < Test::Unit::TestCase
|
|
60
61
|
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
61
62
|
res = silence_stderr { fm.check(path_to('perl')) }
|
62
63
|
fm.close
|
63
|
-
|
64
|
+
assert(res)
|
64
65
|
end
|
65
66
|
|
66
67
|
def test_compile
|
@@ -68,7 +69,7 @@ class TestFileMagic < Test::Unit::TestCase
|
|
68
69
|
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
69
70
|
res = fm.compile(path_to('perl'))
|
70
71
|
fm.close
|
71
|
-
|
72
|
+
assert(res)
|
72
73
|
File.unlink(path_to('perl.mgc', '.'))
|
73
74
|
end
|
74
75
|
|
@@ -85,6 +86,14 @@ class TestFileMagic < Test::Unit::TestCase
|
|
85
86
|
assert block_fm.closed?
|
86
87
|
end
|
87
88
|
|
89
|
+
def test_flags_to_int
|
90
|
+
assert_raise(TypeError) { FileMagic.flags(0) }
|
91
|
+
assert_equal(0, FileMagic.flags([FileMagic::MAGIC_NONE]))
|
92
|
+
assert_equal(0, FileMagic.flags([:none]))
|
93
|
+
assert_equal(0, FileMagic.flags([]))
|
94
|
+
assert_equal(1072, FileMagic.flags([:mime, :continue]))
|
95
|
+
end
|
96
|
+
|
88
97
|
def test_setflags
|
89
98
|
fm = FileMagic.new(FileMagic::MAGIC_NONE)
|
90
99
|
assert_equal([], fm.flags)
|
@@ -95,7 +104,7 @@ class TestFileMagic < Test::Unit::TestCase
|
|
95
104
|
|
96
105
|
def test_abbr
|
97
106
|
fm = FileMagic.new(:mime, :continue)
|
98
|
-
assert_equal([:mime_type, :continue, :mime_encoding]
|
107
|
+
assert_equal([:mime_type, :continue, :mime_encoding], fm.flags)
|
99
108
|
fm.flags = :symlink
|
100
109
|
assert_equal([:symlink], fm.flags)
|
101
110
|
fm.close
|
@@ -159,7 +168,8 @@ class TestFileMagic < Test::Unit::TestCase
|
|
159
168
|
assert_equal('text/plain', fm.file(path_to('perl')))
|
160
169
|
assert_equal(match_version(
|
161
170
|
0 => 'application/vnd.ms-office',
|
162
|
-
5.11 => 'application/msword'
|
171
|
+
5.11 => 'application/msword',
|
172
|
+
5.14 => 'application/vnd.ms-office'
|
163
173
|
), fm.file(path_to('excel-example.xls')))
|
164
174
|
end
|
165
175
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-filemagic
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Travis Whitton
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-05-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hen
|
@@ -39,6 +39,20 @@ dependencies:
|
|
39
39
|
- - ">="
|
40
40
|
- !ruby/object:Gem::Version
|
41
41
|
version: '0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rake-compiler
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: test-unit
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -54,9 +68,7 @@ dependencies:
|
|
54
68
|
- !ruby/object:Gem::Version
|
55
69
|
version: '0'
|
56
70
|
description: Ruby bindings to the magic(4) library
|
57
|
-
email:
|
58
|
-
- tinymountain@gmail.com
|
59
|
-
- jens.wille@gmail.com
|
71
|
+
email: jens.wille@gmail.com
|
60
72
|
executables: []
|
61
73
|
extensions:
|
62
74
|
- ext/filemagic/extconf.rb
|
@@ -92,14 +104,21 @@ licenses:
|
|
92
104
|
metadata: {}
|
93
105
|
post_install_message: |2+
|
94
106
|
|
95
|
-
ruby-filemagic-0.
|
107
|
+
ruby-filemagic-0.6.0 [2014-05-16]:
|
96
108
|
|
97
|
-
*
|
98
|
-
*
|
109
|
+
* Required Ruby version >= 1.9.3.
|
110
|
+
* New method FileMagic#list (+magic_list+).
|
111
|
+
* New method FileMagic#load (+magic_load+).
|
112
|
+
* New method FileMagic.path (+magic_getpath+).
|
113
|
+
* New method FileMagic.magic_version.
|
114
|
+
* New method FileMagic.flags.
|
115
|
+
* New flag +no_check_builtin+.
|
116
|
+
* Tests print libmagic version and path.
|
117
|
+
* Internal refactoring.
|
99
118
|
|
100
119
|
rdoc_options:
|
101
120
|
- "--title"
|
102
|
-
- ruby-filemagic Application documentation (v0.
|
121
|
+
- ruby-filemagic Application documentation (v0.6.0)
|
103
122
|
- "--charset"
|
104
123
|
- UTF-8
|
105
124
|
- "--line-numbers"
|
@@ -112,7 +131,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
112
131
|
requirements:
|
113
132
|
- - ">="
|
114
133
|
- !ruby/object:Gem::Version
|
115
|
-
version:
|
134
|
+
version: 1.9.3
|
116
135
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
136
|
requirements:
|
118
137
|
- - ">="
|