-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmagics.rl
69 lines (60 loc) · 1.69 KB
/
magics.rl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
module MIME
module Magic
%%{
machine magic;
action begin {b = p}
action end {e = data[ b .. p]}
action number {n = e.pack("c*").to_i}
number = digit+ >begin @end %number;
# media-type
action type {type = e.pack("c*")}
type_part = alnum | [\-_+.] ;
type = (type_part+ "/" type_part+) >begin @end %type;
# Section
action value {
value_length = data[p+1, 2].pack("c*").unpack('n').first
p +=2
value = data[p+1, value_length]
mask = [0xff] * value_length
p += value_length
}
action mask {
mask = data[p+1, value_length]
p += value_length
}
action priority {priority = n}
action indent {indent = n}
action start_offset {start_offset = n}
action word_size {word_size = n}
action range_length {range_length = n}
action section_header {magics << RootEntry.new(type, priority)}
action begin_section { indent = 0; word_size = 0; range_length = 1}
action section {
magics.last.add_subentry Entry.new(indent, start_offset, value_length, value, mask, word_size, range_length)
}
indent = number %indent;
start_offset = ">" number %start_offset;
value = "=" @value;
mask = "&" @mask;
word_size = "~" number %word_size;
range_length = "+" number %range_length;
priority = number %priority;
section_header = "[" priority ":" type "]\n" %section_header ;
section = indent? >begin_section start_offset value mask? word_size? range_length? "\n";
sections = section_header section+ @section;
main := "MIME-Magic\0\n" sections*;
write data;
}%%
def self.parse_magic( data )
magics = []
data = data.unpack("c*")
%% write init;
eof = pe
%% write exec;
if cs < magic_first_final
raise BadMagic
end
magics
end
end
end