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
1d410d6d
Commit
1d410d6d
authored
Nov 14, 2014
by
Rémi Denis-Courmont
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
str_format_meta: rewrite and fix leaks due to expansion-unsafe macros
parent
8a3c4f91
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
265 additions
and
274 deletions
+265
-274
configure.ac
configure.ac
+1
-1
src/text/strings.c
src/text/strings.c
+264
-273
No files found.
configure.ac
View file @
1d410d6d
...
...
@@ -548,7 +548,7 @@ need_libc=false
dnl Check for usual libc functions
AC_CHECK_DECLS([nanosleep],,,[#include <time.h>])
AC_CHECK_FUNCS([daemon fcntl fstatvfs fork getenv getpwuid_r isatty lstat memalign mmap openat pread posix_fadvise posix_madvise setlocale stricmp strnicmp strptime uselocale pthread_cond_timedwait_monotonic_np pthread_condattr_setclock])
AC_CHECK_FUNCS([daemon fcntl fstatvfs fork getenv getpwuid_r isatty lstat memalign mmap open
_memstream open
at pread posix_fadvise posix_madvise setlocale stricmp strnicmp strptime uselocale pthread_cond_timedwait_monotonic_np pthread_condattr_setclock])
AC_REPLACE_FUNCS([atof atoll dirfd fdopendir flockfile fsync getdelim getpid gmtime_r lldiv localtime_r nrand48 poll posix_memalign rewind setenv strcasecmp strcasestr strdup strlcpy strndup strnlen strsep strtof strtok_r strtoll swab tdestroy strverscmp])
AC_CHECK_FUNCS(fdatasync,,
[AC_DEFINE(fdatasync, fsync, [Alias fdatasync() to fsync() if missing.])
...
...
src/text/strings.c
View file @
1d410d6d
...
...
@@ -502,314 +502,305 @@ char *str_format_time( const char *tformat )
assert
(
0
);
}
static
void
format_duration
(
char
*
buf
,
size_t
len
,
int64_t
duration
)
static
void
write_duration
(
FILE
*
stream
,
int64_t
duration
)
{
lldiv_t
d
;
int
sec
;
long
long
sec
;
duration
/=
CLOCK_FREQ
;
d
=
lldiv
(
duration
,
60
);
d
=
lldiv
(
duration
,
60
);
sec
=
d
.
rem
;
d
=
lldiv
(
d
.
quot
,
60
);
snprintf
(
buf
,
len
,
"%02lld:%02d:%02d"
,
d
.
quot
,
(
int
)
d
.
rem
,
sec
);
d
=
lldiv
(
d
.
quot
,
60
);
fprintf
(
stream
,
"%02lld:%02lld:%02lld"
,
d
.
quot
,
d
.
rem
,
sec
);
}
#define INSERT_STRING( string ) \
if( string != NULL ) \
{ \
size_t len = strlen( string ); \
dst = xrealloc( dst, i_size = i_size + len );\
memcpy( (dst+d), string, len ); \
d += len; \
free( string ); \
}
/* same than INSERT_STRING, except that string won't be freed */
#define INSERT_STRING_NO_FREE( string ) \
{ \
size_t len = strlen( string ); \
dst = xrealloc( dst, i_size = i_size + len );\
memcpy( dst+d, string, len ); \
d += len; \
}
char
*
str_format_meta
(
input_thread_t
*
p_input
,
const
char
*
s
)
static
int
write_meta
(
FILE
*
stream
,
input_item_t
*
item
,
vlc_meta_type_t
type
)
{
char
*
dst
=
strdup
(
s
);
if
(
unlikely
(
dst
==
NULL
)
)
if
(
item
==
NULL
)
return
EOF
;
char
*
value
=
input_item_GetMeta
(
item
,
type
);
if
(
value
==
NULL
)
return
EOF
;
int
ret
=
fputs
(
value
,
stream
);
free
(
value
);
return
ret
;
}
char
*
str_format_meta
(
input_thread_t
*
input
,
const
char
*
s
)
{
char
*
str
;
size_t
len
;
#ifdef HAVE_OPEN_MEMSTREAM
FILE
*
stream
=
open_memstream
(
&
str
,
&
len
);
#else
FILE
*
stream
=
tmpfile
();
#endif
if
(
stream
==
NULL
)
return
NULL
;
input_item_t
*
p_item
=
p_input
?
input_GetItem
(
p_input
)
:
NULL
;
size_t
i_size
=
strlen
(
s
)
+
1
;
/* +1 to store '\0' */
size_t
d
=
0
;
input_item_t
*
item
=
(
input
!=
NULL
)
?
input_GetItem
(
input
)
:
NULL
;
char
c
;
bool
b_is_format
=
false
;
bool
b_empty_if_na
=
false
;
char
buf
[
10
];
while
(
*
s
)
while
((
c
=
*
s
)
!=
'\0'
)
{
s
++
;
if
(
!
b_is_format
)
{
if
(
b_is_format
)
if
(
c
==
'$'
)
{
switch
(
*
s
)
b_is_format
=
true
;
b_empty_if_na
=
false
;
continue
;
}
fputc
(
c
,
stream
);
continue
;
}
b_is_format
=
false
;
switch
(
c
)
{
case
'a'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetArtist
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Artist
);
break
;
case
'b'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetAlbum
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Album
);
break
;
case
'c'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetCopyright
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Copyright
);
break
;
case
'd'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetDescription
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Description
);
break
;
case
'e'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetEncodedBy
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_EncodedBy
);
break
;
case
'f'
:
if
(
p_item
&&
p_item
->
p_stats
)
if
(
item
!=
NULL
&&
item
->
p_stats
!=
NULL
)
{
vlc_mutex_lock
(
&
p_item
->
p_stats
->
lock
);
snprintf
(
buf
,
10
,
"%"
PRIi64
,
p_item
->
p_stats
->
i_displayed_pictures
);
vlc_mutex_unlock
(
&
p_item
->
p_stats
->
lock
);
vlc_mutex_lock
(
&
item
->
p_stats
->
lock
);
fprintf
(
stream
,
"%"
PRIi64
,
item
->
p_stats
->
i_displayed_pictures
);
vlc_mutex_unlock
(
&
item
->
p_stats
->
lock
);
}
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING_NO_FREE
(
buf
);
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
case
'g'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetGenre
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Genre
);
break
;
case
'l'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetLanguage
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Language
);
break
;
case
'n'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetTrackNum
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_TrackNumber
);
break
;
case
'p'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetNowPlaying
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_NowPlaying
);
break
;
case
'r'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetRating
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Rating
);
break
;
case
's'
:
{
char
*
psz_lang
=
NULL
;
if
(
p_input
)
psz_lang
=
var_GetNonEmptyString
(
p_input
,
"sub-language"
);
if
(
psz_lang
==
NULL
)
psz_lang
=
strdup
(
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING
(
psz_lang
);
char
*
lang
=
NULL
;
if
(
input
!=
NULL
)
lang
=
var_GetNonEmptyString
(
input
,
"sub-language"
);
if
(
lang
!=
NULL
)
{
fputs
(
lang
,
stream
);
free
(
lang
);
}
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
}
case
't'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetTitle
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Title
);
break
;
case
'u'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetURL
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_URL
);
break
;
case
'A'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetDate
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Date
);
break
;
case
'B'
:
if
(
p_input
)
snprintf
(
buf
,
10
,
"%"
PRId64
,
var_GetInteger
(
p_input
,
"bit-rate"
)
/
1000
);
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING_NO_FREE
(
buf
);
if
(
input
!=
NULL
)
fprintf
(
stream
,
"%"
PRId64
,
var_GetInteger
(
input
,
"bit-rate"
)
/
1000
);
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
case
'C'
:
if
(
p_input
)
snprintf
(
buf
,
10
,
"%"
PRId64
,
var_GetInteger
(
p_input
,
"chapter"
)
);
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING_NO_FREE
(
buf
);
if
(
input
!=
NULL
)
fprintf
(
stream
,
"%"
PRId64
,
var_GetInteger
(
input
,
"chapter"
));
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
case
'D'
:
if
(
p_item
)
{
mtime_t
i_duration
=
input_item_GetDuration
(
p_item
);
format_duration
(
buf
,
sizeof
(
buf
),
i_duration
);
}
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"--:--:--"
);
INSERT_STRING_NO_FREE
(
buf
);
if
(
item
!=
NULL
)
write_duration
(
stream
,
input_item_GetDuration
(
item
));
else
if
(
!
b_empty_if_na
)
fputs
(
"--:--:--"
,
stream
);
break
;
case
'F'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetURI
(
p_item
)
);
if
(
item
!=
NULL
)
{
char
*
uri
=
input_item_GetURI
(
item
);
if
(
uri
!=
NULL
)
{
fputs
(
uri
,
stream
);
free
(
uri
);
}
}
break
;
case
'I'
:
if
(
p_input
)
snprintf
(
buf
,
10
,
"%"
PRId64
,
var_GetInteger
(
p_input
,
"title"
)
);
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING_NO_FREE
(
buf
);
if
(
input
!=
NULL
)
fprintf
(
stream
,
"%"
PRId64
,
var_GetInteger
(
input
,
"title"
));
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
case
'L'
:
if
(
p_item
&&
p_input
)
if
(
item
!=
NULL
)
{
mtime_t
i_duration
=
input_item_GetDuration
(
p_item
);
int64_t
i_time
=
var_GetTime
(
p_input
,
"time"
);
format_duration
(
buf
,
sizeof
(
buf
),
i_duration
-
i_time
);
assert
(
input
!=
NULL
);
write_duration
(
stream
,
input_item_GetDuration
(
item
)
-
var_GetTime
(
input
,
"time"
));
}
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"--:--:--"
);
INSERT_STRING_NO_FREE
(
buf
);
else
if
(
!
b_empty_if_na
)
fputs
(
"--:--:--"
,
stream
);
break
;
case
'N'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetName
(
p_item
)
);
if
(
item
!=
NULL
)
{
char
*
name
=
input_item_GetName
(
item
);
if
(
name
!=
NULL
)
{
fputs
(
name
,
stream
);
free
(
name
);
}
}
break
;
case
'O'
:
{
char
*
lang
=
NULL
;
if
(
p_input
)
lang
=
var_GetNonEmptyString
(
p_input
,
"audio-language"
);
if
(
lang
==
NULL
)
lang
=
strdup
(
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING
(
lang
);
if
(
input
!=
NULL
)
lang
=
var_GetNonEmptyString
(
input
,
"audio-language"
);
if
(
lang
!=
NULL
)
{
fputs
(
lang
,
stream
);
free
(
lang
);
}
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
}
case
'P'
:
if
(
p_input
)
snprintf
(
buf
,
10
,
"%2.1lf"
,
var_GetFloat
(
p_input
,
"position"
)
*
100
.
);
else
snprintf
(
buf
,
10
,
b_empty_if_na
?
""
:
"--.-%%"
);
INSERT_STRING_NO_FREE
(
buf
);
if
(
input
!=
NULL
)
fprintf
(
stream
,
"%2.1f"
,
var_GetFloat
(
input
,
"position"
)
*
100
.
f
);
else
if
(
!
b_empty_if_na
)
fputs
(
"--.-%"
,
stream
);
break
;
case
'R'
:
if
(
p_input
)
{
float
f
=
var_GetFloat
(
p_input
,
"rate"
);
snprintf
(
buf
,
10
,
"%.3f"
,
f
);
}
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING_NO_FREE
(
buf
);
if
(
input
!=
NULL
)
fprintf
(
stream
,
"%.3f"
,
var_GetFloat
(
input
,
"rate"
));
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
case
'S'
:
if
(
p_input
)
if
(
input
!=
NULL
)
{
int
r
=
var_GetInteger
(
p_input
,
"sample-rate"
);
snprintf
(
buf
,
10
,
"%d.%d"
,
r
/
1000
,
(
r
/
100
)
%
10
);
int
rate
=
var_GetInteger
(
input
,
"sample-rate"
);
div_t
dr
=
div
((
rate
+
50
)
/
100
,
10
);
fprintf
(
stream
,
"%d.%01d"
,
dr
.
quot
,
dr
.
rem
);
}
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"-"
);
INSERT_STRING_NO_FREE
(
buf
);
else
if
(
!
b_empty_if_na
)
fputc
(
'-'
,
stream
);
break
;
case
'T'
:
if
(
p_input
)
{
int64_t
i_time
=
var_GetTime
(
p_input
,
"time"
);
format_duration
(
buf
,
sizeof
(
buf
),
i_time
);
}
else
strcpy
(
buf
,
b_empty_if_na
?
""
:
"--:--:--"
);
INSERT_STRING_NO_FREE
(
buf
);
if
(
input
!=
NULL
)
write_duration
(
stream
,
var_GetTime
(
input
,
"time"
));
else
if
(
!
b_empty_if_na
)
fputs
(
"--:--:--"
,
stream
);
break
;
case
'U'
:
if
(
p_item
)
INSERT_STRING
(
input_item_GetPublisher
(
p_item
)
);
write_meta
(
stream
,
item
,
vlc_meta_Publisher
);
break
;
case
'V'
:
{
float
vol
=
0
.
f
;
if
(
p_input
)
if
(
input
!=
NULL
)
{
audio_output_t
*
aout
=
input_GetAout
(
p_input
);
if
(
aout
)
audio_output_t
*
aout
=
input_GetAout
(
input
);
if
(
aout
!=
NULL
)
{
vol
=
aout_VolumeGet
(
aout
);
vlc_object_release
(
aout
);
vol
=
aout_VolumeGet
(
aout
);
vlc_object_release
(
aout
);
}
}
if
(
vol
>=
0
.
f
)
{
snprintf
(
buf
,
10
,
"%ld"
,
lroundf
(
vol
*
256
.
f
)
);
INSERT_STRING_NO_FREE
(
buf
);
}
else
INSERT_STRING_NO_FREE
(
"---"
);
if
(
vol
>=
0
.
f
)
fprintf
(
stream
,
"%ld"
,
lroundf
(
vol
*
256
.
f
));
else
if
(
!
b_empty_if_na
)
fputs
(
"---"
,
stream
);
break
;
}
case
'_'
:
*
(
dst
+
d
)
=
'\n'
;
d
++
;
fputc
(
'\n'
,
stream
);
break
;
case
'Z'
:
if
(
p_item
)
{
char
*
psz_now_playing
=
input_item_GetNowPlaying
(
p_item
);
if
(
EMPTY_STR
(
psz_now_playing
)
)
if
(
write_meta
(
stream
,
item
,
vlc_meta_NowPlaying
)
==
EOF
)
{
char
*
psz_temp
=
input_item_GetTitleFbName
(
p_item
);
char
*
psz_artist
=
input_item_GetArtist
(
p_item
);
if
(
!
EMPTY_STR
(
psz_artist
)
)
char
*
title
=
input_item_GetTitleFbName
(
item
);
if
(
write_meta
(
stream
,
item
,
vlc_meta_Artist
)
>=
0
&&
title
!=
NULL
)
fputs
(
" - "
,
stream
);
if
(
title
!=
NULL
)
{
INSERT_STRING
(
psz_artist
);
if
(
!
EMPTY_STR
(
psz_temp
)
)
INSERT_STRING_NO_FREE
(
" - "
);
fputs
(
title
,
stream
);
free
(
title
);
}
INSERT_STRING
(
psz_temp
);
}
else
INSERT_STRING
(
psz_now_playing
);
}
break
;
case
' '
:
b_empty_if_na
=
true
;
b_is_format
=
true
;
break
;
default:
*
(
dst
+
d
)
=
*
s
;
d
++
;
fputc
(
c
,
stream
);
break
;
}
if
(
*
s
!=
' '
)
b_is_format
=
false
;
}
else
if
(
*
s
==
'$'
)
{
b_is_format
=
true
;
b_empty_if_na
=
false
;
}
else
#ifdef HAVE_OPEN_MEMSTREAM
return
(
fclose
(
stream
)
==
0
)
?
str
:
NULL
;
#else
len
=
ftell
(
stream
);
if
(
len
!=
(
size_t
)
-
1
)
{
*
(
dst
+
d
)
=
*
s
;
d
++
;
rewind
(
stream
);
str
=
xmalloc
(
len
+
1
);
fread
(
str
,
len
,
1
,
stream
);
str
[
len
]
=
'\0'
;
}
s
++
;
}
*
(
dst
+
d
)
=
'\0'
;
return
dst
;
fclose
(
stream
);
return
str
;
#endif
}
#undef INSERT_STRING
#undef INSERT_STRING_NO_FREE
/**
* Remove forbidden, potentially forbidden and otherwise evil characters from
...
...
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