Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
6f8e8326
Commit
6f8e8326
authored
Dec 26, 2012
by
Denis Charmet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle with resilience unknown ebml elements
Fix #7884 and #7887 by implementing the first proposition.
parent
ca80c3e8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
71 additions
and
16 deletions
+71
-16
modules/demux/mkv/Ebml_parser.cpp
modules/demux/mkv/Ebml_parser.cpp
+65
-11
modules/demux/mkv/Ebml_parser.hpp
modules/demux/mkv/Ebml_parser.hpp
+6
-5
No files found.
modules/demux/mkv/Ebml_parser.cpp
View file @
6f8e8326
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
* Ebml Stream parser
* Ebml Stream parser
*****************************************************************************/
*****************************************************************************/
EbmlParser
::
EbmlParser
(
EbmlStream
*
es
,
EbmlElement
*
el_start
,
demux_t
*
p_demux
)
:
EbmlParser
::
EbmlParser
(
EbmlStream
*
es
,
EbmlElement
*
el_start
,
demux_t
*
p_demux
)
:
p_demux
(
p_demux
),
m_es
(
es
),
m_es
(
es
),
mi_level
(
1
),
mi_level
(
1
),
m_got
(
NULL
),
m_got
(
NULL
),
...
@@ -103,7 +104,7 @@ void EbmlParser::Up( void )
...
@@ -103,7 +104,7 @@ void EbmlParser::Up( void )
{
{
if
(
mi_user_level
==
mi_level
)
if
(
mi_user_level
==
mi_level
)
{
{
fprintf
(
stderr
,
"MKV/Ebml Parser: Up cannot escape itself
\n
"
);
msg_Warn
(
p_demux
,
"MKV/Ebml Parser: Up cannot escape itself
"
);
}
}
mi_user_level
--
;
mi_user_level
--
;
...
@@ -133,15 +134,17 @@ void EbmlParser::Reset( demux_t *p_demux )
...
@@ -133,15 +134,17 @@ void EbmlParser::Reset( demux_t *p_demux )
m_el
[
mi_level
]
=
NULL
;
m_el
[
mi_level
]
=
NULL
;
mi_level
--
;
mi_level
--
;
}
}
this
->
p_demux
=
p_demux
;
mi_user_level
=
mi_level
=
1
;
mi_user_level
=
mi_level
=
1
;
// a little faster and cleaner
// a little faster and cleaner
m_es
->
I_O
().
setFilePointer
(
static_cast
<
KaxSegment
*>
(
m_el
[
0
])
->
GetGlobalPosition
(
0
)
);
m_es
->
I_O
().
setFilePointer
(
static_cast
<
KaxSegment
*>
(
m_el
[
0
])
->
GetGlobalPosition
(
0
)
);
mb_dummy
=
var_InheritBool
(
p_demux
,
"mkv-use-dummy"
);
mb_dummy
=
var_InheritBool
(
p_demux
,
"mkv-use-dummy"
);
}
}
EbmlElement
*
EbmlParser
::
Get
(
void
)
EbmlElement
*
EbmlParser
::
Get
(
int
n_call
)
{
{
int
i_ulev
=
0
;
int
i_ulev
=
0
;
EbmlElement
*
p_prev
=
NULL
;
if
(
mi_user_level
!=
mi_level
)
if
(
mi_user_level
!=
mi_level
)
{
{
...
@@ -155,24 +158,29 @@ EbmlElement *EbmlParser::Get( void )
...
@@ -155,24 +158,29 @@ EbmlElement *EbmlParser::Get( void )
return
ret
;
return
ret
;
}
}
p_prev
=
m_el
[
mi_level
];
if
(
m_el
[
mi_level
]
)
if
(
m_el
[
mi_level
]
)
{
{
m_el
[
mi_level
]
->
SkipData
(
*
m_es
,
EBML_CONTEXT
(
m_el
[
mi_level
])
);
m_el
[
mi_level
]
->
SkipData
(
*
m_es
,
EBML_CONTEXT
(
m_el
[
mi_level
])
);
if
(
!
mb_keep
)
{
if
(
MKV_IS_ID
(
m_el
[
mi_level
],
KaxBlockVirtual
)
)
static_cast
<
KaxBlockVirtualWorkaround
*>
(
m_el
[
mi_level
])
->
Fix
();
delete
m_el
[
mi_level
];
}
mb_keep
=
false
;
}
}
vlc_stream_io_callback
&
io_stream
=
(
vlc_stream_io_callback
&
)
m_es
->
I_O
();
vlc_stream_io_callback
&
io_stream
=
(
vlc_stream_io_callback
&
)
m_es
->
I_O
();
uint64
i_size
=
io_stream
.
toRead
();
uint64
i_size
=
io_stream
.
toRead
();
m_el
[
mi_level
]
=
m_es
->
FindNextElement
(
EBML_CONTEXT
(
m_el
[
mi_level
-
1
]),
m_el
[
mi_level
]
=
m_es
->
FindNextElement
(
EBML_CONTEXT
(
m_el
[
mi_level
-
1
]),
i_ulev
,
i_size
,
mb_dummy
,
1
);
i_ulev
,
i_size
,
true
,
1
);
// mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
// mi_remain_size[mi_level] = m_el[mi_level]->GetSize();
if
(
i_ulev
>
0
)
if
(
i_ulev
>
0
)
{
{
if
(
p_prev
)
{
if
(
!
mb_keep
)
{
if
(
MKV_IS_ID
(
p_prev
,
KaxBlockVirtual
)
)
static_cast
<
KaxBlockVirtualWorkaround
*>
(
p_prev
)
->
Fix
();
delete
p_prev
;
}
mb_keep
=
false
;
}
while
(
i_ulev
>
0
)
while
(
i_ulev
>
0
)
{
{
if
(
mi_level
==
1
)
if
(
mi_level
==
1
)
...
@@ -192,9 +200,55 @@ EbmlElement *EbmlParser::Get( void )
...
@@ -192,9 +200,55 @@ EbmlElement *EbmlParser::Get( void )
}
}
else
if
(
m_el
[
mi_level
]
==
NULL
)
else
if
(
m_el
[
mi_level
]
==
NULL
)
{
{
fprintf
(
stderr
,
"MKV/Ebml Parser: m_el[mi_level] == NULL
\n
"
);
msg_Warn
(
p_demux
,
"MKV/Ebml Parser: m_el[mi_level] == NULL
\n
"
);
}
else
if
(
m_el
[
mi_level
]
->
IsDummy
()
&&
!
mb_dummy
)
{
bool
b_bad_position
=
false
;
/* We got a dummy element but don't want those...
* perform a sanity check */
if
(
!
mi_level
)
{
msg_Err
(
p_demux
,
"Got invalid lvl 0 element... Aborting"
);
return
NULL
;
}
if
(
p_prev
&&
p_prev
->
IsFiniteSize
()
&&
p_prev
->
GetEndPosition
()
!=
m_el
[
mi_level
]
->
GetElementPosition
())
{
msg_Err
(
p_demux
,
"Dummy Element at unexpected position... corrupted file?"
);
b_bad_position
=
true
;
}
if
(
n_call
<
10
&&
!
b_bad_position
&&
m_el
[
mi_level
]
->
IsFiniteSize
()
&&
(
!
m_el
[
mi_level
-
1
]
->
IsFiniteSize
()
||
m_el
[
mi_level
]
->
GetEndPosition
()
<=
m_el
[
mi_level
-
1
]
->
GetEndPosition
()
)
)
{
/* The element fits inside its upper element */
msg_Warn
(
p_demux
,
"Dummy element found... skipping it"
);
return
Get
(
++
n_call
);
}
else
{
/* Too large, misplaced or 10 successive dummy elements */
msg_Err
(
p_demux
,
"Dummy element too large or misplaced... skipping to next upper element"
);
delete
m_el
[
mi_level
];
m_el
[
mi_level
]
=
NULL
;
m_el
[
mi_level
-
1
]
->
SkipData
(
*
m_es
,
EBML_CONTEXT
(
m_el
[
mi_level
-
1
])
);
return
Get
();
}
}
}
if
(
p_prev
)
{
if
(
!
mb_keep
)
{
if
(
MKV_IS_ID
(
p_prev
,
KaxBlockVirtual
)
)
static_cast
<
KaxBlockVirtualWorkaround
*>
(
p_prev
)
->
Fix
();
delete
p_prev
;
}
mb_keep
=
false
;
}
return
m_el
[
mi_level
];
return
m_el
[
mi_level
];
}
}
...
...
modules/demux/mkv/Ebml_parser.hpp
View file @
6f8e8326
...
@@ -39,7 +39,7 @@ class EbmlParser
...
@@ -39,7 +39,7 @@ class EbmlParser
void
Up
(
void
);
void
Up
(
void
);
void
Down
(
void
);
void
Down
(
void
);
void
Reset
(
demux_t
*
p_demux
);
void
Reset
(
demux_t
*
p_demux
);
EbmlElement
*
Get
(
void
);
EbmlElement
*
Get
(
int
n_call
=
0
);
void
Keep
(
void
);
void
Keep
(
void
);
EbmlElement
*
UnGet
(
uint64
i_block_pos
,
uint64
i_cluster_pos
);
EbmlElement
*
UnGet
(
uint64
i_block_pos
,
uint64
i_cluster_pos
);
...
@@ -49,16 +49,17 @@ class EbmlParser
...
@@ -49,16 +49,17 @@ class EbmlParser
bool
IsTopPresent
(
EbmlElement
*
)
const
;
bool
IsTopPresent
(
EbmlElement
*
)
const
;
private:
private:
demux_t
*
p_demux
;
EbmlStream
*
m_es
;
EbmlStream
*
m_es
;
int
mi_level
;
int
mi_level
;
EbmlElement
*
m_el
[
10
];
EbmlElement
*
m_el
[
10
];
int64_t
mi_remain_size
[
10
];
int64_t
mi_remain_size
[
10
];
EbmlElement
*
m_got
;
EbmlElement
*
m_got
;
int
mi_user_level
;
int
mi_user_level
;
bool
mb_keep
;
bool
mb_keep
;
bool
mb_dummy
;
bool
mb_dummy
;
};
};
/* This class works around a bug in KaxBlockVirtual implementation */
/* This class works around a bug in KaxBlockVirtual implementation */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment