format_parser 2.4.3 → 2.4.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7ed2f3d1a503aee2a0b68f00dfae5253fa88cb9ab95b61066642749785542c06
4
- data.tar.gz: 3cac7120ef119969273568714fa3f75c07e3493bd80c18b89e4a7ac93efbc9dd
3
+ metadata.gz: 7daa912b01159c41fc44b099188bac919984d4e0d75000acc7053e221b719f06
4
+ data.tar.gz: d081b9d2e1bbe5458b1ca57a5d1140c4cf1ad289a2d1af8557093c201b6969b4
5
5
  SHA512:
6
- metadata.gz: 311393234d4bc595a81169dcfa658b872c539179fba29149d7794df64d388ebbad7e1bdbf8f963018b438c3ad0a350a1f23f47fd1a383a0d50d6897f429c727c
7
- data.tar.gz: e73d90e24cef65d936eebd0765403b3d83e52fdb6bf3640bfabba2afd2b059d4a85a1010fca6ff575e6e0ff84e003cc75fa1bb4a8cb2adbff0c1fb55e97161d1
6
+ metadata.gz: 8e19114d58216267ea215e91f6ec0d616eb58459d0a052f755decdb7fc3f7b7d653f6ab17a79d12e09039df538d2c7361cdee44e015802378489ca186e333fbc
7
+ data.tar.gz: c1a3b6fe0c05ec3002e1f823f14d06d95eec0f96f411190970fa954080827f08ca14ecb50b638edd23155c72f76b14da7ba305770adffa120b329a39c7557033
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 2.4.5
2
+ * Disable `udta` ISOBMFF box parsing, since their contents are not guaranteed to be consistent with the spec.
3
+
4
+ ## 2.4.4
5
+ * Prevent infinite loops when parsing ISOBMFF boxes with size = 0 (meaning that the box extends to the end of the file).
6
+
1
7
  ## 2.4.3
2
8
  * Improve resiliency in ISOBMFF parsing to missing mandatory boxes and fields.
3
9
  * Simplify ISOBMFF frame rate calculations.
@@ -1,3 +1,3 @@
1
1
  module FormatParser
2
- VERSION = '2.4.3'
2
+ VERSION = '2.4.5'
3
3
  end
@@ -116,7 +116,7 @@ module FormatParser
116
116
  'trak' => :container,
117
117
  # 'trex' => :trex,
118
118
  # 'tsel' => :tsel,
119
- 'udta' => :container,
119
+ # 'udta' => :container,
120
120
  # 'url ' => :dref_url,
121
121
  # 'urn ' => :dref_urn,
122
122
  'uuid' => :uuid,
@@ -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.5
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-04-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: exifr