1 /*****************************************************************************
2 * strings.c: String related functions
3 *****************************************************************************
4 * Copyright (C) 2006 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea at videolan dot org>
8 * Daniel Stranger <vlc at schmaller dot de>
9 * Rémi Denis-Courmont <rem # videolan org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
24 *****************************************************************************/
26 /*****************************************************************************
28 *****************************************************************************/
35 /* Needed by str_format_time */
38 /* Needed by str_format_meta */
39 #include <vlc_input.h>
41 #include <vlc_playlist.h>
44 #include <vlc_strings.h>
46 #include <vlc_charset.h>
49 * Unescape URI encoded string
50 * \return decoded duplicated string
52 char *unescape_URI_duplicate( const char *psz )
54 char *psz_dup = strdup( psz );
55 unescape_URI( psz_dup );
60 * Unescape URI encoded string in place
63 void unescape_URI( char *psz )
65 unsigned char *in = (unsigned char *)psz, *out = in, c;
69 while( ( c = *in++ ) != '\0' )
75 char val[5], *pval = val;
85 if( ( *pval++ = *in++ ) == '\0' )
87 if( ( *pval++ = *in++ ) == '\0' )
93 if( ( *pval++ = *in++ ) == '\0' )
98 cp = strtoul( val, NULL, 0x10 );
104 *out++ = (( cp >> 6) | 0xc0);
105 *out++ = (( cp & 0x3f) | 0x80);
109 assert( cp < 0x10000 );
110 *out++ = (( cp >> 12) | 0xe0);
111 *out++ = (((cp >> 6) & 0x3f) | 0x80);
112 *out++ = (( cp & 0x3f) | 0x80);
117 /* + is not a special case - it means plus, not space. */
120 /* Inserting non-ASCII or non-printable characters is unsafe,
121 * and no sane browser will send these unencoded */
122 if( ( c < 32 ) || ( c > 127 ) )
132 * Decode encoded URI string
133 * \return decoded duplicated string
135 char *decode_URI_duplicate( const char *psz )
137 char *psz_dup = strdup( psz );
138 decode_URI( psz_dup );
143 * Decode encoded URI string in place
146 void decode_URI( char *psz )
148 unsigned char *in = (unsigned char *)psz, *out = in, c;
152 while( ( c = *in++ ) != '\0' )
160 if( ( ( hex[0] = *in++ ) == 0 )
161 || ( ( hex[1] = *in++ ) == 0 ) )
165 *out++ = (unsigned char)strtoul( hex, NULL, 0x10 );
174 /* Inserting non-ASCII or non-printable characters is unsafe,
175 * and no sane browser will send these unencoded */
176 if( ( c < 32 ) || ( c > 127 ) )
186 static inline int isurlsafe( int c )
188 return ( (unsigned char)( c - 'a' ) < 26 )
189 || ( (unsigned char)( c - 'A' ) < 26 )
190 || ( (unsigned char)( c - '0' ) < 10 )
191 /* Hmm, we should not encode character that are allowed in URLs
192 * (even if they are not URL-safe), nor URL-safe characters.
193 * We still encode some of them because of Microsoft's crap browser.
195 || ( strchr( "-_.", c ) != NULL );
198 static inline char url_hexchar( int c )
200 return ( c < 10 ) ? c + '0' : c + 'A' - 10;
204 * encode_URI_component
205 * Encodes an URI component.
207 * @param psz_url nul-terminated UTF-8 representation of the component.
208 * Obviously, you can't pass an URI containing a nul character, but you don't
209 * want to do that, do you?
211 * @return encoded string (must be free()'d)
213 char *encode_URI_component( const char *psz_url )
215 char psz_enc[3 * strlen( psz_url ) + 1], *out = psz_enc;
218 for( in = (const uint8_t *)psz_url; *in; in++ )
230 *out++ = url_hexchar( c >> 4 );
231 *out++ = url_hexchar( c & 0xf );
236 return strdup( psz_enc );
240 * Converts "<", ">" and "&" to "<", ">" and "&"
241 * \param string to convert
243 void resolve_xml_special_chars( char *psz_value )
245 char *p_pos = psz_value;
249 if( *psz_value == '&' )
251 #define TRY_CHAR( src, len, dst ) \
252 if( !strncmp( psz_value, src, len ) ) \
257 #define TRY_LONGCHAR( src, len, dst ) \
258 if( !strncmp( psz_value, src, len ) ) \
260 strncpy( p_pos, dst, strlen( dst ) ); \
261 p_pos += strlen( dst ) - 1; \
264 TRY_CHAR( "<", 4, '<' )
265 else TRY_CHAR( ">", 4, '>' )
266 else TRY_CHAR( "&", 5, '&' )
267 else TRY_CHAR( """, 6, '"' )
268 else TRY_CHAR( "'", 6, '\'' )
269 else if( psz_value[1] == '#' )
272 int i = strtol( psz_value+2, &psz_end, 10 );
273 if( *psz_end == ';' )
275 if( i >= 32 && i <= 126 )
278 psz_value = psz_end+1;
282 /* Unhandled code, FIXME */
289 /* Invalid entity number */
294 else TRY_LONGCHAR( "À", 8, "À" )
295 else TRY_LONGCHAR( "Á", 8, "Á" )
296 else TRY_LONGCHAR( "Â", 7, "Â" )
297 else TRY_LONGCHAR( "Ã", 8, "Ã" )
298 else TRY_LONGCHAR( "Ä", 6, "Ä" )
299 else TRY_LONGCHAR( "Å", 7, "Å" )
300 else TRY_LONGCHAR( "Æ", 7, "Æ" )
301 else TRY_LONGCHAR( "Ç", 8, "Ç" )
302 else TRY_LONGCHAR( "È", 8, "È" )
303 else TRY_LONGCHAR( "É", 8, "É" )
304 else TRY_LONGCHAR( "Ê", 7, "Ê" )
305 else TRY_LONGCHAR( "Ë", 6, "Ë" )
306 else TRY_LONGCHAR( "Ì", 8, "Ì" )
307 else TRY_LONGCHAR( "Í", 8, "Í" )
308 else TRY_LONGCHAR( "Î", 7, "Î" )
309 else TRY_LONGCHAR( "Ï", 6, "Ï" )
310 else TRY_LONGCHAR( "Ð", 5, "Ð" )
311 else TRY_LONGCHAR( "Ñ", 8, "Ñ" )
312 else TRY_LONGCHAR( "Ò", 8, "Ò" )
313 else TRY_LONGCHAR( "Ó", 8, "Ó" )
314 else TRY_LONGCHAR( "Ô", 7, "Ô" )
315 else TRY_LONGCHAR( "Õ", 8, "Õ" )
316 else TRY_LONGCHAR( "Ö", 6, "Ö" )
317 else TRY_LONGCHAR( "Ø", 8, "Ø" )
318 else TRY_LONGCHAR( "Ù", 8, "Ù" )
319 else TRY_LONGCHAR( "Ú", 8, "Ú" )
320 else TRY_LONGCHAR( "Û", 7, "Û" )
321 else TRY_LONGCHAR( "Ü", 6, "Ü" )
322 else TRY_LONGCHAR( "Ý", 8, "Ý" )
323 else TRY_LONGCHAR( "Þ", 7, "Þ" )
324 else TRY_LONGCHAR( "ß", 7, "ß" )
325 else TRY_LONGCHAR( "à", 8, "à" )
326 else TRY_LONGCHAR( "á", 8, "á" )
327 else TRY_LONGCHAR( "â", 7, "â" )
328 else TRY_LONGCHAR( "ã", 8, "ã" )
329 else TRY_LONGCHAR( "ä", 6, "ä" )
330 else TRY_LONGCHAR( "å", 7, "å" )
331 else TRY_LONGCHAR( "æ", 7, "æ" )
332 else TRY_LONGCHAR( "ç", 8, "ç" )
333 else TRY_LONGCHAR( "è", 8, "è" )
334 else TRY_LONGCHAR( "é", 8, "é" )
335 else TRY_LONGCHAR( "ê", 7, "ê" )
336 else TRY_LONGCHAR( "ë", 6, "ë" )
337 else TRY_LONGCHAR( "ì", 8, "ì" )
338 else TRY_LONGCHAR( "í", 8, "í" )
339 else TRY_LONGCHAR( "î", 7, "î" )
340 else TRY_LONGCHAR( "ï", 6, "ï" )
341 else TRY_LONGCHAR( "ð", 5, "ð" )
342 else TRY_LONGCHAR( "ñ", 8, "ñ" )
343 else TRY_LONGCHAR( "ò", 8, "ò" )
344 else TRY_LONGCHAR( "ó", 8, "ó" )
345 else TRY_LONGCHAR( "ô", 7, "ô" )
346 else TRY_LONGCHAR( "õ", 8, "õ" )
347 else TRY_LONGCHAR( "ö", 6, "ö" )
348 else TRY_LONGCHAR( "ø", 8, "ø" )
349 else TRY_LONGCHAR( "ù", 8, "ù" )
350 else TRY_LONGCHAR( "ú", 8, "ú" )
351 else TRY_LONGCHAR( "û", 7, "û" )
352 else TRY_LONGCHAR( "ü", 6, "ü" )
353 else TRY_LONGCHAR( "ý", 8, "ý" )
354 else TRY_LONGCHAR( "þ", 7, "þ" )
355 else TRY_LONGCHAR( "ÿ", 6, "ÿ" )
356 else TRY_LONGCHAR( "¡", 7, "¡" )
357 else TRY_LONGCHAR( "¤", 8, "¤" )
358 else TRY_LONGCHAR( "¢", 6, "¢" )
359 else TRY_LONGCHAR( "£", 7, "£" )
360 else TRY_LONGCHAR( "¥", 5, "¥" )
361 else TRY_LONGCHAR( "¦", 8, "¦" )
362 else TRY_LONGCHAR( "§", 6, "§" )
363 else TRY_LONGCHAR( "¨", 5, "¨" )
364 else TRY_LONGCHAR( "©", 6, "©" )
365 else TRY_LONGCHAR( "ª", 6, "ª" )
366 else TRY_LONGCHAR( "«", 7, "«" )
367 else TRY_LONGCHAR( "¬", 5, "¬" )
368 else TRY_LONGCHAR( "­", 5, "" )
369 else TRY_LONGCHAR( "®", 5, "®" )
370 else TRY_LONGCHAR( "™", 7, "™" )
371 else TRY_LONGCHAR( "¯", 6, "¯" )
372 else TRY_LONGCHAR( "°", 5, "°" )
373 else TRY_LONGCHAR( "±", 8, "±" )
374 else TRY_LONGCHAR( "²", 6, "²" )
375 else TRY_LONGCHAR( "³", 6, "³" )
376 else TRY_LONGCHAR( "´", 7, "´" )
377 else TRY_LONGCHAR( "µ", 7, "µ" )
378 else TRY_LONGCHAR( "¶", 6, "¶" )
379 else TRY_LONGCHAR( "·", 8, "·" )
380 else TRY_LONGCHAR( "¸", 7, "¸" )
381 else TRY_LONGCHAR( "¹", 6, "¹" )
382 else TRY_LONGCHAR( "º", 6, "º" )
383 else TRY_LONGCHAR( "»", 7, "»" )
384 else TRY_LONGCHAR( "¼", 8, "¼" )
385 else TRY_LONGCHAR( "½", 8, "½" )
386 else TRY_LONGCHAR( "¾", 8, "¾" )
387 else TRY_LONGCHAR( "¿", 8, "¿" )
388 else TRY_LONGCHAR( "×", 7, "×" )
389 else TRY_LONGCHAR( "÷", 8, "÷" )
390 else TRY_LONGCHAR( "Œ", 7, "Œ" )
391 else TRY_LONGCHAR( "œ", 7, "œ" )
392 else TRY_LONGCHAR( "Š", 8, "Š" )
393 else TRY_LONGCHAR( "š", 8, "š" )
394 else TRY_LONGCHAR( "Ÿ", 6, "Ÿ" )
395 else TRY_LONGCHAR( "ˆ", 6, "ˆ" )
396 else TRY_LONGCHAR( "˜", 7, "˜" )
397 else TRY_LONGCHAR( "–", 7, "–" )
398 else TRY_LONGCHAR( "—", 7, "—" )
399 else TRY_LONGCHAR( "‘", 7, "‘" )
400 else TRY_LONGCHAR( "’", 7, "’" )
401 else TRY_LONGCHAR( "‚", 7, "‚" )
402 else TRY_LONGCHAR( "“", 7, "“" )
403 else TRY_LONGCHAR( "”", 7, "”" )
404 else TRY_LONGCHAR( "„", 7, "„" )
405 else TRY_LONGCHAR( "†", 8, "†" )
406 else TRY_LONGCHAR( "‡", 8, "‡" )
407 else TRY_LONGCHAR( "…", 8, "…" )
408 else TRY_LONGCHAR( "‰", 8, "‰" )
409 else TRY_LONGCHAR( "‹", 8, "‹" )
410 else TRY_LONGCHAR( "›", 8, "›" )
411 else TRY_LONGCHAR( "€", 6, "€" )
431 * Converts '<', '>', '\"', '\'' and '&' to their html entities
432 * \param psz_content simple element content that is to be converted
434 char *convert_xml_special_chars( const char *psz_content )
436 char *psz_temp = malloc( 6 * strlen( psz_content ) + 1 );
437 const char *p_from = psz_content;
438 char *p_to = psz_temp;
442 if ( *p_from == '<' )
444 strcpy( p_to, "<" );
447 else if ( *p_from == '>' )
449 strcpy( p_to, ">" );
452 else if ( *p_from == '&' )
454 strcpy( p_to, "&" );
457 else if( *p_from == '\"' )
459 strcpy( p_to, """ );
462 else if( *p_from == '\'' )
464 strcpy( p_to, "'" );
479 /* Base64 encoding */
480 char *vlc_b64_encode_binary( const uint8_t *src, size_t i_src )
482 static const char b64[] =
483 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
485 char *ret = malloc( ( i_src + 4 ) * 4 / 3 );
493 /* pops (up to) 3 bytes of input, push 4 bytes */
498 *dst++ = b64[v >> 26];
504 *dst++ = b64[v >> 26];
509 v |= *src++ << 20; // 3/3
510 *dst++ = ( i_src >= 2 ) ? b64[v >> 26] : '='; // 3/4
514 *dst++ = ( i_src >= 3 ) ? b64[v >> 26] : '='; // 4/4
526 char *vlc_b64_encode( const char *src )
529 return vlc_b64_encode_binary( (const uint8_t*)src, strlen(src) );
531 return vlc_b64_encode_binary( (const uint8_t*)"", 0 );
534 /* Base64 decoding */
535 size_t vlc_b64_decode_binary_to_buffer( uint8_t *p_dst, size_t i_dst, const char *p_src )
537 static const int b64[256] = {
538 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 00-0F */
539 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 10-1F */
540 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, /* 20-2F */
541 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, /* 30-3F */
542 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, /* 40-4F */
543 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, /* 50-5F */
544 -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, /* 60-6F */
545 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, /* 70-7F */
546 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 80-8F */
547 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 90-9F */
548 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* A0-AF */
549 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* B0-BF */
550 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* C0-CF */
551 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* D0-DF */
552 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* E0-EF */
553 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 /* F0-FF */
555 uint8_t *p_start = p_dst;
556 uint8_t *p = (uint8_t *)p_src;
561 for( i_level = 0, i_last = 0; i_dst > 0 && *p != '\0'; i_dst--, p++ )
563 const int c = b64[(unsigned int)*p];
573 *p_dst++ = ( i_last << 2 ) | ( ( c >> 4)&0x03 );
577 *p_dst++ = ( ( i_last << 4 )&0xf0 ) | ( ( c >> 2 )&0x0f );
581 *p_dst++ = ( ( i_last &0x03 ) << 6 ) | c;
587 return p_dst - p_start;
589 size_t vlc_b64_decode_binary( uint8_t **pp_dst, const char *psz_src )
591 const int i_src = strlen( psz_src );
594 *pp_dst = p_dst = malloc( i_src );
597 return vlc_b64_decode_binary_to_buffer( p_dst, i_src, psz_src );
599 char *vlc_b64_decode( const char *psz_src )
601 const int i_src = strlen( psz_src );
602 char *p_dst = malloc( i_src + 1 );
607 i_dst = vlc_b64_decode_binary_to_buffer( (uint8_t*)p_dst, i_src, psz_src );
613 /****************************************************************************
614 * String formating functions
615 ****************************************************************************/
616 char *str_format_time( const char *tformat )
620 #if defined(HAVE_LOCALTIME_R)
626 /* Get the current time. */
627 curtime = time( NULL );
629 /* Convert it to local time representation. */
630 #if defined(HAVE_LOCALTIME_R)
631 localtime_r( &curtime, &loctime );
632 strftime( buffer, 255, tformat, &loctime );
634 loctime = localtime( &curtime );
635 strftime( buffer, 255, tformat, loctime );
637 return strdup( buffer );
640 #define INSERT_STRING( check, string ) \
641 if( check && string ) \
643 int len = strlen( string ); \
644 dst = realloc( dst, \
645 i_size = i_size + len + 1 ); \
646 strncpy( d, string, len+1 ); \
654 char *__str_format_meta( vlc_object_t *p_object, const char *string )
656 const char *s = string;
657 char *dst = malloc( 1000 );
660 int b_empty_if_na = 0;
662 int i_size = strlen( string );
664 playlist_t *p_playlist = pl_Yield( p_object );
665 input_thread_t *p_input = p_playlist->p_input;
666 input_item_t *p_item = NULL;
667 pl_Release( p_object );
670 vlc_object_yield( p_input );
671 p_item = input_GetItem(p_input);
673 vlc_mutex_lock( &p_item->lock );
676 sprintf( dst, string );
685 INSERT_STRING( p_item && p_item->p_meta,
686 p_item->p_meta->psz_artist );
689 INSERT_STRING( p_item && p_item->p_meta,
690 p_item->p_meta->psz_album );
693 INSERT_STRING( p_item && p_item->p_meta,
694 p_item->p_meta->psz_copyright );
697 INSERT_STRING( p_item && p_item->p_meta,
698 p_item->p_meta->psz_description );
701 INSERT_STRING( p_item && p_item->p_meta,
702 p_item->p_meta->psz_encodedby );
705 INSERT_STRING( p_item && p_item->p_meta,
706 p_item->p_meta->psz_genre );
709 INSERT_STRING( p_item && p_item->p_meta,
710 p_item->p_meta->psz_language );
713 INSERT_STRING( p_item && p_item->p_meta,
714 p_item->p_meta->psz_tracknum );
717 INSERT_STRING( p_item && p_item->p_meta,
718 p_item->p_meta->psz_nowplaying );
721 INSERT_STRING( p_item && p_item->p_meta,
722 p_item->p_meta->psz_rating );
729 lang = var_GetString( p_input, "sub-language" );
733 lang = strdup( b_empty_if_na ? "" : "-" );
735 INSERT_STRING( 1, lang );
740 INSERT_STRING( p_item && p_item->p_meta,
741 p_item->p_meta->psz_title );
744 INSERT_STRING( p_item && p_item->p_meta,
745 p_item->p_meta->psz_url );
748 INSERT_STRING( p_item && p_item->p_meta,
749 p_item->p_meta->psz_date );
754 snprintf( buf, 10, "%d",
755 var_GetInteger( p_input, "bit-rate" )/1000 );
759 sprintf( buf, b_empty_if_na ? "" : "-" );
761 INSERT_STRING( 1, buf );
766 snprintf( buf, 10, "%d",
767 var_GetInteger( p_input, "chapter" ) );
771 sprintf( buf, b_empty_if_na ? "" : "-" );
773 INSERT_STRING( 1, buf );
778 sprintf( buf, "%02d:%02d:%02d",
779 (int)(p_item->i_duration/(3600000000)),
780 (int)((p_item->i_duration/(60000000))%60),
781 (int)((p_item->i_duration/1000000)%60) );
785 sprintf( buf, b_empty_if_na ? "" : "--:--:--" );
787 INSERT_STRING( 1, buf );
790 INSERT_STRING( p_item, p_item->psz_uri );
795 snprintf( buf, 10, "%d",
796 var_GetInteger( p_input, "title" ) );
800 sprintf( buf, b_empty_if_na ? "" : "-" );
802 INSERT_STRING( 1, buf );
805 if( p_item && p_input )
807 sprintf( buf, "%02d:%02d:%02d",
808 (int)((p_item->i_duration-p_input->i_time)/(3600000000)),
809 (int)(((p_item->i_duration-p_input->i_time)/(60000000))%60),
810 (int)(((p_item->i_duration-p_input->i_time)/1000000)%60) );
814 sprintf( buf, b_empty_if_na ? "" : "--:--:--" );
816 INSERT_STRING( 1, buf );
819 INSERT_STRING( p_item, p_item->psz_name );
826 lang = var_GetString( p_input, "audio-language" );
830 lang = strdup( b_empty_if_na ? "" : "-" );
832 INSERT_STRING( 1, lang );
839 snprintf( buf, 10, "%2.1lf",
840 var_GetFloat( p_input, "position" ) * 100. );
844 sprintf( buf, b_empty_if_na ? "" : "--.-%%" );
846 INSERT_STRING( 1, buf );
851 int r = var_GetInteger( p_input, "rate" );
852 snprintf( buf, 10, "%d.%d", r/1000, r%1000 );
856 sprintf( buf, b_empty_if_na ? "" : "-" );
858 INSERT_STRING( 1, buf );
863 int r = var_GetInteger( p_input, "sample-rate" );
864 snprintf( buf, 10, "%d.%d", r/1000, (r/100)%10 );
868 sprintf( buf, b_empty_if_na ? "" : "-" );
870 INSERT_STRING( 1, buf );
875 sprintf( buf, "%02d:%02d:%02d",
876 (int)(p_input->i_time/(3600000000)),
877 (int)((p_input->i_time/(60000000))%60),
878 (int)((p_input->i_time/1000000)%60) );
882 sprintf( buf, b_empty_if_na ? "" : "--:--:--" );
884 INSERT_STRING( 1, buf );
887 INSERT_STRING( p_item && p_item->p_meta,
888 p_item->p_meta->psz_publisher );
892 audio_volume_t volume;
893 aout_VolumeGet( p_object, &volume );
894 snprintf( buf, 10, "%d", volume );
895 INSERT_STRING( 1, buf );
931 vlc_object_release( p_input );
933 vlc_mutex_unlock( &p_item->lock );
940 * Apply str format time and str format meta
942 char *__str_format( vlc_object_t *p_this, const char *psz_src )
944 char *psz_buf1, *psz_buf2;
945 psz_buf1 = str_format_time( psz_src );
946 psz_buf2 = str_format_meta( p_this, psz_buf1 );
952 * Remove forbidden characters from filenames (including slashes)
954 void filename_sanitize( char *str )
956 if( *str == '.' && (str[1] == '\0' || (str[1] == '.' && str[2] == '\0' ) ) )
988 * Remove forbidden characters from full paths (leaves slashes)
990 void path_sanitize( char *str )
994 * Uncomment the two blocks to prevent /../ or /./, i'm not sure that we
997 char *prev = str - 1;
1000 /* check drive prefix if path is absolute */
1001 if( isalpha(*str) && (':' == *(str+1)) )
1026 if( str - prev == 2 && prev[1] == '.' )
1030 else if( str - prev == 3 && prev[1] == '.' && prev[2] == '.' )