Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
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-1.1
Commits
f93e275d
Commit
f93e275d
authored
Jan 21, 2006
by
Sam Hocevar
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* modules/codec/spudec: fixed various (innocuous) buffer overflows and
paved the way for private SPU commands.
parent
6fbe51ed
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
141 additions
and
79 deletions
+141
-79
modules/codec/spudec/parse.c
modules/codec/spudec/parse.c
+98
-42
modules/codec/spudec/spudec.c
modules/codec/spudec/spudec.c
+36
-30
modules/codec/spudec/spudec.h
modules/codec/spudec/spudec.h
+7
-7
No files found.
modules/codec/spudec/parse.c
View file @
f93e275d
/*****************************************************************************
* parse.c: SPU parser
*****************************************************************************
* Copyright (C) 2000-2001, 2005 the VideoLAN team
* Copyright (C) 2000-2001, 2005
, 2006
the VideoLAN team
* $Id$
*
* Authors: Sam
uel
Hocevar <sam@zoy.org>
* Authors: Sam Hocevar <sam@zoy.org>
* Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@videolan.org>
*
...
...
@@ -149,21 +149,18 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu,
p_spu
->
i_start
=
p_spu
->
i_stop
=
0
;
p_spu
->
b_ephemer
=
VLC_FALSE
;
do
for
(
i_index
=
4
+
p_sys
->
i_rle_size
;
i_index
<
p_sys
->
i_spu_size
;
)
{
if
(
(
int
)
i_index
>=
p_sys
->
i_spu_size
+
1
)
{
/* sanity
* XXX only on test by loop as p_sys->buffer is bigger than needed
* to avoid checking at each access
*/
break
;
}
/* If we just read a command sequence, read the next one;
* otherwise, go on with the commands of the current sequence. */
if
(
i_command
==
SPU_CMD_END
)
{
if
(
i_index
+
4
>
p_sys
->
i_spu_size
)
{
msg_Err
(
p_dec
,
"overflow in SPU command sequence"
);
return
VLC_EGENERIC
;
}
/* Get the control sequence date */
date
=
(
mtime_t
)
GetWBE
(
&
p_sys
->
buffer
[
i_index
]
)
*
11000
;
/* FIXME How to access i_rate
...
...
@@ -174,41 +171,56 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu,
i_cur_seq
=
i_index
;
i_next_seq
=
GetWBE
(
&
p_sys
->
buffer
[
i_index
+
2
]
);
if
(
i_next_seq
>
p_sys
->
i_spu_size
)
{
msg_Err
(
p_dec
,
"overflow in SPU next command sequence"
);
return
VLC_EGENERIC
;
}
/* Skip what we just read */
i_index
+=
4
;
}
i_command
=
p_sys
->
buffer
[
i_index
++
];
i_command
=
p_sys
->
buffer
[
i_index
];
switch
(
i_command
)
{
case
SPU_CMD_FORCE_DISPLAY
:
/* 00 (force displaying) */
p_spu
->
i_start
=
p_spu_data
->
i_pts
+
date
;
p_spu
->
b_ephemer
=
VLC_TRUE
;
i_index
+=
1
;
break
;
/* Convert the dates in seconds to PTS values */
case
SPU_CMD_START_DISPLAY
:
/* 01 (start displaying) */
p_spu
->
i_start
=
p_spu_data
->
i_pts
+
date
;
i_index
+=
1
;
break
;
case
SPU_CMD_STOP_DISPLAY
:
/* 02 (stop displaying) */
p_spu
->
i_stop
=
p_spu_data
->
i_pts
+
date
;
i_index
+=
1
;
break
;
case
SPU_CMD_SET_PALETTE
:
/* 03xxxx (palette) */
if
(
i_index
+
3
>
p_sys
->
i_spu_size
)
{
msg_Err
(
p_dec
,
"overflow in SPU command"
);
return
VLC_EGENERIC
;
}
if
(
p_dec
->
fmt_in
.
subs
.
spu
.
palette
[
0
]
==
0xBeeF
)
{
unsigned
int
idx
[
4
];
p_spu_data
->
b_palette
=
VLC_TRUE
;
idx
[
0
]
=
(
p_sys
->
buffer
[
i_index
+
0
]
>>
4
)
&
0x0f
;
idx
[
1
]
=
(
p_sys
->
buffer
[
i_index
+
0
])
&
0x0f
;
idx
[
2
]
=
(
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
;
idx
[
3
]
=
(
p_sys
->
buffer
[
i_index
+
1
])
&
0x0f
;
idx
[
0
]
=
(
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
;
idx
[
1
]
=
(
p_sys
->
buffer
[
i_index
+
1
])
&
0x0f
;
idx
[
2
]
=
(
p_sys
->
buffer
[
i_index
+
2
]
>>
4
)
&
0x0f
;
idx
[
3
]
=
(
p_sys
->
buffer
[
i_index
+
2
])
&
0x0f
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
...
...
@@ -220,15 +232,21 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu,
p_spu_data
->
pi_yuv
[
3
-
i
][
2
]
=
(
i_color
>>
8
)
&
0xff
;
}
}
i_index
+=
2
;
i_index
+=
3
;
break
;
case
SPU_CMD_SET_ALPHACHANNEL
:
/* 04xxxx (alpha channel) */
pi_alpha
[
3
]
=
(
p_sys
->
buffer
[
i_index
+
0
]
>>
4
)
&
0x0f
;
pi_alpha
[
2
]
=
(
p_sys
->
buffer
[
i_index
+
0
])
&
0x0f
;
pi_alpha
[
1
]
=
(
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
;
pi_alpha
[
0
]
=
(
p_sys
->
buffer
[
i_index
+
1
])
&
0x0f
;
if
(
i_index
+
3
>
p_sys
->
i_spu_size
)
{
msg_Err
(
p_dec
,
"overflow in SPU command"
);
return
VLC_EGENERIC
;
}
pi_alpha
[
3
]
=
(
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
;
pi_alpha
[
2
]
=
(
p_sys
->
buffer
[
i_index
+
1
])
&
0x0f
;
pi_alpha
[
1
]
=
(
p_sys
->
buffer
[
i_index
+
2
]
>>
4
)
&
0x0f
;
pi_alpha
[
0
]
=
(
p_sys
->
buffer
[
i_index
+
2
])
&
0x0f
;
/* Ignore blank alpha palette. Sometimes spurious blank
* alpha palettes are present - dunno why. */
...
...
@@ -244,39 +262,73 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu,
msg_Warn
(
p_dec
,
"ignoring blank alpha palette"
);
}
i_index
+=
2
;
i_index
+=
3
;
break
;
case
SPU_CMD_SET_COORDINATES
:
/* 05xxxyyyxxxyyy (coordinates) */
p_spu
->
i_x
=
(
p_sys
->
buffer
[
i_index
+
0
]
<<
4
)
|
((
p_sys
->
buffer
[
i_index
+
1
]
>>
4
)
&
0x0f
);
p_spu
->
i_width
=
(((
p_sys
->
buffer
[
i_index
+
1
]
&
0x0f
)
<<
8
)
|
p_sys
->
buffer
[
i_index
+
2
])
-
p_spu
->
i_x
+
1
;
if
(
i_index
+
7
>
p_sys
->
i_spu_size
)
{
msg_Err
(
p_dec
,
"overflow in SPU command"
);
return
VLC_EGENERIC
;
}
p_spu
->
i_y
=
(
p_sys
->
buffer
[
i_index
+
3
]
<<
4
)
|
((
p_sys
->
buffer
[
i_index
+
4
]
>>
4
)
&
0x0f
);
p_spu
->
i_height
=
(((
p_sys
->
buffer
[
i_index
+
4
]
&
0x0f
)
<<
8
)
|
p_sys
->
buffer
[
i_index
+
5
])
-
p_spu
->
i_y
+
1
;
p_spu
->
i_x
=
(
p_sys
->
buffer
[
i_index
+
1
]
<<
4
)
|
((
p_sys
->
buffer
[
i_index
+
2
]
>>
4
)
&
0x0f
);
p_spu
->
i_width
=
(((
p_sys
->
buffer
[
i_index
+
2
]
&
0x0f
)
<<
8
)
|
p_sys
->
buffer
[
i_index
+
3
])
-
p_spu
->
i_x
+
1
;
p_spu
->
i_y
=
(
p_sys
->
buffer
[
i_index
+
4
]
<<
4
)
|
((
p_sys
->
buffer
[
i_index
+
5
]
>>
4
)
&
0x0f
);
p_spu
->
i_height
=
(((
p_sys
->
buffer
[
i_index
+
5
]
&
0x0f
)
<<
8
)
|
p_sys
->
buffer
[
i_index
+
6
])
-
p_spu
->
i_y
+
1
;
/* Auto crop fullscreen subtitles */
if
(
p_spu
->
i_height
>
250
)
p_spu_data
->
b_auto_crop
=
VLC_TRUE
;
i_index
+=
6
;
i_index
+=
7
;
break
;
case
SPU_CMD_SET_OFFSETS
:
/* 06xxxxyyyy (byte offsets) */
p_spu_data
->
pi_offset
[
0
]
=
GetWBE
(
&
p_sys
->
buffer
[
i_index
+
0
])
-
4
;
p_spu_data
->
pi_offset
[
1
]
=
GetWBE
(
&
p_sys
->
buffer
[
i_index
+
2
])
-
4
;
i_index
+=
4
;
if
(
i_index
+
5
>
p_sys
->
i_spu_size
)
{
msg_Err
(
p_dec
,
"overflow in SPU command"
);
return
VLC_EGENERIC
;
}
p_spu_data
->
pi_offset
[
0
]
=
GetWBE
(
&
p_sys
->
buffer
[
i_index
+
1
])
-
4
;
p_spu_data
->
pi_offset
[
1
]
=
GetWBE
(
&
p_sys
->
buffer
[
i_index
+
3
])
-
4
;
i_index
+=
5
;
break
;
case
SPU_CMD_END
:
/* ff (end) */
i_index
+=
1
;
break
;
default:
/* xx (unknown command) */
msg_Warn
(
p_dec
,
"unknown command 0x%.2x"
,
i_command
);
return
VLC_EGENERIC
;
msg_Warn
(
p_dec
,
"unknown SPU command 0x%.2x"
,
i_command
);
if
(
i_index
+
1
<
i_next_seq
)
{
/* There is at least one other command sequence */
if
(
p_sys
->
buffer
[
i_next_seq
-
1
]
==
SPU_CMD_END
)
{
/* This is consistent. Skip to that command sequence. */
i_index
=
i_next_seq
;
}
else
{
/* There were other commands. */
msg_Warn
(
p_dec
,
"cannot recover, dropping subtitle"
);
return
VLC_EGENERIC
;
}
}
else
{
/* We were in the last command sequence. Stop parsing by
* pretending we met an SPU_CMD_END command. */
i_command
=
SPU_CMD_END
;
i_index
++
;
}
}
/* We need to check for quit commands here */
...
...
@@ -285,7 +337,11 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu,
return
VLC_EGENERIC
;
}
}
while
(
i_command
!=
SPU_CMD_END
||
i_index
==
i_next_seq
);
if
(
i_command
==
SPU_CMD_END
&&
i_index
!=
i_next_seq
)
{
break
;
}
}
/* Check that the next sequence index matches the current one */
if
(
i_next_seq
!=
i_cur_seq
)
...
...
@@ -295,7 +351,7 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu,
return
VLC_EGENERIC
;
}
if
(
(
int
)
i_index
>
p_sys
->
i_spu_size
)
if
(
i_index
>
p_sys
->
i_spu_size
)
{
msg_Err
(
p_dec
,
"uh-oh, we went too far (0x%.4x > 0x%.4x)"
,
i_index
,
p_sys
->
i_spu_size
);
...
...
@@ -315,11 +371,11 @@ static int ParseControlSeq( decoder_t *p_dec, subpicture_t *p_spu,
}
/* Get rid of padding bytes */
if
(
p_sys
->
i_spu_size
>
(
int
)
i_index
+
1
)
if
(
p_sys
->
i_spu_size
>
i_index
+
1
)
{
/* Zero or one padding byte
,
are quite usual
/* Zero or one padding byte are quite usual
* More than one padding byte - this is very strange, but
* we can
deal with it
*/
* we can
ignore them.
*/
msg_Warn
(
p_dec
,
"%i padding bytes, we usually get 0 or 1 of them"
,
p_sys
->
i_spu_size
-
i_index
);
}
...
...
modules/codec/spudec/spudec.c
View file @
f93e275d
/*****************************************************************************
* spudec.c : SPU decoder thread
*****************************************************************************
* Copyright (C) 2000-2001 the VideoLAN team
* Copyright (C) 2000-2001
, 2006
the VideoLAN team
* $Id$
*
* Authors: Sam
uel
Hocevar <sam@zoy.org>
* Authors: Sam Hocevar <sam@zoy.org>
* Laurent Aimar <fenrir@via.ecp.fr>
*
* This program is free software; you can redistribute it and/or modify
...
...
@@ -119,7 +119,11 @@ static void Close( vlc_object_t *p_this )
decoder_t
*
p_dec
=
(
decoder_t
*
)
p_this
;
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
if
(
p_sys
->
p_block
)
block_ChainRelease
(
p_sys
->
p_block
);
if
(
p_sys
->
p_block
)
{
block_ChainRelease
(
p_sys
->
p_block
);
}
free
(
p_sys
);
}
...
...
@@ -130,28 +134,30 @@ static subpicture_t *Decode( decoder_t *p_dec, block_t **pp_block )
{
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_spu_block
;
subpicture_t
*
p_spu
;
if
(
(
p_spu_block
=
Reassemble
(
p_dec
,
pp_block
))
)
{
subpicture_t
*
p_spu
;
p_spu_block
=
Reassemble
(
p_dec
,
pp_block
);
p_sys
->
i_spu
=
block_ChainExtract
(
p_spu_block
,
p_sys
->
buffer
,
65536
);
p_sys
->
i_pts
=
p_spu_block
->
i_pts
;
block_ChainRelease
(
p_spu_block
);
if
(
!
p_spu_block
)
{
return
NULL
;
}
/* Parse and decode */
p_spu
=
E_
(
ParsePacket
)(
p_dec
);
/* FIXME: what the, we shouldn’t need to allocate 64k of buffer --sam. */
p_sys
->
i_spu
=
block_ChainExtract
(
p_spu_block
,
p_sys
->
buffer
,
65536
);
p_sys
->
i_pts
=
p_spu_block
->
i_pts
;
block_ChainRelease
(
p_spu_block
);
/* reinit context */
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_rle_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
/* Parse and decode */
p_spu
=
E_
(
ParsePacket
)(
p_dec
);
return
p_spu
;
}
/* reinit context */
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_rle_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
return
NULL
;
return
p_spu
;
}
/*****************************************************************************
...
...
@@ -162,21 +168,21 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
decoder_sys_t
*
p_sys
=
p_dec
->
p_sys
;
block_t
*
p_spu
=
Reassemble
(
p_dec
,
pp_block
);
if
(
p_spu
)
if
(
!
p_spu
)
{
p_spu
->
i_dts
=
p_spu
->
i_pts
;
p_spu
->
i_length
=
0
;
return
NULL
;
}
/* reinit context */
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_rle_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
p_spu
->
i_dts
=
p_spu
->
i_pts
;
p_spu
->
i_length
=
0
;
return
block_ChainGather
(
p_spu
);
}
/* reinit context */
p_sys
->
i_spu_size
=
0
;
p_sys
->
i_rle_size
=
0
;
p_sys
->
i_spu
=
0
;
p_sys
->
p_block
=
NULL
;
return
NULL
;
return
block_ChainGather
(
p_spu
)
;
}
/*****************************************************************************
...
...
modules/codec/spudec/spudec.h
View file @
f93e275d
/*****************************************************************************
* spudec.h : sub picture unit decoder thread interface
*****************************************************************************
* Copyright (C) 1999, 2000 the VideoLAN team
* Copyright (C) 1999, 2000
, 2006
the VideoLAN team
* $Id$
*
* Authors: Sam
uel
Hocevar <sam@zoy.org>
* Authors: Sam Hocevar <sam@zoy.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
...
...
@@ -26,14 +26,14 @@ struct decoder_sys_t
int
b_packetizer
;
mtime_t
i_pts
;
int
i_spu_size
;
int
i_rle_size
;
int
i_spu
;
unsigned
int
i_spu_size
;
unsigned
int
i_rle_size
;
unsigned
int
i_spu
;
block_t
*
p_block
;
/* We will never overflow
more than 11 bytes if I'm right
*/
uint8_t
buffer
[
65536
+
20
];
/* We will never overflow */
uint8_t
buffer
[
65536
];
};
typedef
struct
subpicture_data_t
...
...
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