format_parser 0.21.0 → 0.21.1
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.md +5 -0
- data/lib/format_parser/version.rb +1 -1
- data/lib/parsers/mpeg_parser.rb +13 -17
- data/spec/parsers/mpeg_parser_spec.rb +21 -0
- 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: 916f22d0efd27a6e32065b50c51a4a482664c344669aa1f9586769ccf2be7b06
|
4
|
+
data.tar.gz: 3fd1b2ba7285ca69bb8d4c14c9f83e4001b55fee7e85332d97cbdbd36620597f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df680824b240f15df52fbc6c14d44f9b5fb99a93fb69cf191db6027a9871115f5e3e5bbaec48751853683b01b8e87b4266b0bbfb23700901910f2ce0f8da1137
|
7
|
+
data.tar.gz: d944a5db3fb2e1d06435b10bfc6aa0651312b45393180b08cf7a7f0b6237a0804b90a216cdeaf770e50de1af5bf31234f987e6fabc0e72bcb682e59a87cf2e7a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## 0.21.1
|
2
|
+
* MPEG: Ensure parsing does not inadvertently return an Integer instead of Result|nil
|
3
|
+
* MPEG: Scan further into the MPEG file than previously (scan 32 1KB chunks)
|
4
|
+
* MPEG: Ensure the parser does not raise an exception when there is no data to read for scanning beyound the initial header
|
5
|
+
|
1
6
|
## 0.21.0
|
2
7
|
* Adds support for MPEG video files
|
3
8
|
|
data/lib/parsers/mpeg_parser.rb
CHANGED
@@ -26,9 +26,8 @@ class FormatParser::MPEGParser
|
|
26
26
|
|
27
27
|
PACK_HEADER_START_CODE = [0x00, 0x00, 0x01, 0xBA].pack('C*')
|
28
28
|
SEQUENCE_HEADER_START_CODE = [0xB3].pack('C*')
|
29
|
-
|
30
|
-
|
31
|
-
BYTES_TO_READ_PER_TIME = 1024
|
29
|
+
MAX_BLOCK_READS = 32
|
30
|
+
BYTES_TO_READ_PER_READ = 1024
|
32
31
|
|
33
32
|
def self.likely_match?(filename)
|
34
33
|
filename =~ /\.(mpg|mpeg)$/i
|
@@ -37,18 +36,19 @@ class FormatParser::MPEGParser
|
|
37
36
|
def self.call(io)
|
38
37
|
return unless matches_mpeg_header?(io)
|
39
38
|
|
40
|
-
# We are looping though the stream because there can be several sequence headers and some of them are not
|
41
|
-
# If we detect that the header is not
|
39
|
+
# We are looping though the stream because there can be several sequence headers and some of them are not useful.
|
40
|
+
# If we detect that the header is not useful, then we look for the next one for SEEK_FOR_SEQUENCE_HEADER_TIMES_LIMIT
|
42
41
|
# If we reach the EOF, then the mpg is likely to be corrupted and we return nil
|
43
|
-
|
44
|
-
|
42
|
+
MAX_BLOCK_READS.times do
|
43
|
+
next unless pos = find_next_header_code_pos(io)
|
44
|
+
io.seek(pos + 1)
|
45
45
|
horizontal_size, vertical_size = parse_image_size(io)
|
46
46
|
ratio_code, rate_code = parse_rate_information(io)
|
47
|
-
|
48
47
|
if valid_aspect_ratio_code?(ratio_code) && valid_frame_rate_code?(rate_code)
|
49
48
|
return file_info(horizontal_size, vertical_size, ratio_code, rate_code)
|
50
49
|
end
|
51
50
|
end
|
51
|
+
nil # otherwise the return value of Integer#times will be returned
|
52
52
|
rescue FormatParser::IOUtils::InvalidRead
|
53
53
|
nil
|
54
54
|
end
|
@@ -90,15 +90,11 @@ class FormatParser::MPEGParser
|
|
90
90
|
# Returns the position of the next sequence package content in the stream
|
91
91
|
# This method will read BYTES_TO_READ_PER_TIME in each loop for a maximum amount of SEEK_FOR_SEQUENCE_HEADER_START_CODE_TIMES_LIMIT times
|
92
92
|
# If the package is not found, then it returns nil.
|
93
|
-
def self.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
new_io_pos = io.pos - BYTES_TO_READ_PER_TIME + header_relative_index + 1
|
99
|
-
io.seek(new_io_pos)
|
100
|
-
return new_io_pos
|
101
|
-
end
|
93
|
+
def self.find_next_header_code_pos(io)
|
94
|
+
pos_before_read = io.pos
|
95
|
+
bin_str = io.read(BYTES_TO_READ_PER_READ) # bin_str might be nil if we are at EOF
|
96
|
+
header_relative_index = bin_str && bin_str.index(SEQUENCE_HEADER_START_CODE)
|
97
|
+
return pos_before_read + header_relative_index if header_relative_index
|
102
98
|
end
|
103
99
|
|
104
100
|
# If the first 4 bytes of the stream are equal to 00 00 01 BA, the pack start code for the Pack Header, then it's an MPEG file.
|
@@ -12,6 +12,27 @@ describe FormatParser::MPEGParser do
|
|
12
12
|
expect(parse_result.intrinsics[:frame_rate]).to eq('30')
|
13
13
|
end
|
14
14
|
|
15
|
+
it 'returns a nil if it is necessary to iterate over a very large number of bytes and the requisite sequences are not detected' do
|
16
|
+
bytes_buffer = StringIO.new
|
17
|
+
bytes_buffer.write([0x00, 0x00, 0x01, 0xBA].pack('C*')) # MPEG header
|
18
|
+
zero_bytes = [0x00].pack('C') * (1024 * 1024 * 5)
|
19
|
+
bytes_buffer.write(zero_bytes)
|
20
|
+
|
21
|
+
bytes_buffer.rewind
|
22
|
+
|
23
|
+
parse_result = described_class.call(bytes_buffer)
|
24
|
+
expect(parse_result).to be_nil
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'returns a nil if the IO only contains the MPEG header bytes at the start and nothing else' do
|
28
|
+
bytes_buffer = StringIO.new
|
29
|
+
bytes_buffer.write([0x00, 0x00, 0x01, 0xBA].pack('C*')) # MPEG header
|
30
|
+
bytes_buffer.rewind
|
31
|
+
|
32
|
+
parse_result = described_class.call(bytes_buffer)
|
33
|
+
expect(parse_result).to be_nil
|
34
|
+
end
|
35
|
+
|
15
36
|
it 'parses a file with mpeg extension' do
|
16
37
|
parse_result = described_class.call(File.open(__dir__ + '/../fixtures/MPG/video2.mpeg', 'rb'))
|
17
38
|
|
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: 0.21.
|
4
|
+
version: 0.21.1
|
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: 2020-
|
12
|
+
date: 2020-04-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ks
|