format_parser 2.4.3 → 2.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ed2f3d1a503aee2a0b68f00dfae5253fa88cb9ab95b61066642749785542c06
4
- data.tar.gz: 3cac7120ef119969273568714fa3f75c07e3493bd80c18b89e4a7ac93efbc9dd
3
+ metadata.gz: a3b2c55550282f0f8d7b04723decd4d0d35f73afc3d987fbaaf14e2274838bab
4
+ data.tar.gz: 24119780ac672b473a1e01c3cc2bb4dc545aec45d8a5e331a09b37cebece100b
5
5
  SHA512:
6
- metadata.gz: 311393234d4bc595a81169dcfa658b872c539179fba29149d7794df64d388ebbad7e1bdbf8f963018b438c3ad0a350a1f23f47fd1a383a0d50d6897f429c727c
7
- data.tar.gz: e73d90e24cef65d936eebd0765403b3d83e52fdb6bf3640bfabba2afd2b059d4a85a1010fca6ff575e6e0ff84e003cc75fa1bb4a8cb2adbff0c1fb55e97161d1
6
+ metadata.gz: 251a7268c1c829424613f9a811bf59d88061b96efbc44557f6bfcffbbd0d7de5c1430f98b956eeace9bc590b1fbc6ada05eeaa215c526f24fe063c236bb5b8af
7
+ data.tar.gz: 2e263df394eddd302c1ea8d4f99bcac262e276f251a1cf37abe0475ec0c6ec36fa5a2c6181d88e9a889053b00fe54568d72f1bd083395cd6994f916ff848d3ed
data/CHANGELOG.md CHANGED
@@ -1,3 +1,6 @@
1
+ ## 2.4.4
2
+ * Prevent infinite loops when parsing ISOBMFF boxes with size = 0 (meaning that the box extends to the end of the file).
3
+
1
4
  ## 2.4.3
2
5
  * Improve resiliency in ISOBMFF parsing to missing mandatory boxes and fields.
3
6
  * Simplify ISOBMFF frame rate calculations.
@@ -1,3 +1,3 @@
1
1
  module FormatParser
2
- VERSION = '2.4.3'
2
+ VERSION = '2.4.4'
3
3
  end
@@ -129,10 +129,15 @@ module FormatParser
129
129
  # @return [Box, nil]
130
130
  def parse_box
131
131
  position = @buf.pos
132
-
133
132
  size = read_int
134
133
  type = read_string(4)
135
- size = read_int(n: 8) if size == 1
134
+
135
+ if size == 1
136
+ size = read_int(n: 8)
137
+ elsif size == 0
138
+ size = @buf.size - position
139
+ end
140
+
136
141
  body_size = size - (@buf.pos - position)
137
142
  next_box_position = position + size
138
143
 
@@ -48,12 +48,29 @@ describe FormatParser::ISOBaseMediaFileFormat::Decoder do
48
48
  end
49
49
  let(:result) { subject.build_box_tree(0xFF, io) }
50
50
 
51
- it('parses successfully') { expect(result.length).to eq(1) }
52
- it('parses the correct type') { expect(result[0].type).to eq('foo ') }
53
- it('parses the correct position') { expect(result[0].position).to eq(0) }
54
- it('parses the correct size') { expect(result[0].size).to eq(0x14) }
55
- it('skips additional fields') { expect(result[0].fields).to eq({}) }
56
- it('skips children') { expect(result[0].children).to eq([]) }
51
+ it 'parses successfully' do
52
+ expect(result.length).to eq(1)
53
+ end
54
+
55
+ it 'parses the correct type' do
56
+ expect(result[0].type).to eq('foo ')
57
+ end
58
+
59
+ it 'parses the correct position' do
60
+ expect(result[0].position).to eq(0)
61
+ end
62
+
63
+ it 'parses the correct size' do
64
+ expect(result[0].size).to eq(0x14)
65
+ end
66
+
67
+ it 'skips additional fields' do
68
+ expect(result[0].fields).to eq({})
69
+ end
70
+
71
+ it 'skips children' do
72
+ expect(result[0].children).to eq([])
73
+ end
57
74
  end
58
75
 
59
76
  context 'when parsing a container box' do
@@ -66,12 +83,29 @@ describe FormatParser::ISOBaseMediaFileFormat::Decoder do
66
83
  end
67
84
  let(:result) { subject.build_box_tree(0xFF, io) }
68
85
 
69
- it('parses successfully') { expect(result.length).to eq(1) }
70
- it('parses the correct type') { expect(result[0].type).to eq('moov') }
71
- it('parses the correct position') { expect(result[0].position).to eq(0) }
72
- it('parses the correct size') { expect(result[0].size).to eq(0x18) }
73
- it('skips additional fields') { expect(result[0].fields).to eq({}) }
74
- it('parses children') { expect(result[0].children.length).to eq(2) }
86
+ it 'parses successfully' do
87
+ expect(result.length).to eq(1)
88
+ end
89
+
90
+ it 'parses the correct type' do
91
+ expect(result[0].type).to eq('moov')
92
+ end
93
+
94
+ it 'parses the correct position' do
95
+ expect(result[0].position).to eq(0)
96
+ end
97
+
98
+ it 'parses the correct size' do
99
+ expect(result[0].size).to eq(0x18)
100
+ end
101
+
102
+ it 'skips additional fields' do
103
+ expect(result[0].fields).to eq({})
104
+ end
105
+
106
+ it 'parses children' do
107
+ expect(result[0].children.length).to eq(2)
108
+ end
75
109
  end
76
110
 
77
111
  context 'when parsing an empty box' do
@@ -83,17 +117,32 @@ describe FormatParser::ISOBaseMediaFileFormat::Decoder do
83
117
  end
84
118
  let(:result) { subject.build_box_tree(0xFF, io) }
85
119
 
86
- it('parses successfully') { expect(result.length).to eq(1) }
87
- it('parses the correct type') { expect(result[0].type).to eq('nmhd') }
88
- it('parses the correct position') { expect(result[0].position).to eq(0) }
89
- it('parses the correct size') { expect(result[0].size).to eq(0x18) }
90
- it('parses version and flags') do
120
+ it 'parses successfully' do
121
+ expect(result.length).to eq(1)
122
+ end
123
+
124
+ it 'parses the correct type' do
125
+ expect(result[0].type).to eq('nmhd')
126
+ end
127
+
128
+ it 'parses the correct position' do
129
+ expect(result[0].position).to eq(0)
130
+ end
131
+
132
+ it 'parses the correct size' do
133
+ expect(result[0].size).to eq(0x18)
134
+ end
135
+
136
+ it 'parses version and flags' do
91
137
  expect(result[0].fields).to include({
92
138
  version: 1,
93
139
  flags: 'fla'
94
140
  })
95
141
  end
96
- it('skips children') { expect(result[0].children).to eq([]) }
142
+
143
+ it 'skips children' do
144
+ expect(result[0].children).to eq([])
145
+ end
97
146
  end
98
147
 
99
148
  context 'when parsing a uuid box' do
@@ -106,12 +155,54 @@ describe FormatParser::ISOBaseMediaFileFormat::Decoder do
106
155
  end
107
156
  let(:result) { subject.build_box_tree(0xFF, io) }
108
157
 
109
- it('parses successfully') { expect(result.length).to eq(1) }
110
- it('parses the correct type') { expect(result[0].type).to eq('uuid') }
111
- it('parses the correct position') { expect(result[0].position).to eq(0) }
112
- it('parses the correct size') { expect(result[0].size).to eq(0x20) }
113
- it('parses usertype') { expect(result[0].fields).to include({ usertype: usertype }) }
114
- it('skips children') { expect(result[0].children).to eq([]) }
158
+ it 'parses successfully' do
159
+ expect(result.length).to eq(1)
160
+ end
161
+
162
+ it 'parses the correct type' do
163
+ expect(result[0].type).to eq('uuid')
164
+ end
165
+
166
+ it 'parses the correct position' do
167
+ expect(result[0].position).to eq(0)
168
+ end
169
+
170
+ it 'parses the correct size' do
171
+ expect(result[0].size).to eq(0x20)
172
+ end
173
+
174
+ it 'parses usertype' do
175
+ expect(result[0].fields).to include({ usertype: usertype })
176
+ end
177
+
178
+ it 'skips children' do
179
+ expect(result[0].children).to eq([])
180
+ end
181
+ end
182
+
183
+ context 'when parsing a box with 0 size' do
184
+ let(:io) do
185
+ # foo
186
+ # moov
187
+ # |-> bar
188
+ # |-> baz
189
+ input = [0x8].pack('N') + 'foo ' + [0x0].pack('N') + 'moov' + [0x8].pack('N') + 'bar ' + [0x8].pack('N') + 'baz '
190
+ StringIO.new(input)
191
+ end
192
+ let(:result) { subject.build_box_tree(0xFF, io) }
193
+
194
+ it 'reads the rest of the file' do
195
+ expect(result.length).to eq(2)
196
+ expect(io.pos).to eq(0x20)
197
+ end
198
+
199
+ it 'parses correctly' do
200
+ expect(result[0].type).to eq('foo ')
201
+ expect(result[1].type).to eq('moov')
202
+ expect(result[1].children.length).to eq(2)
203
+ expect(result[1].children[0].type).to eq('bar ')
204
+ expect(result[1].children[1].type).to eq('baz ')
205
+ end
115
206
  end
116
207
  end
117
208
  end
@@ -35,15 +35,41 @@ describe FormatParser::MOVParser do
35
35
  context "for #{path}" do
36
36
  let(:result) { subject.call(File.open(path, 'rb')) }
37
37
 
38
- it('should not be nil') { expect(result).not_to be_nil }
39
- it('should have video nature') { expect(result.nature).to eq(:video) }
40
- it('should have MOV video content type') { expect(result.content_type).to eq('video/quicktime') }
41
- it('should have MOV video format') { expect(result.format).to eq(:mov) }
42
- it('should have a non-zero height ') { expect(result.height_px).to be > 0 }
43
- it('should have a non-zero width') { expect(result.width_px).to be > 0 }
44
- it('should have a non-zero duration') { expect(result.media_duration_seconds).to be > 0 }
45
- it('should have a non-nil frame rate') { expect(result.frame_rate).not_to be_nil }
46
- it('should have intrinsics') { expect(result.intrinsics).not_to be_nil }
38
+ it 'should not be nil' do
39
+ expect(result).not_to be_nil
40
+ end
41
+
42
+ it 'should have video nature' do
43
+ expect(result.nature).to eq(:video)
44
+ end
45
+
46
+ it 'should have MOV video content type' do
47
+ expect(result.content_type).to eq('video/quicktime')
48
+ end
49
+
50
+ it 'should have MOV video format' do
51
+ expect(result.format).to eq(:mov)
52
+ end
53
+
54
+ it 'should have a non-zero height ' do
55
+ expect(result.height_px).to be > 0
56
+ end
57
+
58
+ it 'should have a non-zero width' do
59
+ expect(result.width_px).to be > 0
60
+ end
61
+
62
+ it 'should have a non-zero duration' do
63
+ expect(result.media_duration_seconds).to be > 0
64
+ end
65
+
66
+ it 'should have a non-nil frame rate' do
67
+ expect(result.frame_rate).not_to be_nil
68
+ end
69
+
70
+ it 'should have intrinsics' do
71
+ expect(result.intrinsics).not_to be_nil
72
+ end
47
73
  end
48
74
  end
49
75
 
@@ -51,7 +77,9 @@ describe FormatParser::MOVParser do
51
77
  context "for #{path}" do
52
78
  let(:result) { subject.call(File.open(path, 'rb')) }
53
79
 
54
- it('should be nil') { expect(result).to be_nil }
80
+ it 'should be nil' do
81
+ expect(result).to be_nil
82
+ end
55
83
  end
56
84
  end
57
85
 
@@ -61,10 +89,21 @@ describe FormatParser::MOVParser do
61
89
  subject.call(File.open(path, 'rb'))
62
90
  end
63
91
 
64
- it('should have the correct height') { expect(result.height_px).to eq(360) }
65
- it('should have the correct width') { expect(result.width_px).to eq(640) }
66
- it('should have the correct duration') { expect(result.media_duration_seconds.truncate(2)).to eq(9.36) }
67
- it('should have the correct frame rate') { expect(result.frame_rate).to eq(30) }
92
+ it 'should have the correct height' do
93
+ expect(result.height_px).to eq(360)
94
+ end
95
+
96
+ it 'should have the correct width' do
97
+ expect(result.width_px).to eq(640)
98
+ end
99
+
100
+ it 'should have the correct duration' do
101
+ expect(result.media_duration_seconds.truncate(2)).to eq(9.36)
102
+ end
103
+
104
+ it 'should have the correct frame rate' do
105
+ expect(result.frame_rate).to eq(30)
106
+ end
68
107
  end
69
108
 
70
109
  context "for a scaled MOV video" do
@@ -73,8 +112,13 @@ describe FormatParser::MOVParser do
73
112
  subject.call(File.open(path, 'rb'))
74
113
  end
75
114
 
76
- it('should have the correct height') { expect(result.height_px).to eq(720) }
77
- it('should have the correct width') { expect(result.width_px).to eq(1280) }
115
+ it 'should have the correct height' do
116
+ expect(result.height_px).to eq(720)
117
+ end
118
+
119
+ it 'should have the correct width' do
120
+ expect(result.width_px).to eq(1280)
121
+ end
78
122
  end
79
123
 
80
124
  context "for a rotated MOV video" do
@@ -83,8 +127,13 @@ describe FormatParser::MOVParser do
83
127
  subject.call(File.open(path, 'rb'))
84
128
  end
85
129
 
86
- it('should have the correct height') { expect(result.height_px).to eq(640) }
87
- it('should have the correct width') { expect(result.width_px).to eq(360) }
130
+ it 'should have the correct height' do
131
+ expect(result.height_px).to eq(640)
132
+ end
133
+
134
+ it 'should have the correct width' do
135
+ expect(result.width_px).to eq(360)
136
+ end
88
137
  end
89
138
  end
90
139
  end
@@ -35,15 +35,41 @@ describe FormatParser::MP4Parser do
35
35
  context "for #{path}" do
36
36
  let(:result) { subject.call(File.open(path, 'rb')) }
37
37
 
38
- it('should not be nil') { expect(result).not_to be_nil }
39
- it('should have video nature') { expect(result.nature).to eq(:video) }
40
- it('should have MP4 video content type') { expect(result.content_type).to eq('video/mp4') }
41
- it('should have MP4 video format') { expect([:mp4, :mv4]).to include(result.format) }
42
- it('should have a non-zero height ') { expect(result.height_px).to be > 0 }
43
- it('should have a non-zero width') { expect(result.width_px).to be > 0 }
44
- it('should have a non-zero duration') { expect(result.media_duration_seconds).to be > 0 }
45
- it('should have a non-nil frame rate') { expect(result.frame_rate).not_to be_nil }
46
- it('should have intrinsics') { expect(result.intrinsics).not_to be_nil }
38
+ it 'should not be nil' do
39
+ expect(result).not_to be_nil
40
+ end
41
+
42
+ it 'should have video nature' do
43
+ expect(result.nature).to eq(:video)
44
+ end
45
+
46
+ it 'should have MP4 video content type' do
47
+ expect(result.content_type).to eq('video/mp4')
48
+ end
49
+
50
+ it 'should have MP4 video format' do
51
+ expect([:mp4, :mv4]).to include(result.format)
52
+ end
53
+
54
+ it 'should have a non-zero height ' do
55
+ expect(result.height_px).to be > 0
56
+ end
57
+
58
+ it 'should have a non-zero width' do
59
+ expect(result.width_px).to be > 0
60
+ end
61
+
62
+ it 'should have a non-zero duration' do
63
+ expect(result.media_duration_seconds).to be > 0
64
+ end
65
+
66
+ it 'should have a non-nil frame rate' do
67
+ expect(result.frame_rate).not_to be_nil
68
+ end
69
+
70
+ it 'should have intrinsics' do
71
+ expect(result.intrinsics).not_to be_nil
72
+ end
47
73
  end
48
74
  end
49
75
 
@@ -51,12 +77,29 @@ describe FormatParser::MP4Parser do
51
77
  context "for #{path}" do
52
78
  let(:result) { subject.call(File.open(path, 'rb')) }
53
79
 
54
- it('should not be nil') { expect(result).not_to be_nil }
55
- it('should have audio nature') { expect(result.nature).to eq(:audio) }
56
- it('should have MP4 audio content type') { expect(result.content_type).to eq('audio/mp4') }
57
- it('should have MP4 audio format') { expect([:m4a, :m4b, :m4p, :m4r]).to include(result.format) }
58
- it('should have a non-zero duration') { expect(result.media_duration_seconds).to be > 0 }
59
- it('should have intrinsics') { expect(result.intrinsics).not_to be_nil }
80
+ it 'should not be nil' do
81
+ expect(result).not_to be_nil
82
+ end
83
+
84
+ it 'should have audio nature' do
85
+ expect(result.nature).to eq(:audio)
86
+ end
87
+
88
+ it 'should have MP4 audio content type' do
89
+ expect(result.content_type).to eq('audio/mp4')
90
+ end
91
+
92
+ it 'should have MP4 audio format' do
93
+ expect([:m4a, :m4b, :m4p, :m4r]).to include(result.format)
94
+ end
95
+
96
+ it 'should have a non-zero duration' do
97
+ expect(result.media_duration_seconds).to be > 0
98
+ end
99
+
100
+ it 'should have intrinsics' do
101
+ expect(result.intrinsics).not_to be_nil
102
+ end
60
103
  end
61
104
  end
62
105
 
@@ -64,7 +107,9 @@ describe FormatParser::MP4Parser do
64
107
  context "for #{path}" do
65
108
  let(:result) { subject.call(File.open(path, 'rb')) }
66
109
 
67
- it('should be nil') { expect(result).to be_nil }
110
+ it 'should be nil' do
111
+ expect(result).to be_nil
112
+ end
68
113
  end
69
114
  end
70
115
 
@@ -74,10 +119,21 @@ describe FormatParser::MP4Parser do
74
119
  subject.call(File.open(path, 'rb'))
75
120
  end
76
121
 
77
- it('should have the correct height') { expect(result.height_px).to eq(360) }
78
- it('should have the correct width') { expect(result.width_px).to eq(640) }
79
- it('should have the correct duration') { expect(result.media_duration_seconds.truncate(2)).to eq(9.36) }
80
- it('should have the correct frame rate') { expect(result.frame_rate).to eq(30) }
122
+ it 'should have the correct height' do
123
+ expect(result.height_px).to eq(360)
124
+ end
125
+
126
+ it 'should have the correct width' do
127
+ expect(result.width_px).to eq(640)
128
+ end
129
+
130
+ it 'should have the correct duration' do
131
+ expect(result.media_duration_seconds.truncate(2)).to eq(9.36)
132
+ end
133
+
134
+ it 'should have the correct frame rate' do
135
+ expect(result.frame_rate).to eq(30)
136
+ end
81
137
  end
82
138
 
83
139
  context "for a scaled MP4 video" do
@@ -86,8 +142,13 @@ describe FormatParser::MP4Parser do
86
142
  subject.call(File.open(path, 'rb'))
87
143
  end
88
144
 
89
- it('should have the correct height') { expect(result.height_px).to eq(720) }
90
- it('should have the correct width') { expect(result.width_px).to eq(1280) }
145
+ it 'should have the correct height' do
146
+ expect(result.height_px).to eq(720)
147
+ end
148
+
149
+ it 'should have the correct width' do
150
+ expect(result.width_px).to eq(1280)
151
+ end
91
152
  end
92
153
 
93
154
  context "for a rotated MP4 video" do
@@ -96,8 +157,13 @@ describe FormatParser::MP4Parser do
96
157
  subject.call(File.open(path, 'rb'))
97
158
  end
98
159
 
99
- it('should have the correct height') { expect(result.height_px).to eq(640) }
100
- it('should have the correct width') { expect(result.width_px).to eq(360) }
160
+ it 'should have the correct height' do
161
+ expect(result.height_px).to eq(640)
162
+ end
163
+
164
+ it 'should have the correct width' do
165
+ expect(result.width_px).to eq(360)
166
+ end
101
167
  end
102
168
 
103
169
  context "for a multi-track MP4 video" do
@@ -106,9 +172,17 @@ describe FormatParser::MP4Parser do
106
172
  subject.call(File.open(path, 'rb'))
107
173
  end
108
174
 
109
- it('should have the correct height') { expect(result.height_px).to eq(1280) }
110
- it('should have the correct width') { expect(result.width_px).to eq(1024) }
111
- it('should have the correct frame rate') { expect(result.frame_rate).to eq(24) }
175
+ it 'should have the correct height' do
176
+ expect(result.height_px).to eq(1280)
177
+ end
178
+
179
+ it 'should have the correct width' do
180
+ expect(result.width_px).to eq(1024)
181
+ end
182
+
183
+ it 'should have the correct frame rate' do
184
+ expect(result.frame_rate).to eq(24)
185
+ end
112
186
  end
113
187
  end
114
188
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: format_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.3
4
+ version: 2.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Berman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-03-27 00:00:00.000000000 Z
12
+ date: 2023-03-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: exifr