defend against badly-formatted cue points
Change-Id: I72bab89f0828b2c5275a4c4b3ac22ee61a173ddf
This commit is contained in:
parent
aec650fed7
commit
43f77d54bd
155
mkvparser.cpp
155
mkvparser.cpp
@ -1830,7 +1830,7 @@ void Cues::PreloadCuePoint(
|
||||
cue_points_size = n;
|
||||
}
|
||||
|
||||
CuePoint* const pCP = new CuePoint(pos);
|
||||
CuePoint* const pCP = new CuePoint(m_preload_count, pos);
|
||||
m_cue_points[m_preload_count++] = pCP;
|
||||
}
|
||||
|
||||
@ -1880,8 +1880,9 @@ bool Cues::LoadCuePoint() const
|
||||
|
||||
CuePoint* const pCP = m_cue_points[m_count];
|
||||
assert(pCP);
|
||||
assert((pCP->GetTimeCode() >= 0) || (-pCP->GetTimeCode() == idpos));
|
||||
|
||||
pCP->Load(pReader, idpos);
|
||||
pCP->Load(pReader);
|
||||
++m_count;
|
||||
--m_preload_count;
|
||||
|
||||
@ -1939,7 +1940,7 @@ bool Cues::Find(
|
||||
CuePoint* const pCP = *k;
|
||||
assert(pCP);
|
||||
|
||||
pCP->Load(pReader, 0);
|
||||
pCP->Load(pReader);
|
||||
|
||||
const long long t = pCP->GetTime(m_pSegment);
|
||||
|
||||
@ -2032,7 +2033,50 @@ bool Cues::FindNext(
|
||||
#endif
|
||||
|
||||
|
||||
CuePoint::CuePoint(long long pos) :
|
||||
bool Cues::GetNext(
|
||||
const CuePoint* pCurrCP,
|
||||
const Track* pTrack,
|
||||
const CuePoint*& pNextCP,
|
||||
const CuePoint::TrackPosition*& pNextTP) const
|
||||
{
|
||||
assert(pCurrCP);
|
||||
assert(pCurrCP->GetTimeCode() >= 0);
|
||||
assert(pTrack);
|
||||
assert(m_cue_points);
|
||||
assert(m_count >= 1);
|
||||
|
||||
const size_t count = m_count + m_preload_count;
|
||||
|
||||
size_t index = pCurrCP->m_index;
|
||||
assert(index < count);
|
||||
|
||||
CuePoint* const* pp = m_cue_points;
|
||||
assert(pp);
|
||||
assert(pp[index] == pCurrCP);
|
||||
|
||||
++index;
|
||||
|
||||
if (index >= count)
|
||||
return false;
|
||||
|
||||
CuePoint* const p = pp[index];
|
||||
assert(p);
|
||||
|
||||
p->Load(m_pSegment->m_pReader);
|
||||
|
||||
pNextCP = p;
|
||||
|
||||
pNextTP = pNextCP->Find(pTrack);
|
||||
assert(pNextTP); //TODO
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
CuePoint::CuePoint(size_t idx, long long pos) :
|
||||
m_index(idx),
|
||||
m_timecode(-1 * pos),
|
||||
m_track_positions(NULL),
|
||||
m_track_positions_count(0)
|
||||
@ -2047,7 +2091,7 @@ CuePoint::~CuePoint()
|
||||
}
|
||||
|
||||
|
||||
void CuePoint::Load(IMkvReader* pReader, long long idpos)
|
||||
void CuePoint::Load(IMkvReader* pReader)
|
||||
{
|
||||
//odbgstream os;
|
||||
//os << "CuePoint::Load(begin): timecode=" << m_timecode << endl;
|
||||
@ -2058,8 +2102,7 @@ void CuePoint::Load(IMkvReader* pReader, long long idpos)
|
||||
assert(m_track_positions == NULL);
|
||||
assert(m_track_positions_count == 0);
|
||||
|
||||
long long pos_ = -1 * m_timecode;
|
||||
assert((idpos <= 0) || (idpos == pos_));
|
||||
long long pos_ = -m_timecode;
|
||||
|
||||
long long stop;
|
||||
|
||||
@ -2534,7 +2577,7 @@ void Segment::GetCluster(
|
||||
{
|
||||
pCluster = *i;
|
||||
assert(pCluster);
|
||||
assert(pCluster->m_index == 0);
|
||||
assert(pCluster->m_index == 0); //m_clusterCount > 0
|
||||
assert(pCluster->m_pSegment == this);
|
||||
|
||||
if (time_ns <= pCluster->GetTime())
|
||||
@ -2731,9 +2774,7 @@ bool Segment::SearchCues(
|
||||
else
|
||||
{
|
||||
pBlockEntry = pCluster->GetEntry(*pCP, *pTP);
|
||||
assert(pBlockEntry);
|
||||
|
||||
return true;
|
||||
return pBlockEntry ? true : false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2748,9 +2789,7 @@ bool Segment::SearchCues(
|
||||
assert(m_clusters[idx] == pCluster);
|
||||
|
||||
pBlockEntry = pCluster->GetEntry(*pCP, *pTP);
|
||||
assert(pBlockEntry);
|
||||
|
||||
return true;
|
||||
return pBlockEntry ? true : false;
|
||||
}
|
||||
|
||||
|
||||
@ -2766,7 +2805,7 @@ const SegmentInfo* Segment::GetInfo() const
|
||||
}
|
||||
|
||||
|
||||
Cues* Segment::GetCues() const
|
||||
const Cues* Segment::GetCues() const
|
||||
{
|
||||
return m_pCues;
|
||||
}
|
||||
@ -3986,23 +4025,85 @@ Cluster::GetEntry(
|
||||
const CuePoint::TrackPosition& tp)
|
||||
{
|
||||
assert(m_pSegment);
|
||||
assert(tp.m_block > 0);
|
||||
|
||||
LoadBlockEntries();
|
||||
assert(m_entries); //TODO: handle empty cluster
|
||||
assert(m_entriesCount > 0);
|
||||
assert(tp.m_block <= (long long)m_entriesCount); //blocks are 1-based
|
||||
|
||||
const size_t block = static_cast<size_t>(tp.m_block);
|
||||
const size_t index = block - 1;
|
||||
if (m_entries == NULL)
|
||||
return NULL;
|
||||
|
||||
const BlockEntry* const pEntry = m_entries[index];
|
||||
assert(pEntry);
|
||||
assert(!pEntry->EOS());
|
||||
assert(pEntry->GetBlock()->GetTrackNumber() == tp.m_track);
|
||||
assert(pEntry->GetBlock()->GetTimeCode(this) == cp.GetTimeCode());
|
||||
const long long count = m_entriesCount;
|
||||
|
||||
return pEntry;
|
||||
if (count <= 0)
|
||||
return NULL;
|
||||
|
||||
const long long tc = cp.GetTimeCode();
|
||||
|
||||
if ((tp.m_block > 0) && (tp.m_block <= count))
|
||||
{
|
||||
const size_t block = static_cast<size_t>(tp.m_block);
|
||||
const size_t index = block - 1;
|
||||
|
||||
const BlockEntry* const pEntry = m_entries[index];
|
||||
assert(pEntry);
|
||||
assert(!pEntry->EOS());
|
||||
|
||||
const Block* const pBlock = pEntry->GetBlock();
|
||||
assert(pBlock);
|
||||
|
||||
if ((pBlock->GetTrackNumber() == tp.m_track) &&
|
||||
(pBlock->GetTimeCode(this) == tc))
|
||||
{
|
||||
return pEntry;
|
||||
}
|
||||
}
|
||||
|
||||
const BlockEntry* const* i = m_entries;
|
||||
const BlockEntry* const* const j = i + count;
|
||||
|
||||
while (i != j)
|
||||
{
|
||||
const BlockEntry* const pEntry = *i++;
|
||||
assert(pEntry);
|
||||
assert(!pEntry->EOS());
|
||||
|
||||
const Block* const pBlock = pEntry->GetBlock();
|
||||
assert(pBlock);
|
||||
|
||||
if (pBlock->GetTrackNumber() != tp.m_track)
|
||||
continue;
|
||||
|
||||
const long long tc_ = pBlock->GetTimeCode(this);
|
||||
|
||||
if (tc_ < tc)
|
||||
continue;
|
||||
|
||||
if (tc_ > tc)
|
||||
return NULL;
|
||||
|
||||
const Tracks* const pTracks = m_pSegment->GetTracks();
|
||||
assert(pTracks);
|
||||
|
||||
const long tn = static_cast<long>(tp.m_track);
|
||||
const Track* const pTrack = pTracks->GetTrackByNumber(tn);
|
||||
|
||||
if (pTrack == NULL)
|
||||
return NULL;
|
||||
|
||||
const long long type = pTrack->GetType();
|
||||
|
||||
if (type == 2) //audio
|
||||
return pEntry;
|
||||
|
||||
if (type != 1) //not video
|
||||
return NULL;
|
||||
|
||||
if (!pBlock->IsKey())
|
||||
return NULL;
|
||||
|
||||
return pEntry;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -334,18 +334,19 @@ private:
|
||||
char* m_pTitleAsUTF8;
|
||||
};
|
||||
|
||||
|
||||
class Cues;
|
||||
class CuePoint
|
||||
{
|
||||
friend class Cues;
|
||||
|
||||
CuePoint(size_t, long long);
|
||||
~CuePoint();
|
||||
|
||||
CuePoint(const CuePoint&);
|
||||
CuePoint& operator=(const CuePoint&);
|
||||
|
||||
public:
|
||||
explicit CuePoint(long long);
|
||||
~CuePoint();
|
||||
|
||||
//void Parse(IMkvReader*, long long start, long long size);
|
||||
void Load(IMkvReader*, long long);
|
||||
void Load(IMkvReader*);
|
||||
|
||||
long long GetTimeCode() const; //absolute but unscaled
|
||||
long long GetTime(Segment*) const; //absolute and scaled (ns units)
|
||||
@ -365,7 +366,7 @@ public:
|
||||
const TrackPosition* Find(const Track*) const;
|
||||
|
||||
private:
|
||||
//long long m_pos;
|
||||
const size_t m_index;
|
||||
long long m_timecode;
|
||||
TrackPosition* m_track_positions;
|
||||
size_t m_track_positions_count;
|
||||
@ -375,6 +376,11 @@ private:
|
||||
|
||||
class Cues
|
||||
{
|
||||
friend class Segment;
|
||||
|
||||
Cues(Segment*, long long start, long long size);
|
||||
~Cues();
|
||||
|
||||
Cues(const Cues&);
|
||||
Cues& operator=(const Cues&);
|
||||
|
||||
@ -383,9 +389,6 @@ public:
|
||||
const long long m_start;
|
||||
const long long m_size;
|
||||
|
||||
Cues(Segment*, long long start, long long size);
|
||||
~Cues();
|
||||
|
||||
bool Find( //lower bound of time_ns
|
||||
long long time_ns,
|
||||
const Track*,
|
||||
@ -400,6 +403,12 @@ public:
|
||||
const CuePoint::TrackPosition*&) const;
|
||||
#endif
|
||||
|
||||
bool GetNext(
|
||||
const CuePoint*,
|
||||
const Track*,
|
||||
const CuePoint*&,
|
||||
const CuePoint::TrackPosition*&) const;
|
||||
|
||||
private:
|
||||
void Init() const;
|
||||
bool LoadCuePoint() const;
|
||||
@ -514,7 +523,7 @@ public:
|
||||
Cluster*&,
|
||||
const BlockEntry*&);
|
||||
|
||||
Cues* GetCues() const;
|
||||
const Cues* GetCues() const;
|
||||
|
||||
private:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user