libmagic_rb 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +41 -9
- data/ext/libmagic/func.h +175 -3
- data/ext/libmagic/magic.c +67 -2
- data/lib/libmagic_rb/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: add88dc48d3eda81cd55f1eafd163822b50452852b1f0ae0121b3de36e2f5588
|
4
|
+
data.tar.gz: 60b7af94ac6e809f16ae22b1c7aac8eb3eab68b4be76c2437217bc6da32be58a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d694f12d7d3211dc40e0e1eedbac222bb232a529f5ac9a27fdc3a7f58f2c0238cebacff4ed4490931abc0fd46baee72aa84402863809b938fe9d65f9bf781c61
|
7
|
+
data.tar.gz: 8a2f6b16efe5644f66cbe45dab50b0ef671592fd0d586cd2a51edc09bdd0b993c903eed617f748567e50b1db4c6c02a36577af98b653fa9a1b5466f5c615ead2
|
data/README.md
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
# LibmagicRb
|
1
|
+
# LibmagicRb [![Gem Version](https://badge.fury.io/rb/libmagic_rb.svg)](https://rubygems.org/gems/libmagic_rb) ![Workflow Status](https://github.com/cybergizer-hq/libmagicrb/workflows/LibmagicRb%20Test/badge.svg)
|
2
|
+
|
2
3
|
Adds ability to check mime-type of a file using the libmagic ([magic(4)](https://man7.org/linux/man-pages/man4/magic.4.html)).
|
3
4
|
It uses native extensions and it's quite performant.
|
4
5
|
|
@@ -17,31 +18,62 @@ You also need Ruby > 1.9.0 in order to run this gem.
|
|
17
18
|
|
18
19
|
With that info in mind, let's continue to the installation part for your Linux distributions...
|
19
20
|
|
20
|
-
#### Arch / Manjaro / Archlabs & other Arch
|
21
|
+
#### Arch / Manjaro / Archlabs / Garuda Linux / Hefftor Linux & other Arch Based Linux
|
21
22
|
|
22
23
|
```
|
23
|
-
# pacman -S file gcc make
|
24
|
+
# pacman -S ruby file gcc make --needed
|
24
25
|
```
|
25
26
|
|
26
|
-
#### Debian / Ubuntu / Linux Mint / RaspberryPi OS & other Debian
|
27
|
+
#### Debian / Ubuntu / Linux Mint / Deepin / Pop!_OS / RaspberryPi OS & other Debian Based Linux
|
27
28
|
|
28
29
|
```
|
29
|
-
# apt install libmagic-dev ruby-dev gcc make
|
30
|
+
# apt install ruby libmagic-dev ruby-dev gcc make
|
30
31
|
```
|
31
32
|
|
32
|
-
#### Fedora / Amazon Linux / CentOS & Other RedHat
|
33
|
+
#### Fedora / Amazon Linux / CentOS & Other RedHat Based Linux
|
33
34
|
|
34
35
|
```
|
35
|
-
# yum install file-devel ruby-devel gcc make
|
36
|
+
# yum install ruby file-devel ruby-devel gcc make
|
36
37
|
```
|
37
38
|
|
38
39
|
#### OpenSUSE
|
39
40
|
|
40
41
|
```
|
41
|
-
zypper in ruby ruby-devel file-devel gcc make
|
42
|
+
# zypper in ruby ruby-devel file-devel gcc make
|
43
|
+
```
|
44
|
+
|
45
|
+
#### Gentoo
|
46
|
+
|
47
|
+
There are already make, and magic.h available for Gentoo. You just need Ruby:
|
48
|
+
|
49
|
+
```
|
50
|
+
# emerge --ask dev-lang/ruby
|
51
|
+
```
|
52
|
+
|
53
|
+
#### DragonflyBSD / FreeBSD
|
54
|
+
|
55
|
+
Versions upto 0.1.2 is tested on DragonflyBSD (Version 6.0-SYNTH).
|
56
|
+
|
42
57
|
```
|
58
|
+
# pkg install ruby devel/ruby-gems gcc gmake
|
59
|
+
```
|
60
|
+
|
61
|
+
#### MacOS
|
62
|
+
|
63
|
+
You can install libmagic with homebrew:
|
64
|
+
|
65
|
+
```
|
66
|
+
$ brew install libmagic
|
67
|
+
|
68
|
+
# if the link is already created is going to fail, don't worry about that
|
69
|
+
$ brew link libmagic
|
70
|
+
```
|
71
|
+
|
72
|
+
[ Source: [ eparreno/gist:1845561 ](https://gist.github.com/eparreno/1845561) ]
|
73
|
+
|
74
|
+
#### Windows
|
43
75
|
|
44
|
-
|
76
|
+
Windows is currently not tested, hence the support is unknown.
|
45
77
|
|
46
78
|
## Installation
|
47
79
|
|
data/ext/libmagic/func.h
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
Closes a magic cookie. For example:
|
3
|
+
|
4
|
+
> cookie = LibmagicRb.new(file: '/usr/share/dict/words')
|
5
|
+
# => #<LibmagicRb:0x00005581019fa7e0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
6
|
+
|
7
|
+
> cookie.close
|
8
|
+
# => #<LibmagicRb:0x00005581019fa7e0 @closed=true, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
9
|
+
|
10
|
+
Returns self.
|
11
|
+
*/
|
12
|
+
|
1
13
|
VALUE _closeGlobal_(volatile VALUE self) {
|
2
14
|
RB_UNWRAP(cookie) ;
|
3
15
|
|
@@ -7,6 +19,23 @@ VALUE _closeGlobal_(volatile VALUE self) {
|
|
7
19
|
return self ;
|
8
20
|
}
|
9
21
|
|
22
|
+
/*
|
23
|
+
Changes the database path. For example:
|
24
|
+
> cookie = LibmagicRb.new(file: '/usr/share/dict/words')
|
25
|
+
# => #<LibmagicRb:0x00005581019181b0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
26
|
+
|
27
|
+
> cookie.db = '/usr/share/file/misc/magic.mgc'
|
28
|
+
# => "/usr/share/file/misc/magic.mgc"
|
29
|
+
|
30
|
+
> cookie.check
|
31
|
+
# => "text/plain; charset=utf-8"
|
32
|
+
|
33
|
+
> cookie.close
|
34
|
+
# => #<LibmagicRb:0x00005581019181b0 @closed=true, @db="/usr/share/file/misc/magic.mgc", @file="/usr/share/dict/words", @mode=1106>
|
35
|
+
|
36
|
+
Returns self.
|
37
|
+
*/
|
38
|
+
|
10
39
|
VALUE _loadGlobal_(volatile VALUE self, volatile VALUE dbPath) {
|
11
40
|
char *databasePath = NULL ;
|
12
41
|
|
@@ -27,6 +56,20 @@ VALUE _loadGlobal_(volatile VALUE self, volatile VALUE dbPath) {
|
|
27
56
|
return self ;
|
28
57
|
}
|
29
58
|
|
59
|
+
/*
|
60
|
+
Check a file with the magic database. For example:
|
61
|
+
> cookie = LibmagicRb.new(file: '/usr/share/dict/words')
|
62
|
+
# => #<LibmagicRb:0x00005581019181b0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
63
|
+
|
64
|
+
> cookie.check
|
65
|
+
# => "text/plain; charset=utf-8"
|
66
|
+
|
67
|
+
> cookie.close
|
68
|
+
# => #<LibmagicRb:0x00005581019181b0 @closed=true, @db="/usr/share/file/misc/magic.mgc", @file="/usr/share/dict/words", @mode=1106>
|
69
|
+
|
70
|
+
Returns String or nil.
|
71
|
+
*/
|
72
|
+
|
30
73
|
VALUE _checkGlobal_(volatile VALUE self) {
|
31
74
|
RB_UNWRAP(cookie) ;
|
32
75
|
|
@@ -51,6 +94,18 @@ VALUE _checkGlobal_(volatile VALUE self) {
|
|
51
94
|
return mt ? rb_str_new_cstr(mt) : Qnil ;
|
52
95
|
}
|
53
96
|
|
97
|
+
/*
|
98
|
+
Get parameters for a cookie. For example:
|
99
|
+
cookie = LibmagicRb.new(file: '/usr/share/dict/words')
|
100
|
+
# => #<LibmagicRb:0x00005581018f35e0 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
101
|
+
|
102
|
+
> cookie.getparam(LibmagicRb::MAGIC_PARAM_NAME_MAX)
|
103
|
+
# => 50
|
104
|
+
|
105
|
+
> cookie.close
|
106
|
+
# => #<LibmagicRb:0x00005581018f35e0 @closed=true, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
107
|
+
*/
|
108
|
+
|
54
109
|
VALUE _getParamGlobal_(volatile VALUE self, volatile VALUE param) {
|
55
110
|
#if MAGIC_VERSION > 525
|
56
111
|
RB_UNWRAP(cookie) ;
|
@@ -66,6 +121,27 @@ VALUE _getParamGlobal_(volatile VALUE self, volatile VALUE param) {
|
|
66
121
|
#endif
|
67
122
|
}
|
68
123
|
|
124
|
+
/*
|
125
|
+
Sets parameter for a cookie. For example:
|
126
|
+
|
127
|
+
> cookie = LibmagicRb.new(file: '/usr/share/dict/words')
|
128
|
+
# => #<LibmagicRb:0x00005581019f9840 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
129
|
+
|
130
|
+
> cookie.getparam(LibmagicRb::MAGIC_PARAM_NAME_MAX)
|
131
|
+
=> 50
|
132
|
+
|
133
|
+
> cookie.setparam(LibmagicRb::MAGIC_PARAM_NAME_MAX, 101)
|
134
|
+
# => 101
|
135
|
+
|
136
|
+
> cookie.getparam(LibmagicRb::MAGIC_PARAM_NAME_MAX)
|
137
|
+
# => 101
|
138
|
+
|
139
|
+
> cookie.close
|
140
|
+
# => #<LibmagicRb:0x00005581019f9840 @closed=true, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
141
|
+
|
142
|
+
Returns Integer or nil on failure.
|
143
|
+
*/
|
144
|
+
|
69
145
|
VALUE _setParamGlobal_(volatile VALUE self, volatile VALUE param, volatile VALUE paramVal) {
|
70
146
|
#if MAGIC_VERSION > 525
|
71
147
|
unsigned int _param = NUM2UINT(param) ;
|
@@ -85,25 +161,121 @@ VALUE _setParamGlobal_(volatile VALUE self, volatile VALUE param, volatile VALUE
|
|
85
161
|
#endif
|
86
162
|
}
|
87
163
|
|
164
|
+
/*
|
165
|
+
Returns a textual description of the contents of the buffer argument with length bytes size.
|
166
|
+
|
167
|
+
For example:
|
168
|
+
|
169
|
+
> cookie = LibmagicRb.new(file: '.')
|
170
|
+
# => #<LibmagicRb:0x00005582de0d1bf8 @closed=false, @db=nil, @file=".", @mode=1106>
|
171
|
+
|
172
|
+
> cookie.magic_buffer("%PDF-1.3\r\n")
|
173
|
+
# => "application/pdf; charset=us-ascii"
|
174
|
+
|
175
|
+
> cookie.close
|
176
|
+
# => #<LibmagicRb:0x00005582de0d1bf8 @closed=true, @db=nil, @file=".", @mode=1106>
|
177
|
+
|
178
|
+
Note that it automatically loads the database.
|
179
|
+
|
180
|
+
Returns either String or nil.
|
181
|
+
*/
|
182
|
+
|
88
183
|
VALUE _bufferGlobal_(volatile VALUE self, volatile VALUE string) {
|
89
184
|
RB_UNWRAP(cookie) ;
|
90
185
|
|
186
|
+
VALUE db = rb_iv_get(self, "@db") ;
|
187
|
+
|
188
|
+
char *database = NULL ;
|
189
|
+
if(RB_TYPE_P(db, T_STRING)) {
|
190
|
+
database = StringValuePtr(db) ;
|
191
|
+
}
|
192
|
+
|
193
|
+
if(database) magic_validate_db(*cookie, database) ;
|
194
|
+
magic_load(*cookie, database) ;
|
195
|
+
|
91
196
|
char *buffer = StringValuePtr(string) ;
|
92
|
-
const char *buf = magic_buffer(*cookie, buffer,
|
197
|
+
const char *buf = magic_buffer(*cookie, buffer, strlen(buffer)) ;
|
93
198
|
|
94
|
-
return rb_str_new_cstr(buf) ;
|
199
|
+
return buf ? rb_str_new_cstr(buf) : Qnil ;
|
95
200
|
}
|
96
201
|
|
202
|
+
/*
|
203
|
+
Dumps all magic entries in a human
|
204
|
+
readable format, dumping first the entries that are matched against
|
205
|
+
binary files and then the ones that match text files.
|
206
|
+
|
207
|
+
For example:
|
208
|
+
|
209
|
+
|
210
|
+
> cookie = LibmagicRb.new(file: '.')
|
211
|
+
# => #<LibmagicRb:0x000055cf280a9b30 @closed=false, @db=nil, @file=".", @mode=1106>
|
212
|
+
|
213
|
+
> cookie.magic_list
|
214
|
+
Set 0:
|
215
|
+
Binary patterns:
|
216
|
+
Strength = 500@47: Biosig/Brainvision Marker file [biosig/brainvision]
|
217
|
+
Strength = 490@122: Biosig/TMSiLOG [biosig/tmsilog]
|
218
|
+
Strength = 461@127: Biosig/SYNERGY [biosig/synergy]
|
219
|
+
Strength = 460@46: Biosig/Brainvision V-Amp file []
|
220
|
+
Strength = 410@45: Biosig/Brainvision data file []
|
221
|
+
Strength = 380@6: OpenSSH private key []
|
222
|
+
Strength = 370@1266: Novell message librarian data []
|
223
|
+
.
|
224
|
+
.
|
225
|
+
.
|
226
|
+
# => 0
|
227
|
+
|
228
|
+
> cookie.close
|
229
|
+
=> #<LibmagicRb:0x000055cf280a9b30 @closed=true, @db=nil, @file=".", @mode=1106>
|
230
|
+
*/
|
231
|
+
|
97
232
|
VALUE _listGlobal_(volatile VALUE self) {
|
98
233
|
RB_UNWRAP(cookie) ;
|
99
234
|
|
100
235
|
VALUE db = rb_iv_get(self, "@db") ;
|
101
|
-
char *database = StringValuePtr(db) ;
|
102
236
|
|
237
|
+
char *database = NULL ;
|
238
|
+
if (RB_TYPE_P(db, T_STRING)) {
|
239
|
+
database = StringValuePtr(db) ;
|
240
|
+
}
|
241
|
+
|
242
|
+
if(database) magic_validate_db(*cookie, database) ;
|
103
243
|
int status = magic_list(*cookie, database) ;
|
244
|
+
|
104
245
|
return INT2FIX(status) ;
|
105
246
|
}
|
106
247
|
|
248
|
+
/*
|
249
|
+
Set flags/modes for a cookie (not to be confused with params).
|
250
|
+
It's same setting mode through the setter cookie.mode = mode.
|
251
|
+
|
252
|
+
For example:
|
253
|
+
|
254
|
+
> cookie = LibmagicRb.new(file: '.')
|
255
|
+
# => #<LibmagicRb:0x00005583732e1070 @closed=false, @db=nil, @file=".", @mode=1106>
|
256
|
+
|
257
|
+
> cookie.check
|
258
|
+
# => "inode/directory; charset=binary"
|
259
|
+
|
260
|
+
> cookie.setflags(LibmagicRb::MAGIC_RAW)
|
261
|
+
# => 256
|
262
|
+
|
263
|
+
> cookie.check
|
264
|
+
# => "directory"
|
265
|
+
|
266
|
+
#### Similarly you can also do this ####
|
267
|
+
|
268
|
+
> cookie.mode = LibmagicRb::MAGIC_MIME
|
269
|
+
# => 1040
|
270
|
+
|
271
|
+
> cookie.check
|
272
|
+
# => "inode/directory; charset=binary"
|
273
|
+
|
274
|
+
#### Close the cookie when done ####
|
275
|
+
> cookie.close
|
276
|
+
# => #<LibmagicRb:0x00005583732e1070 @closed=true, @db=nil, @file=".", @mode=256>
|
277
|
+
*/
|
278
|
+
|
107
279
|
VALUE _setflagsGlobal_(volatile VALUE self, volatile VALUE flags) {
|
108
280
|
unsigned int flag = NUM2UINT(flags) ;
|
109
281
|
|
data/ext/libmagic/magic.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#include <magic.h>
|
2
2
|
#include <stdio.h>
|
3
3
|
#include <unistd.h>
|
4
|
+
#include <sys/stat.h>
|
4
5
|
#include "ruby.h"
|
5
6
|
|
6
7
|
/*
|
@@ -43,13 +44,30 @@ static rb_data_type_t fileType = {
|
|
43
44
|
},
|
44
45
|
|
45
46
|
.data = NULL,
|
46
|
-
|
47
|
+
|
48
|
+
#ifdef RUBY_TYPED_FREE_IMMEDIATELY
|
49
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
50
|
+
#endif
|
47
51
|
} ;
|
48
52
|
|
49
53
|
#include "validations.h"
|
50
54
|
#include "func.h"
|
51
55
|
|
52
|
-
|
56
|
+
/*
|
57
|
+
Directly check a file with LibmagicRb, without creating any sort of cookies:
|
58
|
+
|
59
|
+
LibmagicRb.check(file: '/tmp/', db: '/usr/share/file/misc/magic.mgc', mode: LibmagicRb::MAGIC_CHECK) # => "sticky, directory"
|
60
|
+
|
61
|
+
[file] The key `file:` is the filename to check. Should be a string
|
62
|
+
|
63
|
+
[db] The key `db:` can be left as nil. Or you can give it the path of the current magic database.
|
64
|
+
|
65
|
+
[mode] The key `mode` can be any of the LibmagicRb.lsmodes().
|
66
|
+
To combine modes you can use `|`. For example:
|
67
|
+
`mode: LibmagicRb::MAGIC_CHECK | LibmagicRb::MAGIC_SYMLINK | Libmagic_MAGIC_MIME`
|
68
|
+
If `mode` key is nil, it will default to `MAGIC_MIME | MAGIC_CHECK | MAGIC_SYMLINK`
|
69
|
+
*/
|
70
|
+
static VALUE _check_(volatile VALUE obj, volatile VALUE args) {
|
53
71
|
if(!RB_TYPE_P(args, T_HASH)) {
|
54
72
|
rb_raise(rb_eArgError, "Expected hash as argument.") ;
|
55
73
|
}
|
@@ -107,6 +125,43 @@ VALUE _check_(volatile VALUE obj, volatile VALUE args) {
|
|
107
125
|
return retVal ;
|
108
126
|
}
|
109
127
|
|
128
|
+
/*
|
129
|
+
Intializes a magic cookie that can be used multiple times.
|
130
|
+
The benefit of this is to assgign various cookies and change flags of each cookie.
|
131
|
+
|
132
|
+
For example:
|
133
|
+
|
134
|
+
> cookie = LibmagicRb.new(file: '/tmp')
|
135
|
+
# => #<LibmagicRb:0x000055810139f738 @closed=false, @db=nil, @file="/tmp", @mode=1106>
|
136
|
+
|
137
|
+
> cookie.check
|
138
|
+
# => "inode/directory; charset=binary"
|
139
|
+
|
140
|
+
> cookie.setflags(LibmagicRb::MAGIC_RAW)
|
141
|
+
# => 256
|
142
|
+
|
143
|
+
> cookie.check
|
144
|
+
# => "sticky, directory"
|
145
|
+
|
146
|
+
> cookie2 = LibmagicRb.new(file: '/usr/share/dict/words')
|
147
|
+
# => #<LibmagicRb:0x000055810190a060 @closed=false, @db=nil, @file="/usr/share/dict/words", @mode=1106>
|
148
|
+
|
149
|
+
> cookie2.check
|
150
|
+
# => "text/plain; charset=utf-8"
|
151
|
+
|
152
|
+
> cookie.close
|
153
|
+
# => #<LibmagicRb:0x000055810139f738 @closed=true, @db=nil, @file="/tmp", @mode=256>
|
154
|
+
|
155
|
+
> cookie.closed?
|
156
|
+
# => true
|
157
|
+
|
158
|
+
> cookie2.closed?
|
159
|
+
# => false
|
160
|
+
|
161
|
+
Here in this example, we can't use cookie, but cookie2 is a different magic_t wrapper, so we can continue using that.
|
162
|
+
Flags/modes applied to cookie, will not affect cookie2 as well. Think of them as totally different containers.
|
163
|
+
Of course, you must close cookies when you don't need them. Otherwise it can use memories unless GC is triggered.
|
164
|
+
*/
|
110
165
|
VALUE rb_libmagicRb_initialize(volatile VALUE self, volatile VALUE args) {
|
111
166
|
// Database Path
|
112
167
|
if(!RB_TYPE_P(args, T_HASH)) {
|
@@ -170,6 +225,10 @@ void Init_main() {
|
|
170
225
|
/*
|
171
226
|
* Libmagic Errors
|
172
227
|
*/
|
228
|
+
|
229
|
+
/*
|
230
|
+
Adds ability to check mime-type of a file using the libmagic (magic(4)). It uses native extensions and it's quite performant.
|
231
|
+
*/
|
173
232
|
VALUE cLibmagicRb = rb_define_class("LibmagicRb", rb_cObject) ;
|
174
233
|
|
175
234
|
rb_eFileNotFoundError = rb_define_class_under(cLibmagicRb, "FileNotFound", rb_eRuntimeError) ;
|
@@ -184,9 +243,15 @@ void Init_main() {
|
|
184
243
|
modes(cLibmagicRb) ;
|
185
244
|
params(cLibmagicRb) ;
|
186
245
|
|
246
|
+
|
187
247
|
#if MAGIC_VERSION > 525
|
188
248
|
char version[6] ;
|
189
249
|
sprintf(version, "%0.2f", magic_version() / 100.0) ;
|
250
|
+
|
251
|
+
/*
|
252
|
+
LibmagicRb::MAGIC_VERSION returns the magic version of the library.
|
253
|
+
For older libmagic version, this can be undefined, so this method will return "0" instead.
|
254
|
+
*/
|
190
255
|
rb_define_const(cLibmagicRb, "MAGIC_VERSION", rb_str_new_cstr(version)) ;
|
191
256
|
#else
|
192
257
|
rb_define_const(cLibmagicRb, "MAGIC_VERSION", rb_str_new_cstr("0")) ;
|
data/lib/libmagic_rb/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libmagic_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Cybergizer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-06 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Check filetype with libmagic
|
14
14
|
email:
|