+ "Invalid length 0x%"PRIx64" > 0x%"PRIx64" for element "
+ "with ID 0x%"PRIX32" at 0x%"PRIx64"\n",
+ length, max_lengths[syntax->type], id, pos);
+ } else if (syntax->type != EBML_NONE) {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Element with ID 0x%"PRIX32" at pos. 0x%"PRIx64" has "
+ "unknown length, yet the length of an element of its "
+ "type must be known.\n", id, pos);
+ } else {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Found unknown-length element with ID 0x%"PRIX32" at "
+ "pos. 0x%"PRIx64" for which no syntax for parsing is "
+ "available.\n", id, pos);
+ }
+ return AVERROR_INVALIDDATA;
+ }
+
+ if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) {
+ // Loosing sync will likely manifest itself as encountering unknown
+ // elements which are not reliably distinguishable from elements
+ // belonging to future extensions of the format.
+ // We use a heuristic to detect such situations: If the current
+ // element is not expected at the current syntax level and there
+ // were only a few unknown elements in a row, then the element is
+ // skipped or considered defective based upon the length of the
+ // current element (i.e. how much would be skipped); if there were
+ // more than a few skipped elements in a row and skipping the current
+ // element would lead us more than SKIP_THRESHOLD away from the last
+ // known good position, then it is inferred that an error occurred.
+ // The dependency on the number of unknown elements in a row exists
+ // because the distance to the last known good position is
+ // automatically big if the last parsed element was big.
+ // In both cases, each unknown element is considered equivalent to
+ // UNKNOWN_EQUIV of skipped bytes for the check.
+ // The whole check is only done for non-seekable output, because
+ // in this situation skipped data can't simply be rechecked later.
+ // This is especially important when using unkown length elements
+ // as the check for whether a child exceeds its containing master
+ // element is not effective in this situation.
+ if (update_pos) {
+ matroska->unknown_count = 0;
+ } else {
+ int64_t dist = length + UNKNOWN_EQUIV * matroska->unknown_count++;
+
+ if (matroska->unknown_count > 3)
+ dist += pos_alt - matroska->resync_pos;
+
+ if (dist > SKIP_THRESHOLD) {
+ av_log(matroska->ctx, AV_LOG_ERROR,
+ "Unknown element %"PRIX32" at pos. 0x%"PRIx64" with "
+ "length 0x%"PRIx64" considered as invalid data. Last "
+ "known good position 0x%"PRIx64", %d unknown elements"
+ " in a row\n", id, pos, length, matroska->resync_pos,
+ matroska->unknown_count);
+ return AVERROR_INVALIDDATA;
+ }