OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/formats/mp4/box_definitions.h" | 5 #include "media/formats/mp4/box_definitions.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/numerics/safe_math.h" |
12 #include "base/strings/string_number_conversions.h" | 13 #include "base/strings/string_number_conversions.h" |
13 #include "media/base/media_switches.h" | 14 #include "media/base/media_switches.h" |
14 #include "media/base/video_types.h" | 15 #include "media/base/video_types.h" |
15 #include "media/base/video_util.h" | 16 #include "media/base/video_util.h" |
16 #include "media/filters/h264_parser.h" | 17 #include "media/filters/h264_parser.h" |
17 #include "media/formats/mp4/avc.h" | 18 #include "media/formats/mp4/avc.h" |
18 #include "media/formats/mp4/es_descriptor.h" | 19 #include "media/formats/mp4/es_descriptor.h" |
19 #include "media/formats/mp4/rcheck.h" | 20 #include "media/formats/mp4/rcheck.h" |
20 #include "media/media_features.h" | 21 #include "media/media_features.h" |
21 | 22 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 const SampleAuxiliaryInformationOffset& other) = default; | 111 const SampleAuxiliaryInformationOffset& other) = default; |
111 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {} | 112 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {} |
112 FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; } | 113 FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; } |
113 | 114 |
114 bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) { | 115 bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) { |
115 RCHECK(reader->ReadFullBoxHeader()); | 116 RCHECK(reader->ReadFullBoxHeader()); |
116 if (reader->flags() & 1) | 117 if (reader->flags() & 1) |
117 RCHECK(reader->SkipBytes(8)); | 118 RCHECK(reader->SkipBytes(8)); |
118 | 119 |
119 uint32_t count; | 120 uint32_t count; |
120 RCHECK(reader->Read4(&count) && | 121 RCHECK(reader->Read4(&count)); |
121 reader->HasBytes(count * (reader->version() == 1 ? 8 : 4))); | 122 int bytes_per_offset = reader->version() == 1 ? 8 : 4; |
| 123 |
| 124 base::CheckedNumeric<size_t> bytes_needed = |
| 125 base::CheckedNumeric<size_t>(bytes_per_offset); |
| 126 bytes_needed *= count; |
| 127 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(), |
| 128 "Extreme SAIO count exceeds implementation limit."); |
| 129 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie())); |
| 130 |
| 131 RCHECK(count <= offsets.max_size()); |
122 offsets.resize(count); | 132 offsets.resize(count); |
123 | 133 |
124 for (uint32_t i = 0; i < count; i++) { | 134 for (uint32_t i = 0; i < count; i++) { |
125 if (reader->version() == 1) { | 135 if (reader->version() == 1) { |
126 RCHECK(reader->Read8(&offsets[i])); | 136 RCHECK(reader->Read8(&offsets[i])); |
127 } else { | 137 } else { |
128 RCHECK(reader->Read4Into8(&offsets[i])); | 138 RCHECK(reader->Read4Into8(&offsets[i])); |
129 } | 139 } |
130 } | 140 } |
131 return true; | 141 return true; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 RCHECK(reader->Read1(initialization_vector + i)); | 178 RCHECK(reader->Read1(initialization_vector + i)); |
169 | 179 |
170 if (!has_subsamples) { | 180 if (!has_subsamples) { |
171 subsamples.clear(); | 181 subsamples.clear(); |
172 return true; | 182 return true; |
173 } | 183 } |
174 | 184 |
175 uint16_t subsample_count; | 185 uint16_t subsample_count; |
176 RCHECK(reader->Read2(&subsample_count)); | 186 RCHECK(reader->Read2(&subsample_count)); |
177 RCHECK(subsample_count > 0); | 187 RCHECK(subsample_count > 0); |
| 188 RCHECK(subsample_count <= subsamples.max_size()); |
178 subsamples.resize(subsample_count); | 189 subsamples.resize(subsample_count); |
179 for (SubsampleEntry& subsample : subsamples) { | 190 for (SubsampleEntry& subsample : subsamples) { |
180 uint16_t clear_bytes; | 191 uint16_t clear_bytes; |
181 uint32_t cypher_bytes; | 192 uint32_t cypher_bytes; |
182 RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes)); | 193 RCHECK(reader->Read2(&clear_bytes) && reader->Read4(&cypher_bytes)); |
183 subsample.clear_bytes = clear_bytes; | 194 subsample.clear_bytes = clear_bytes; |
184 subsample.cypher_bytes = cypher_bytes; | 195 subsample.cypher_bytes = cypher_bytes; |
185 } | 196 } |
186 return true; | 197 return true; |
187 } | 198 } |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
421 | 432 |
422 EditList::EditList() {} | 433 EditList::EditList() {} |
423 EditList::EditList(const EditList& other) = default; | 434 EditList::EditList(const EditList& other) = default; |
424 EditList::~EditList() {} | 435 EditList::~EditList() {} |
425 FourCC EditList::BoxType() const { return FOURCC_ELST; } | 436 FourCC EditList::BoxType() const { return FOURCC_ELST; } |
426 | 437 |
427 bool EditList::Parse(BoxReader* reader) { | 438 bool EditList::Parse(BoxReader* reader) { |
428 uint32_t count; | 439 uint32_t count; |
429 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count)); | 440 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count)); |
430 | 441 |
431 if (reader->version() == 1) { | 442 const size_t bytes_per_edit = reader->version() == 1 ? 20 : 12; |
432 RCHECK(reader->HasBytes(count * 20)); | 443 |
433 } else { | 444 base::CheckedNumeric<size_t> bytes_needed = |
434 RCHECK(reader->HasBytes(count * 12)); | 445 base::CheckedNumeric<size_t>(bytes_per_edit); |
435 } | 446 bytes_needed *= count; |
| 447 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(), |
| 448 "Extreme ELST count exceeds implementation limit."); |
| 449 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie())); |
| 450 |
| 451 RCHECK(count <= edits.max_size()); |
436 edits.resize(count); | 452 edits.resize(count); |
437 | 453 |
438 for (std::vector<EditListEntry>::iterator edit = edits.begin(); | 454 for (std::vector<EditListEntry>::iterator edit = edits.begin(); |
439 edit != edits.end(); ++edit) { | 455 edit != edits.end(); ++edit) { |
440 if (reader->version() == 1) { | 456 if (reader->version() == 1) { |
441 RCHECK(reader->Read8(&edit->segment_duration) && | 457 RCHECK(reader->Read8(&edit->segment_duration) && |
442 reader->Read8s(&edit->media_time)); | 458 reader->Read8s(&edit->media_time)); |
443 } else { | 459 } else { |
444 RCHECK(reader->Read4Into8(&edit->segment_duration) && | 460 RCHECK(reader->Read4Into8(&edit->segment_duration) && |
445 reader->Read4sInto8s(&edit->media_time)); | 461 reader->Read4sInto8s(&edit->media_time)); |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 } else { | 1090 } else { |
1075 data_offset = 0; | 1091 data_offset = 0; |
1076 } | 1092 } |
1077 | 1093 |
1078 uint32_t first_sample_flags = 0; | 1094 uint32_t first_sample_flags = 0; |
1079 if (first_sample_flags_present) | 1095 if (first_sample_flags_present) |
1080 RCHECK(reader->Read4(&first_sample_flags)); | 1096 RCHECK(reader->Read4(&first_sample_flags)); |
1081 | 1097 |
1082 int fields = sample_duration_present + sample_size_present + | 1098 int fields = sample_duration_present + sample_size_present + |
1083 sample_flags_present + sample_composition_time_offsets_present; | 1099 sample_flags_present + sample_composition_time_offsets_present; |
1084 RCHECK(reader->HasBytes(fields * sample_count)); | 1100 const size_t bytes_per_field = 4; |
1085 | 1101 |
1086 if (sample_duration_present) | 1102 base::CheckedNumeric<size_t> bytes_needed(fields); |
| 1103 bytes_needed *= bytes_per_field; |
| 1104 bytes_needed *= sample_count; |
| 1105 RCHECK_MEDIA_LOGGED( |
| 1106 bytes_needed.IsValid(), reader->media_log(), |
| 1107 "Extreme TRUN sample count exceeds implementation limit."); |
| 1108 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie())); |
| 1109 |
| 1110 if (sample_duration_present) { |
| 1111 RCHECK(sample_count <= sample_durations.max_size()); |
1087 sample_durations.resize(sample_count); | 1112 sample_durations.resize(sample_count); |
1088 if (sample_size_present) | 1113 } |
| 1114 if (sample_size_present) { |
| 1115 RCHECK(sample_count <= sample_sizes.max_size()); |
1089 sample_sizes.resize(sample_count); | 1116 sample_sizes.resize(sample_count); |
1090 if (sample_flags_present) | 1117 } |
| 1118 if (sample_flags_present) { |
| 1119 RCHECK(sample_count <= sample_flags.max_size()); |
1091 sample_flags.resize(sample_count); | 1120 sample_flags.resize(sample_count); |
1092 if (sample_composition_time_offsets_present) | 1121 } |
| 1122 if (sample_composition_time_offsets_present) { |
| 1123 RCHECK(sample_count <= sample_composition_time_offsets.max_size()); |
1093 sample_composition_time_offsets.resize(sample_count); | 1124 sample_composition_time_offsets.resize(sample_count); |
| 1125 } |
1094 | 1126 |
1095 for (uint32_t i = 0; i < sample_count; ++i) { | 1127 for (uint32_t i = 0; i < sample_count; ++i) { |
1096 if (sample_duration_present) | 1128 if (sample_duration_present) |
1097 RCHECK(reader->Read4(&sample_durations[i])); | 1129 RCHECK(reader->Read4(&sample_durations[i])); |
1098 if (sample_size_present) | 1130 if (sample_size_present) |
1099 RCHECK(reader->Read4(&sample_sizes[i])); | 1131 RCHECK(reader->Read4(&sample_sizes[i])); |
1100 if (sample_flags_present) | 1132 if (sample_flags_present) |
1101 RCHECK(reader->Read4(&sample_flags[i])); | 1133 RCHECK(reader->Read4(&sample_flags[i])); |
1102 if (sample_composition_time_offsets_present) | 1134 if (sample_composition_time_offsets_present) |
1103 RCHECK(reader->Read4s(&sample_composition_time_offsets[i])); | 1135 RCHECK(reader->Read4s(&sample_composition_time_offsets[i])); |
(...skipping 22 matching lines...) Expand all Loading... |
1126 RCHECK(reader->Read4(&grouping_type_parameter)); | 1158 RCHECK(reader->Read4(&grouping_type_parameter)); |
1127 | 1159 |
1128 if (grouping_type != FOURCC_SEIG) { | 1160 if (grouping_type != FOURCC_SEIG) { |
1129 DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type | 1161 DLOG(WARNING) << "SampleToGroup box with grouping_type '" << grouping_type |
1130 << "' is not supported."; | 1162 << "' is not supported."; |
1131 return true; | 1163 return true; |
1132 } | 1164 } |
1133 | 1165 |
1134 uint32_t count; | 1166 uint32_t count; |
1135 RCHECK(reader->Read4(&count)); | 1167 RCHECK(reader->Read4(&count)); |
| 1168 |
| 1169 const size_t bytes_per_entry = 8; |
| 1170 base::CheckedNumeric<size_t> bytes_needed = |
| 1171 base::CheckedNumeric<size_t>(bytes_per_entry); |
| 1172 bytes_needed *= count; |
| 1173 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(), |
| 1174 "Extreme SBGP count exceeds implementation limit."); |
| 1175 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie())); |
| 1176 |
| 1177 RCHECK(count <= entries.max_size()); |
1136 entries.resize(count); | 1178 entries.resize(count); |
1137 for (uint32_t i = 0; i < count; ++i) { | 1179 for (uint32_t i = 0; i < count; ++i) { |
1138 RCHECK(reader->Read4(&entries[i].sample_count) && | 1180 RCHECK(reader->Read4(&entries[i].sample_count) && |
1139 reader->Read4(&entries[i].group_description_index)); | 1181 reader->Read4(&entries[i].group_description_index)); |
1140 } | 1182 } |
1141 return true; | 1183 return true; |
1142 } | 1184 } |
1143 | 1185 |
1144 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry() | 1186 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry() |
1145 : is_encrypted(false), iv_size(0) {} | 1187 : is_encrypted(false), iv_size(0) {} |
(...skipping 22 matching lines...) Expand all Loading... |
1168 const size_t kKeyIdSize = 16; | 1210 const size_t kKeyIdSize = 16; |
1169 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize; | 1211 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize; |
1170 uint32_t default_length = 0; | 1212 uint32_t default_length = 0; |
1171 if (version == 1) { | 1213 if (version == 1) { |
1172 RCHECK(reader->Read4(&default_length)); | 1214 RCHECK(reader->Read4(&default_length)); |
1173 RCHECK(default_length == 0 || default_length >= kEntrySize); | 1215 RCHECK(default_length == 0 || default_length >= kEntrySize); |
1174 } | 1216 } |
1175 | 1217 |
1176 uint32_t count; | 1218 uint32_t count; |
1177 RCHECK(reader->Read4(&count)); | 1219 RCHECK(reader->Read4(&count)); |
| 1220 |
| 1221 // Check that we have at least two bytes for each entry before allocating a |
| 1222 // potentially huge entries vector. In reality each entry will require a |
| 1223 // variable number of bytes in excess of 2. |
| 1224 const int bytes_per_entry = 2; |
| 1225 base::CheckedNumeric<size_t> bytes_needed = |
| 1226 base::CheckedNumeric<size_t>(bytes_per_entry); |
| 1227 bytes_needed *= count; |
| 1228 RCHECK_MEDIA_LOGGED(bytes_needed.IsValid(), reader->media_log(), |
| 1229 "Extreme SGPD count exceeds implementation limit."); |
| 1230 RCHECK(reader->HasBytes(bytes_needed.ValueOrDie())); |
| 1231 |
| 1232 RCHECK(count <= entries.max_size()); |
1178 entries.resize(count); | 1233 entries.resize(count); |
1179 for (uint32_t i = 0; i < count; ++i) { | 1234 for (uint32_t i = 0; i < count; ++i) { |
1180 if (version == 1) { | 1235 if (version == 1) { |
1181 if (default_length == 0) { | 1236 if (default_length == 0) { |
1182 uint32_t description_length = 0; | 1237 uint32_t description_length = 0; |
1183 RCHECK(reader->Read4(&description_length)); | 1238 RCHECK(reader->Read4(&description_length)); |
1184 RCHECK(description_length >= kEntrySize); | 1239 RCHECK(description_length >= kEntrySize); |
1185 } | 1240 } |
1186 } | 1241 } |
1187 | 1242 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1251 IndependentAndDisposableSamples::IndependentAndDisposableSamples( | 1306 IndependentAndDisposableSamples::IndependentAndDisposableSamples( |
1252 const IndependentAndDisposableSamples& other) = default; | 1307 const IndependentAndDisposableSamples& other) = default; |
1253 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {} | 1308 IndependentAndDisposableSamples::~IndependentAndDisposableSamples() {} |
1254 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; } | 1309 FourCC IndependentAndDisposableSamples::BoxType() const { return FOURCC_SDTP; } |
1255 | 1310 |
1256 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) { | 1311 bool IndependentAndDisposableSamples::Parse(BoxReader* reader) { |
1257 RCHECK(reader->ReadFullBoxHeader()); | 1312 RCHECK(reader->ReadFullBoxHeader()); |
1258 RCHECK(reader->version() == 0); | 1313 RCHECK(reader->version() == 0); |
1259 RCHECK(reader->flags() == 0); | 1314 RCHECK(reader->flags() == 0); |
1260 | 1315 |
1261 int sample_count = reader->box_size() - reader->pos(); | 1316 size_t sample_count = reader->box_size() - reader->pos(); |
| 1317 RCHECK(sample_count <= sample_depends_on_.max_size()); |
1262 sample_depends_on_.resize(sample_count); | 1318 sample_depends_on_.resize(sample_count); |
1263 for (int i = 0; i < sample_count; ++i) { | 1319 for (size_t i = 0; i < sample_count; ++i) { |
1264 uint8_t sample_info; | 1320 uint8_t sample_info; |
1265 RCHECK(reader->Read1(&sample_info)); | 1321 RCHECK(reader->Read1(&sample_info)); |
1266 | 1322 |
1267 sample_depends_on_[i] = | 1323 sample_depends_on_[i] = |
1268 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3); | 1324 static_cast<SampleDependsOn>((sample_info >> 4) & 0x3); |
1269 | 1325 |
1270 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved); | 1326 RCHECK(sample_depends_on_[i] != kSampleDependsOnReserved); |
1271 } | 1327 } |
1272 | 1328 |
1273 return true; | 1329 return true; |
1274 } | 1330 } |
1275 | 1331 |
1276 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( | 1332 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( |
1277 size_t i) const { | 1333 size_t i) const { |
1278 if (i >= sample_depends_on_.size()) | 1334 if (i >= sample_depends_on_.size()) |
1279 return kSampleDependsOnUnknown; | 1335 return kSampleDependsOnUnknown; |
1280 | 1336 |
1281 return sample_depends_on_[i]; | 1337 return sample_depends_on_[i]; |
1282 } | 1338 } |
1283 | 1339 |
1284 } // namespace mp4 | 1340 } // namespace mp4 |
1285 } // namespace media | 1341 } // namespace media |
OLD | NEW |