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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ad2245de4a2119c7572c3962ad14abbf16395b2bec4064b218ee9f99d1e7c24b
4
- data.tar.gz: b982bcc7f6626b66684db532317b0c0d35cd062aa89766ea1a230f93e7d996d6
3
+ metadata.gz: 916f22d0efd27a6e32065b50c51a4a482664c344669aa1f9586769ccf2be7b06
4
+ data.tar.gz: 3fd1b2ba7285ca69bb8d4c14c9f83e4001b55fee7e85332d97cbdbd36620597f
5
5
  SHA512:
6
- metadata.gz: 2df2a3763e12e2bb0c70a8f5ec3319fcf6a3210a73461dc8abb5ec2af706028403eca48cf8c589bd40122dff0cfdabce383a79b1253237e219a5c89936ec0a5e
7
- data.tar.gz: 0ca6084649313b2c7ad32204b4c8b745f13dbf6cf2c347cb7c80ca7976b964f00feabd9666c0372e9a6c10e4ed250500ed4e202cdb687372cbd369378b7a0faa
6
+ metadata.gz: df680824b240f15df52fbc6c14d44f9b5fb99a93fb69cf191db6027a9871115f5e3e5bbaec48751853683b01b8e87b4266b0bbfb23700901910f2ce0f8da1137
7
+ data.tar.gz: d944a5db3fb2e1d06435b10bfc6aa0651312b45393180b08cf7a7f0b6237a0804b90a216cdeaf770e50de1af5bf31234f987e6fabc0e72bcb682e59a87cf2e7a
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module FormatParser
2
- VERSION = '0.21.0'
2
+ VERSION = '0.21.1'
3
3
  end
@@ -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
- SEEK_FOR_SEQUENCE_HEADER_TIMES_LIMIT = 4
30
- SEEK_FOR_SEQUENCE_HEADER_START_CODE_TIMES_LIMIT = 4
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 usefull.
41
- # If we detect that the header is not usefull, then we look for the next one for SEEK_FOR_SEQUENCE_HEADER_TIMES_LIMIT
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
- SEEK_FOR_SEQUENCE_HEADER_TIMES_LIMIT.times do
44
- return if fetch_next_sequence_header_code_position(io).nil?
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.fetch_next_sequence_header_code_position(io)
94
- SEEK_FOR_SEQUENCE_HEADER_START_CODE_TIMES_LIMIT.times do
95
- bytes_stream_read = io.read(BYTES_TO_READ_PER_TIME)
96
- header_relative_index = bytes_stream_read.index(SEQUENCE_HEADER_START_CODE)
97
- next if header_relative_index.nil?
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.0
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-03-27 00:00:00.000000000 Z
12
+ date: 2020-04-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ks