mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-05 08:56:16 +01:00
Properly nul-terminate return values from g_convert()
The patch ensures that multibyte character sets are properly
nul-terminated. This is an issue because the documentation claims to
return a "nul-terminated" string and users of the API assume that means
a proper nul-termination in the resulting character set.
I looked at Pidgin and GStreamer code and found at least 3 cases where
this was happening.
This patch also reverts the documentation change from
5a633f82db
as that is now no longer
necessary.
This commit is contained in:
parent
5a633f82db
commit
4288ad7692
@ -57,6 +57,12 @@
|
||||
|
||||
#include "galias.h"
|
||||
|
||||
/* We try to terminate strings in unknown charsets with this many zero bytes
|
||||
* to ensure that multibyte strings really are nul-terminated when we return
|
||||
* them from g_convert() and friends.
|
||||
*/
|
||||
#define NUL_TERMINATOR_LENGTH 4
|
||||
|
||||
GQuark
|
||||
g_convert_error_quark (void)
|
||||
{
|
||||
@ -566,16 +572,8 @@ close_converter (GIConv cd)
|
||||
* </footnote>.
|
||||
*
|
||||
* Return value: If the conversion was successful, a newly allocated
|
||||
* nul-terminated<footnote id="nul-returns">
|
||||
* <para>
|
||||
* Nul-terminated return values from conversion functions
|
||||
* are terminated by a single 0 byte only. This means that
|
||||
* for multibyte character sets like UTF-16, they must be
|
||||
* treated as not nul-terminated.
|
||||
* </para>
|
||||
* </footnote>
|
||||
* string, which must be freed with g_free(). Otherwise %NULL
|
||||
* and @error will be set.
|
||||
* nul-terminated string, which must be freed with
|
||||
* g_free(). Otherwise %NULL and @error will be set.
|
||||
**/
|
||||
gchar*
|
||||
g_convert_with_iconv (const gchar *str,
|
||||
@ -603,9 +601,9 @@ g_convert_with_iconv (const gchar *str,
|
||||
|
||||
p = str;
|
||||
inbytes_remaining = len;
|
||||
outbuf_size = len + 1; /* + 1 for nul in case len == 1 */
|
||||
outbuf_size = len + NUL_TERMINATOR_LENGTH;
|
||||
|
||||
outbytes_remaining = outbuf_size - 1; /* -1 for nul */
|
||||
outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH;
|
||||
outp = dest = g_malloc (outbuf_size);
|
||||
|
||||
while (!done && !have_error)
|
||||
@ -631,7 +629,7 @@ g_convert_with_iconv (const gchar *str,
|
||||
dest = g_realloc (dest, outbuf_size);
|
||||
|
||||
outp = dest + used;
|
||||
outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
|
||||
outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH;
|
||||
}
|
||||
break;
|
||||
case EILSEQ:
|
||||
@ -665,7 +663,7 @@ g_convert_with_iconv (const gchar *str,
|
||||
}
|
||||
}
|
||||
|
||||
*outp = '\0';
|
||||
memset (outp, 0, NUL_TERMINATOR_LENGTH);
|
||||
|
||||
if (bytes_read)
|
||||
*bytes_read = p - str;
|
||||
@ -727,9 +725,8 @@ g_convert_with_iconv (const gchar *str,
|
||||
* conversions<footnoteref linkend="streaming-state"/>.
|
||||
*
|
||||
* Return value: If the conversion was successful, a newly allocated
|
||||
* nul-terminated<footnoteref linkend="nul-returns"/> string,
|
||||
* which must be freed with g_free(). Otherwise %NULL and
|
||||
* @error will be set.
|
||||
* nul-terminated string, which must be freed with
|
||||
* g_free(). Otherwise %NULL and @error will be set.
|
||||
**/
|
||||
gchar*
|
||||
g_convert (const gchar *str,
|
||||
@ -803,9 +800,8 @@ g_convert (const gchar *str,
|
||||
* conversions<footnoteref linkend="streaming-state"/>.
|
||||
*
|
||||
* Return value: If the conversion was successful, a newly allocated
|
||||
* nul-terminated<footnoteref linkend="nul-returns"/> string,
|
||||
* which must be freed with g_free(). Otherwise %NULL and
|
||||
* @error will be set.
|
||||
* nul-terminated string, which must be freed with
|
||||
* g_free(). Otherwise %NULL and @error will be set.
|
||||
**/
|
||||
gchar*
|
||||
g_convert_with_fallback (const gchar *str,
|
||||
@ -894,8 +890,8 @@ g_convert_with_fallback (const gchar *str,
|
||||
*/
|
||||
p = utf8;
|
||||
|
||||
outbuf_size = len + 1; /* + 1 for nul in case len == 1 */
|
||||
outbytes_remaining = outbuf_size - 1; /* -1 for nul */
|
||||
outbuf_size = len + NUL_TERMINATOR_LENGTH;
|
||||
outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH;
|
||||
outp = dest = g_malloc (outbuf_size);
|
||||
|
||||
while (!done && !have_error)
|
||||
@ -919,7 +915,7 @@ g_convert_with_fallback (const gchar *str,
|
||||
dest = g_realloc (dest, outbuf_size);
|
||||
|
||||
outp = dest + used;
|
||||
outbytes_remaining = outbuf_size - used - 1; /* -1 for nul */
|
||||
outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -988,7 +984,7 @@ g_convert_with_fallback (const gchar *str,
|
||||
|
||||
/* Cleanup
|
||||
*/
|
||||
*outp = '\0';
|
||||
memset (outp, 0, NUL_TERMINATOR_LENGTH);
|
||||
|
||||
close_converter (cd);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user