mirror of
https://github.com/SubtitleEdit/subtitleedit.git
synced 2024-11-25 20:52:44 +01:00
Try to prevent crash parsing mp4/bdsup
This commit is contained in:
parent
01c8abb025
commit
e5dda77f59
@ -4,7 +4,7 @@
|
|||||||
3.5.11 (xth October 2019) BETA
|
3.5.11 (xth October 2019) BETA
|
||||||
* NEW:
|
* NEW:
|
||||||
* Join: Can now append with "add time" - thx Michael/Nickola
|
* Join: Can now append with "add time" - thx Michael/Nickola
|
||||||
* Add format AWS JSON files - thx jaccoud
|
* Add format AWS transcribe json - thx jaccoud
|
||||||
* Add new subtitle format - thx Zhen
|
* Add new subtitle format - thx Zhen
|
||||||
* Add new subtitle format
|
* Add new subtitle format
|
||||||
* Run only "Batch convert" in UI via "/batchconvert" - thx 07416
|
* Run only "Batch convert" in UI via "/batchconvert" - thx 07416
|
||||||
|
@ -427,6 +427,14 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
|
|||||||
|
|
||||||
private static PcsData ParsePicture(byte[] buffer, SupSegment segment)
|
private static PcsData ParsePicture(byte[] buffer, SupSegment segment)
|
||||||
{
|
{
|
||||||
|
if (buffer.Length < 11)
|
||||||
|
{
|
||||||
|
return new PcsData
|
||||||
|
{
|
||||||
|
CompositionState = CompositionState.Invalid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
var sb = new StringBuilder();
|
var sb = new StringBuilder();
|
||||||
var pcs = new PcsData
|
var pcs = new PcsData
|
||||||
{
|
{
|
||||||
@ -435,7 +443,7 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
|
|||||||
CompNum = BigEndianInt16(buffer, 5),
|
CompNum = BigEndianInt16(buffer, 5),
|
||||||
CompositionState = GetCompositionState(buffer[7]),
|
CompositionState = GetCompositionState(buffer[7]),
|
||||||
StartTime = segment.PtsTimestamp,
|
StartTime = segment.PtsTimestamp,
|
||||||
PaletteUpdate = (buffer[8] == 0x80),
|
PaletteUpdate = buffer[8] == 0x80,
|
||||||
PaletteId = buffer[9]
|
PaletteId = buffer[9]
|
||||||
};
|
};
|
||||||
// hi nibble: frame_rate, lo nibble: reserved
|
// hi nibble: frame_rate, lo nibble: reserved
|
||||||
@ -542,7 +550,7 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
|
|||||||
int objId = BigEndianInt16(buffer, 0); // 16bit object_id
|
int objId = BigEndianInt16(buffer, 0); // 16bit object_id
|
||||||
int objVer = buffer[2]; // 16bit object_id nikse - index 2 or 1???
|
int objVer = buffer[2]; // 16bit object_id nikse - index 2 or 1???
|
||||||
int objSeq = buffer[3]; // 8bit first_in_sequence (0x80),
|
int objSeq = buffer[3]; // 8bit first_in_sequence (0x80),
|
||||||
// last_in_sequence (0x40), 6bits reserved
|
// last_in_sequence (0x40), 6bits reserved
|
||||||
bool first = (objSeq & 0x80) == 0x80 || forceFirst;
|
bool first = (objSeq & 0x80) == 0x80 || forceFirst;
|
||||||
bool last = (objSeq & 0x40) == 0x40;
|
bool last = (objSeq & 0x40) == 0x40;
|
||||||
|
|
||||||
@ -602,159 +610,166 @@ namespace Nikse.SubtitleEdit.Core.BluRaySup
|
|||||||
var segment = fromMatroskaFile ? ParseSegmentHeaderFromMatroska(headerBuffer) : ParseSegmentHeader(headerBuffer, log);
|
var segment = fromMatroskaFile ? ParseSegmentHeaderFromMatroska(headerBuffer) : ParseSegmentHeader(headerBuffer, log);
|
||||||
position += headerBuffer.Length;
|
position += headerBuffer.Length;
|
||||||
|
|
||||||
// Read segment data
|
try
|
||||||
var buffer = new byte[segment.Size];
|
|
||||||
ms.Read(buffer, 0, buffer.Length);
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
log.Append(segmentCount + ": ");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (segment.Type)
|
|
||||||
{
|
{
|
||||||
case 0x14: // Palette
|
// Read segment data
|
||||||
if (latestPcs != null)
|
var buffer = new byte[segment.Size];
|
||||||
{
|
ms.Read(buffer, 0, buffer.Length);
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
log.AppendLine($"0x14 - Palette - PDS offset={position} size={segment.Size}");
|
log.Append(segmentCount + ": ");
|
||||||
#endif
|
#endif
|
||||||
var pds = ParsePds(buffer, segment);
|
|
||||||
#if DEBUG
|
switch (segment.Type)
|
||||||
log.AppendLine(pds.Message);
|
{
|
||||||
#endif
|
case 0x14: // Palette
|
||||||
if (pds.PaletteInfo != null)
|
if (latestPcs != null)
|
||||||
{
|
{
|
||||||
if (!palettes.ContainsKey(pds.PaletteId))
|
#if DEBUG
|
||||||
|
log.AppendLine($"0x14 - Palette - PDS offset={position} size={segment.Size}");
|
||||||
|
#endif
|
||||||
|
var pds = ParsePds(buffer, segment);
|
||||||
|
#if DEBUG
|
||||||
|
log.AppendLine(pds.Message);
|
||||||
|
#endif
|
||||||
|
if (pds.PaletteInfo != null)
|
||||||
{
|
{
|
||||||
palettes[pds.PaletteId] = new List<PaletteInfo>();
|
if (!palettes.ContainsKey(pds.PaletteId))
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (latestPcs.PaletteUpdate)
|
|
||||||
{
|
{
|
||||||
palettes[pds.PaletteId].RemoveAt(palettes[pds.PaletteId].Count - 1);
|
palettes[pds.PaletteId] = new List<PaletteInfo>();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (latestPcs.PaletteUpdate)
|
||||||
|
{
|
||||||
|
palettes[pds.PaletteId].RemoveAt(palettes[pds.PaletteId].Count - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
log.AppendLine("Extra Palette");
|
log.AppendLine("Extra Palette");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
palettes[pds.PaletteId].Add(pds.PaletteInfo);
|
||||||
}
|
}
|
||||||
palettes[pds.PaletteId].Add(pds.PaletteInfo);
|
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x15: // Image bitmap data
|
case 0x15: // Image bitmap data
|
||||||
if (latestPcs != null)
|
if (latestPcs != null)
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
log.AppendLine($"0x15 - Bitmap data - ODS offset={position} size={segment.Size}");
|
|
||||||
#endif
|
|
||||||
var ods = ParseOds(buffer, segment, forceFirstOds);
|
|
||||||
#if DEBUG
|
|
||||||
log.AppendLine(ods.Message);
|
|
||||||
#endif
|
|
||||||
if (!latestPcs.PaletteUpdate)
|
|
||||||
{
|
{
|
||||||
List<OdsData> odsList;
|
#if DEBUG
|
||||||
if (ods.IsFirst)
|
log.AppendLine($"0x15 - Bitmap data - ODS offset={position} size={segment.Size}");
|
||||||
|
#endif
|
||||||
|
var ods = ParseOds(buffer, segment, forceFirstOds);
|
||||||
|
#if DEBUG
|
||||||
|
log.AppendLine(ods.Message);
|
||||||
|
#endif
|
||||||
|
if (!latestPcs.PaletteUpdate)
|
||||||
{
|
{
|
||||||
odsList = new List<OdsData> { ods };
|
List<OdsData> odsList;
|
||||||
bitmapObjects[ods.ObjectId] = odsList;
|
if (ods.IsFirst)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (bitmapObjects.TryGetValue(ods.ObjectId, out odsList))
|
|
||||||
{
|
{
|
||||||
odsList.Add(ods);
|
odsList = new List<OdsData> { ods };
|
||||||
|
bitmapObjects[ods.ObjectId] = odsList;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
if (bitmapObjects.TryGetValue(ods.ObjectId, out odsList))
|
||||||
|
{
|
||||||
|
odsList.Add(ods);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
log.AppendLine($"INVALID ObjectId {ods.ObjectId} in ODS, offset={position}");
|
log.AppendLine($"INVALID ObjectId {ods.ObjectId} in ODS, offset={position}");
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
log.AppendLine($"Bitmap Data Ignore due to PaletteUpdate offset={position}");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
forceFirstOds = false;
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
|
|
||||||
|
case 0x16: // Picture time codes
|
||||||
|
if (latestPcs != null)
|
||||||
|
{
|
||||||
|
if (CompletePcs(latestPcs, bitmapObjects, palettes.Count > 0 ? palettes : lastPalettes))
|
||||||
|
{
|
||||||
|
pcsList.Add(latestPcs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
log.AppendLine($"0x16 - Picture codes, offset={position} size={segment.Size}");
|
||||||
|
#endif
|
||||||
|
forceFirstOds = true;
|
||||||
|
var nextPcs = ParsePicture(buffer, segment);
|
||||||
|
#if DEBUG
|
||||||
|
log.AppendLine(nextPcs.Message);
|
||||||
|
#endif
|
||||||
|
latestPcs = nextPcs;
|
||||||
|
if (latestPcs.CompositionState == CompositionState.EpochStart)
|
||||||
|
{
|
||||||
|
bitmapObjects.Clear();
|
||||||
|
palettes.Clear();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x17: // Window display
|
||||||
|
if (latestPcs != null)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
log.AppendLine($"Bitmap Data Ignore due to PaletteUpdate offset={position}");
|
log.AppendLine($"0x17 - Window display offset={position} size={segment.Size}");
|
||||||
#endif
|
#endif
|
||||||
|
int windowCount = buffer[0];
|
||||||
|
int offset = 0;
|
||||||
|
for (int nextWindow = 0; nextWindow < windowCount; nextWindow++)
|
||||||
|
{
|
||||||
|
int windowId = buffer[1 + offset];
|
||||||
|
int x = BigEndianInt16(buffer, 2 + offset);
|
||||||
|
int y = BigEndianInt16(buffer, 4 + offset);
|
||||||
|
int width = BigEndianInt16(buffer, 6 + offset);
|
||||||
|
int height = BigEndianInt16(buffer, 8 + offset);
|
||||||
|
log.AppendLine(string.Format("WinId: {4}, X: {0}, Y: {1}, Width: {2}, Height: {3}",
|
||||||
|
x, y, width, height, windowId));
|
||||||
|
offset += 9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
forceFirstOds = false;
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x16: // Picture time codes
|
case 0x80:
|
||||||
if (latestPcs != null)
|
forceFirstOds = true;
|
||||||
{
|
#if DEBUG
|
||||||
if (CompletePcs(latestPcs, bitmapObjects, palettes.Count > 0 ? palettes : lastPalettes))
|
log.AppendLine($"0x80 - END offset={position} size={segment.Size}");
|
||||||
|
#endif
|
||||||
|
if (latestPcs != null)
|
||||||
{
|
{
|
||||||
pcsList.Add(latestPcs);
|
if (CompletePcs(latestPcs, bitmapObjects, palettes.Count > 0 ? palettes : lastPalettes))
|
||||||
|
{
|
||||||
|
pcsList.Add(latestPcs);
|
||||||
|
}
|
||||||
|
latestPcs = null;
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
log.AppendLine($"0x16 - Picture codes, offset={position} size={segment.Size}");
|
log.AppendLine($"0x?? - END offset={position} UNKNOWN SEGMENT TYPE={segment.Type}");
|
||||||
#endif
|
#endif
|
||||||
forceFirstOds = true;
|
break;
|
||||||
var nextPcs = ParsePicture(buffer, segment);
|
}
|
||||||
#if DEBUG
|
}
|
||||||
log.AppendLine(nextPcs.Message);
|
catch (IndexOutOfRangeException e)
|
||||||
#endif
|
{
|
||||||
latestPcs = nextPcs;
|
log.Append($"Index of of range at pos {position - headerBuffer.Length}: {e.StackTrace}");
|
||||||
if (latestPcs.CompositionState == CompositionState.EpochStart)
|
|
||||||
{
|
|
||||||
bitmapObjects.Clear();
|
|
||||||
palettes.Clear();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x17: // Window display
|
|
||||||
if (latestPcs != null)
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
log.AppendLine($"0x17 - Window display offset={position} size={segment.Size}");
|
|
||||||
#endif
|
|
||||||
int windowCount = buffer[0];
|
|
||||||
int offset = 0;
|
|
||||||
for (int nextWindow = 0; nextWindow < windowCount; nextWindow++)
|
|
||||||
{
|
|
||||||
int windowId = buffer[1 + offset];
|
|
||||||
int x = BigEndianInt16(buffer, 2 + offset);
|
|
||||||
int y = BigEndianInt16(buffer, 4 + offset);
|
|
||||||
int width = BigEndianInt16(buffer, 6 + offset);
|
|
||||||
int height = BigEndianInt16(buffer, 8 + offset);
|
|
||||||
log.AppendLine(string.Format("WinId: {4}, X: {0}, Y: {1}, Width: {2}, Height: {3}",
|
|
||||||
x, y, width, height, windowId));
|
|
||||||
offset += 9;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x80:
|
|
||||||
forceFirstOds = true;
|
|
||||||
#if DEBUG
|
|
||||||
log.AppendLine($"0x80 - END offset={position} size={segment.Size}");
|
|
||||||
#endif
|
|
||||||
if (latestPcs != null)
|
|
||||||
{
|
|
||||||
if (CompletePcs(latestPcs, bitmapObjects, palettes.Count > 0 ? palettes : lastPalettes))
|
|
||||||
{
|
|
||||||
pcsList.Add(latestPcs);
|
|
||||||
}
|
|
||||||
latestPcs = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
#if DEBUG
|
|
||||||
log.AppendLine($"0x?? - END offset={position} UNKOWN SEGMENT TYPE={segment.Type}");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
position += segment.Size;
|
position += segment.Size;
|
||||||
segmentCount++;
|
segmentCount++;
|
||||||
|
@ -241,7 +241,7 @@ namespace Nikse.SubtitleEdit.Core.ContainerFormats.Mp4.Boxes
|
|||||||
var textIndex = 0;
|
var textIndex = 0;
|
||||||
while (index < allTimes.Count - 1)
|
while (index < allTimes.Count - 1)
|
||||||
{
|
{
|
||||||
if (index > 0 && SampleSizes[index + 1] == 2)
|
if (index > 0 && index + 1 < SampleSizes.Count && SampleSizes[index + 1] == 2)
|
||||||
{
|
{
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user