Commit 5a4c862f authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

XML: encode C0/C1 control codes correctly (fix #4737)

(cherry picked from commit 15c5e82683f89b63542b5f0ee71a059c6dcafdea)
parent 7b017ca7
...@@ -47,6 +47,8 @@ ...@@ -47,6 +47,8 @@
#include <vlc_strings.h> #include <vlc_strings.h>
#include <vlc_url.h> #include <vlc_url.h>
#include <vlc_charset.h> #include <vlc_charset.h>
#include <libvlc.h>
#include <errno.h>
/** /**
* Decode encoded URI component. See also decode_URI(). * Decode encoded URI component. See also decode_URI().
...@@ -392,41 +394,51 @@ void resolve_xml_special_chars( char *psz_value ) ...@@ -392,41 +394,51 @@ void resolve_xml_special_chars( char *psz_value )
} }
/** /**
* Converts '<', '>', '\"', '\'' and '&' to their html entities * XML-encode an UTF-8 string
* \param psz_content simple element content that is to be converted * \param str nul-terminated UTF-8 byte sequence to XML-encode
* \return XML encoded string or NULL on error
* (errno is set to ENOMEM or EILSEQ as appropriate)
*/ */
char *convert_xml_special_chars( const char *psz_content ) char *convert_xml_special_chars (const char *str)
{ {
assert( psz_content ); assert (str != NULL);
const size_t len = strlen( psz_content ); const size_t len = strlen (str);
char *const psz_temp = malloc( 6 * len + 1 ); char *const buf = malloc (6 * len + 1), *ptr = buf;
char *p_to = psz_temp; if (unlikely(buf == NULL))
if( psz_temp == NULL )
return NULL; return NULL;
for( size_t i = 0; i < len; i++ )
size_t n;
uint32_t cp;
while ((n = vlc_towc (str, &cp)) != 0)
{ {
const char *str; if (unlikely(n == (size_t)-1))
char c = psz_content[i]; {
free (buf);
errno = EILSEQ;
return NULL;
}
switch ( c ) if ((cp & ~0x0080) < 32 /* C0/C1 control codes */
&& strchr ("\x09\x0A\x0D\x85", cp) == NULL)
ptr += sprintf (ptr, "&#%"PRIu32";", cp);
else
switch (cp)
{ {
case '\"': str = "quot"; break; case '\"': strcpy (ptr, "&quot;"); ptr += 6; break;
case '&': str = "amp"; break; case '&': strcpy (ptr, "&amp;"); ptr += 5; break;
case '\'': str = "#39"; break; case '\'': strcpy (ptr, "&#39;"); ptr += 5; break;
case '<': str = "lt"; break; case '<': strcpy (ptr, "&lt;"); ptr += 4; break;
case '>': str = "gt"; break; case '>': strcpy (ptr, "&gt;"); ptr += 4; break;
default: default: memcpy (ptr, str, n); ptr += n; break;
*(p_to++) = c;
continue;
} }
p_to += sprintf( p_to, "&%s;", str ); str += n;
} }
*(p_to++) = '\0'; *(ptr++) = '\0';
p_to = realloc( psz_temp, p_to - psz_temp ); ptr = realloc (buf, ptr - buf);
return p_to ? p_to : psz_temp; /* cannot fail */ return likely(ptr != NULL) ? ptr : buf; /* cannot fail */
} }
/* Base64 encoding */ /* Base64 encoding */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment