Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
607ad990
Commit
607ad990
authored
Dec 17, 2014
by
Vittorio Giovara
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
dvbsubdec: check memory allocations and propagate errors
parent
e71149a7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
58 additions
and
30 deletions
+58
-30
dvbsubdec.c
libavcodec/dvbsubdec.c
+58
-30
No files found.
libavcodec/dvbsubdec.c
View file @
607ad990
...
...
@@ -832,8 +832,8 @@ static void dvbsub_parse_pixel_data_block(AVCodecContext *avctx, DVBSubObjectDis
}
static
void
dvbsub_parse_object_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
static
int
dvbsub_parse_object_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
{
DVBSubContext
*
ctx
=
avctx
->
priv_data
;
...
...
@@ -852,7 +852,7 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx,
object
=
get_object
(
ctx
,
object_id
);
if
(
!
object
)
return
;
return
AVERROR_INVALIDDATA
;
coding_method
=
((
*
buf
)
>>
2
)
&
3
;
non_modifying_color
=
((
*
buf
++
)
>>
1
)
&
1
;
...
...
@@ -865,7 +865,7 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx,
if
(
buf
+
top_field_len
+
bottom_field_len
>
buf_end
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Field data size too large
\n
"
);
return
;
return
AVERROR_INVALIDDATA
;
}
for
(
display
=
object
->
display_list
;
display
;
display
=
display
->
object_list_next
)
{
...
...
@@ -889,10 +889,11 @@ static void dvbsub_parse_object_segment(AVCodecContext *avctx,
av_log
(
avctx
,
AV_LOG_ERROR
,
"Unknown object coding %d
\n
"
,
coding_method
);
}
return
0
;
}
static
void
dvbsub_parse_clut_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
static
int
dvbsub_parse_clut_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
{
DVBSubContext
*
ctx
=
avctx
->
priv_data
;
...
...
@@ -921,6 +922,8 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
if
(
!
clut
)
{
clut
=
av_malloc
(
sizeof
(
DVBSubCLUT
));
if
(
!
clut
)
return
AVERROR
(
ENOMEM
);
memcpy
(
clut
,
&
default_clut
,
sizeof
(
DVBSubCLUT
));
...
...
@@ -937,7 +940,7 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
if
(
depth
==
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Invalid clut depth 0x%x!
\n
"
,
*
buf
);
return
;
return
AVERROR_INVALIDDATA
;
}
full_range
=
(
*
buf
++
)
&
1
;
...
...
@@ -971,11 +974,13 @@ static void dvbsub_parse_clut_segment(AVCodecContext *avctx,
if
(
depth
&
0x20
)
clut
->
clut256
[
entry_id
]
=
RGBA
(
r
,
g
,
b
,
255
-
alpha
);
}
return
0
;
}
static
void
dvbsub_parse_region_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
static
int
dvbsub_parse_region_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
{
DVBSubContext
*
ctx
=
avctx
->
priv_data
;
...
...
@@ -987,7 +992,7 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx,
int
fill
;
if
(
buf_size
<
10
)
return
;
return
AVERROR_INVALIDDATA
;
region_id
=
*
buf
++
;
...
...
@@ -995,6 +1000,8 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx,
if
(
!
region
)
{
region
=
av_mallocz
(
sizeof
(
DVBSubRegion
));
if
(
!
region
)
return
AVERROR
(
ENOMEM
);
region
->
id
=
region_id
;
...
...
@@ -1015,6 +1022,8 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx,
region
->
buf_size
=
region
->
width
*
region
->
height
;
region
->
pbuf
=
av_malloc
(
region
->
buf_size
);
if
(
!
region
->
pbuf
)
return
AVERROR
(
ENOMEM
);
fill
=
1
;
}
...
...
@@ -1054,6 +1063,8 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx,
if
(
!
object
)
{
object
=
av_mallocz
(
sizeof
(
DVBSubObject
));
if
(
!
object
)
return
AVERROR
(
ENOMEM
);
object
->
id
=
object_id
;
object
->
next
=
ctx
->
object_list
;
...
...
@@ -1063,6 +1074,8 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx,
object
->
type
=
(
*
buf
)
>>
6
;
display
=
av_mallocz
(
sizeof
(
DVBSubObjectDisplay
));
if
(
!
display
)
return
AVERROR
(
ENOMEM
);
display
->
object_id
=
object_id
;
display
->
region_id
=
region_id
;
...
...
@@ -1083,10 +1096,12 @@ static void dvbsub_parse_region_segment(AVCodecContext *avctx,
display
->
object_list_next
=
object
->
display_list
;
object
->
display_list
=
display
;
}
return
0
;
}
static
void
dvbsub_parse_page_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
static
int
dvbsub_parse_page_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
{
DVBSubContext
*
ctx
=
avctx
->
priv_data
;
DVBSubRegionDisplay
*
display
;
...
...
@@ -1097,7 +1112,7 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx,
int
page_state
;
if
(
buf_size
<
1
)
return
;
return
AVERROR_INVALIDDATA
;
ctx
->
time_out
=
*
buf
++
;
page_state
=
((
*
buf
++
)
>>
2
)
&
3
;
...
...
@@ -1124,8 +1139,11 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx,
display
=
display
->
next
;
}
if
(
!
display
)
if
(
!
display
)
{
display
=
av_mallocz
(
sizeof
(
DVBSubRegionDisplay
));
if
(
!
display
)
return
AVERROR
(
ENOMEM
);
}
display
->
region_id
=
region_id
;
...
...
@@ -1151,6 +1169,7 @@ static void dvbsub_parse_page_segment(AVCodecContext *avctx,
av_free
(
display
);
}
return
0
;
}
...
...
@@ -1204,6 +1223,8 @@ static void save_display_set(DVBSubContext *ctx)
if
(
x_pos
>=
0
)
{
pbuf
=
av_malloc
(
width
*
height
*
4
);
if
(
!
pbuf
)
return
AVERROR
(
ENOMEM
);
for
(
display
=
ctx
->
display_list
;
display
;
display
=
display
->
next
)
{
region
=
get_region
(
ctx
,
display
->
region_id
);
...
...
@@ -1249,28 +1270,28 @@ static void save_display_set(DVBSubContext *ctx)
}
#endif
static
void
dvbsub_parse_display_definition_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
static
int
dvbsub_parse_display_definition_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
)
{
DVBSubContext
*
ctx
=
avctx
->
priv_data
;
DVBSubDisplayDefinition
*
display_def
=
ctx
->
display_definition
;
int
dds_version
,
info_byte
;
if
(
buf_size
<
5
)
return
;
return
AVERROR_INVALIDDATA
;
info_byte
=
bytestream_get_byte
(
&
buf
);
dds_version
=
info_byte
>>
4
;
if
(
display_def
&&
display_def
->
version
==
dds_version
)
return
;
// already have this display definition version
return
0
;
// already have this display definition version
if
(
!
display_def
)
{
display_def
=
av_mallocz
(
sizeof
(
*
display_def
));
if
(
!
display_def
)
return
AVERROR
(
ENOMEM
);
ctx
->
display_definition
=
display_def
;
}
if
(
!
display_def
)
return
;
display_def
->
version
=
dds_version
;
display_def
->
x
=
0
;
...
...
@@ -1279,7 +1300,7 @@ static void dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
display_def
->
height
=
bytestream_get_be16
(
&
buf
)
+
1
;
if
(
buf_size
<
13
)
return
;
return
AVERROR_INVALIDDATA
;
if
(
info_byte
&
1
<<
3
)
{
// display_window_flag
display_def
->
x
=
bytestream_get_be16
(
&
buf
);
...
...
@@ -1287,10 +1308,12 @@ static void dvbsub_parse_display_definition_segment(AVCodecContext *avctx,
display_def
->
width
=
bytestream_get_be16
(
&
buf
)
-
display_def
->
x
+
1
;
display_def
->
height
=
bytestream_get_be16
(
&
buf
)
-
display_def
->
y
+
1
;
}
return
0
;
}
static
int
dvbsub_display_end_segment
(
AVCodecContext
*
avctx
,
const
uint8_t
*
buf
,
int
buf_size
,
AVSubtitle
*
sub
)
int
buf_size
,
AVSubtitle
*
sub
)
{
DVBSubContext
*
ctx
=
avctx
->
priv_data
;
DVBSubDisplayDefinition
*
display_def
=
ctx
->
display_definition
;
...
...
@@ -1411,7 +1434,7 @@ static int dvbsub_decode(AVCodecContext *avctx,
if
(
buf_size
<=
6
||
*
buf
!=
0x0f
)
{
av_dlog
(
avctx
,
"incomplete or broken packet"
);
return
-
1
;
return
AVERROR_INVALIDDATA
;
}
p
=
buf
;
...
...
@@ -1432,30 +1455,35 @@ static int dvbsub_decode(AVCodecContext *avctx,
if
(
page_id
==
ctx
->
composition_id
||
page_id
==
ctx
->
ancillary_id
||
ctx
->
composition_id
==
-
1
||
ctx
->
ancillary_id
==
-
1
)
{
int
ret
=
0
;
switch
(
segment_type
)
{
case
DVBSUB_PAGE_SEGMENT
:
dvbsub_parse_page_segment
(
avctx
,
p
,
segment_length
);
ret
=
dvbsub_parse_page_segment
(
avctx
,
p
,
segment_length
);
break
;
case
DVBSUB_REGION_SEGMENT
:
dvbsub_parse_region_segment
(
avctx
,
p
,
segment_length
);
ret
=
dvbsub_parse_region_segment
(
avctx
,
p
,
segment_length
);
break
;
case
DVBSUB_CLUT_SEGMENT
:
dvbsub_parse_clut_segment
(
avctx
,
p
,
segment_length
);
ret
=
dvbsub_parse_clut_segment
(
avctx
,
p
,
segment_length
);
break
;
case
DVBSUB_OBJECT_SEGMENT
:
dvbsub_parse_object_segment
(
avctx
,
p
,
segment_length
);
ret
=
dvbsub_parse_object_segment
(
avctx
,
p
,
segment_length
);
break
;
case
DVBSUB_DISPLAYDEFINITION_SEGMENT
:
dvbsub_parse_display_definition_segment
(
avctx
,
p
,
segment_length
);
ret
=
dvbsub_parse_display_definition_segment
(
avctx
,
p
,
segment_length
);
break
;
case
DVBSUB_DISPLAY_SEGMENT
:
*
data_size
=
dvbsub_display_end_segment
(
avctx
,
p
,
segment_length
,
sub
);
ret
=
dvbsub_display_end_segment
(
avctx
,
p
,
segment_length
,
sub
);
*
data_size
=
ret
;
break
;
default:
av_dlog
(
avctx
,
"Subtitling segment type 0x%x, page id %d, length %d
\n
"
,
segment_type
,
page_id
,
segment_length
);
break
;
}
if
(
ret
<
0
)
return
ret
;
}
p
+=
segment_length
;
...
...
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