charsets: report GError in byte_array_append() failures

This commit is contained in:
Aleksander Morgado
2020-04-04 14:51:22 +02:00
parent a2b57474dc
commit 2376859f36
6 changed files with 64 additions and 61 deletions

View File

@@ -4561,7 +4561,7 @@ ussd_encode (const gchar *command,
guint32 *scheme, guint32 *scheme,
GError **error) GError **error)
{ {
GByteArray *array; g_autoptr(GByteArray) array = NULL;
if (mm_charset_can_convert_to (command, MM_MODEM_CHARSET_GSM)) { if (mm_charset_can_convert_to (command, MM_MODEM_CHARSET_GSM)) {
guint8 *gsm; guint8 *gsm;
@@ -4581,12 +4581,13 @@ ussd_encode (const gchar *command,
array = g_byte_array_new_take (packed, packed_len); array = g_byte_array_new_take (packed, packed_len);
} else { } else {
g_autoptr(GError) inner_error = NULL;
*scheme = MM_MODEM_GSM_USSD_SCHEME_UCS2; *scheme = MM_MODEM_GSM_USSD_SCHEME_UCS2;
array = g_byte_array_sized_new (strlen (command) * 2); array = g_byte_array_sized_new (strlen (command) * 2);
if (!mm_modem_charset_byte_array_append (array, command, FALSE, MM_MODEM_CHARSET_UCS2)) { if (!mm_modem_charset_byte_array_append (array, command, FALSE, MM_MODEM_CHARSET_UCS2, &inner_error)) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED, g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_UNSUPPORTED,
"Failed to encode USSD command in UCS2 charset"); "Failed to encode USSD command in UCS2 charset: %s", inner_error->message);
g_byte_array_unref (array);
return NULL; return NULL;
} }
} }
@@ -4594,11 +4595,10 @@ ussd_encode (const gchar *command,
if (array->len > 160) { if (array->len > 160) {
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS,
"Failed to encode USSD command: encoded data too long (%u > 160)", array->len); "Failed to encode USSD command: encoded data too long (%u > 160)", array->len);
g_byte_array_unref (array);
return NULL; return NULL;
} }
return array; return g_steal_pointer (&array);
} }
static gchar * static gchar *

View File

@@ -5800,14 +5800,14 @@ modem_3gpp_ussd_send (MMIfaceModem3gppUssd *_self,
/* USSD Encode/Decode (3GPP/USSD interface) */ /* USSD Encode/Decode (3GPP/USSD interface) */
static gchar * static gchar *
modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self, modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
const gchar *command, const gchar *command,
guint *scheme, guint *scheme,
GError **error) GError **error)
{ {
MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self); MMBroadbandModem *broadband = MM_BROADBAND_MODEM (self);
GByteArray *ussd_command; gchar *hex = NULL;
gchar *hex = NULL; g_autoptr(GByteArray) ussd_command = NULL;
ussd_command = g_byte_array_new (); ussd_command = g_byte_array_new ();
@@ -5816,7 +5816,8 @@ modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
if (mm_modem_charset_byte_array_append (ussd_command, if (mm_modem_charset_byte_array_append (ussd_command,
command, command,
FALSE, FALSE,
broadband->priv->modem_current_charset)) { broadband->priv->modem_current_charset,
NULL)) {
/* The scheme value does NOT represent the encoding used to encode the string /* The scheme value does NOT represent the encoding used to encode the string
* we're giving. This scheme reflects the encoding that the modem should use when * we're giving. This scheme reflects the encoding that the modem should use when
* sending the data out to the network. We're hardcoding this to GSM-7 because * sending the data out to the network. We're hardcoding this to GSM-7 because
@@ -5827,8 +5828,6 @@ modem_3gpp_ussd_encode (MMIfaceModem3gppUssd *self,
hex = mm_utils_bin2hexstr (ussd_command->data, ussd_command->len); hex = mm_utils_bin2hexstr (ussd_command->data, ussd_command->len);
} }
g_byte_array_free (ussd_command, TRUE);
return hex; return hex;
} }

View File

@@ -112,29 +112,26 @@ charset_iconv_from (MMModemCharset charset)
} }
gboolean gboolean
mm_modem_charset_byte_array_append (GByteArray *array, mm_modem_charset_byte_array_append (GByteArray *array,
const char *utf8, const gchar *utf8,
gboolean quoted, gboolean quoted,
MMModemCharset charset) MMModemCharset charset,
GError **error)
{ {
const char *iconv_to; g_autofree gchar *converted = NULL;
char *converted; const gchar *iconv_to;
GError *error = NULL; gsize written = 0;
gsize written = 0;
g_return_val_if_fail (array != NULL, FALSE); g_return_val_if_fail (array != NULL, FALSE);
g_return_val_if_fail (utf8 != NULL, FALSE); g_return_val_if_fail (utf8 != NULL, FALSE);
iconv_to = charset_iconv_to (charset); iconv_to = charset_iconv_to (charset);
g_return_val_if_fail (iconv_to != NULL, FALSE); g_assert (iconv_to);
converted = g_convert (utf8, -1, iconv_to, "UTF-8", NULL, &written, &error); converted = g_convert (utf8, -1, iconv_to, "UTF-8", NULL, &written, error);
if (!converted) { if (!converted) {
if (error) { g_prefix_error (error, "Failed to convert '%s' to %s character set",
mm_warn ("failed to convert '%s' to %s character set: (%d) %s", utf8, iconv_to);
utf8, iconv_to, error->code, error->message);
g_error_free (error);
}
return FALSE; return FALSE;
} }
@@ -144,7 +141,6 @@ mm_modem_charset_byte_array_append (GByteArray *array,
if (quoted) if (quoted)
g_byte_array_append (array, (const guint8 *) "\"", 1); g_byte_array_append (array, (const guint8 *) "\"", 1);
g_free (converted);
return TRUE; return TRUE;
} }

View File

@@ -38,10 +38,11 @@ MMModemCharset mm_modem_charset_from_string (const char *string);
* into the given charset first. The original string is assumed to be * into the given charset first. The original string is assumed to be
* UTF-8 encoded. * UTF-8 encoded.
*/ */
gboolean mm_modem_charset_byte_array_append (GByteArray *array, gboolean mm_modem_charset_byte_array_append (GByteArray *array,
const char *utf8, const gchar *utf8,
gboolean quoted, gboolean quoted,
MMModemCharset charset); MMModemCharset charset,
GError **error);
/* Take a string encoded in the given charset in binary form, and /* Take a string encoded in the given charset in binary form, and
* convert it to UTF-8. */ * convert it to UTF-8. */

View File

@@ -1013,16 +1013,16 @@ mm_sms_part_3gpp_get_submit_pdu (MMSmsPart *part,
g_free (packed); g_free (packed);
offset += packlen; offset += packlen;
} else if (mm_sms_part_get_encoding (part) == MM_SMS_ENCODING_UCS2) { } else if (mm_sms_part_get_encoding (part) == MM_SMS_ENCODING_UCS2) {
GByteArray *array; g_autoptr(GByteArray) array = NULL;
g_autoptr(GError) inner_error = NULL;
/* Try to guess a good value for the array */ /* Try to guess a good value for the array */
array = g_byte_array_sized_new (strlen (mm_sms_part_get_text (part)) * 2); array = g_byte_array_sized_new (strlen (mm_sms_part_get_text (part)) * 2);
if (!mm_modem_charset_byte_array_append (array, mm_sms_part_get_text (part), FALSE, MM_MODEM_CHARSET_UCS2)) { if (!mm_modem_charset_byte_array_append (array, mm_sms_part_get_text (part), FALSE, MM_MODEM_CHARSET_UCS2, &inner_error)) {
g_byte_array_free (array, TRUE); g_set_error (error,
g_set_error_literal (error, MM_MESSAGE_ERROR,
MM_MESSAGE_ERROR, MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER,
MM_MESSAGE_ERROR_INVALID_PDU_PARAMETER, "Failed to convert message text to UCS2: %s", inner_error->message);
"Failed to convert message text to UCS2");
goto error; goto error;
} }
@@ -1031,12 +1031,11 @@ mm_sms_part_3gpp_get_submit_pdu (MMSmsPart *part,
*/ */
*udl_ptr = mm_sms_part_get_concat_sequence (part) ? (6 + array->len) : array->len; *udl_ptr = mm_sms_part_get_concat_sequence (part) ? (6 + array->len) : array->len;
mm_obj_dbg (log_object, " user data length is %u octets (%s UDH)", mm_obj_dbg (log_object, " user data length is %u octets (%s UDH)",
*udl_ptr, *udl_ptr,
mm_sms_part_get_concat_sequence (part) ? "with" : "without"); mm_sms_part_get_concat_sequence (part) ? "with" : "without");
memcpy (&pdu[offset], array->data, array->len); memcpy (&pdu[offset], array->data, array->len);
offset += array->len; offset += array->len;
g_byte_array_free (array, TRUE);
} else if (mm_sms_part_get_encoding (part) == MM_SMS_ENCODING_8BIT) { } else if (mm_sms_part_get_encoding (part) == MM_SMS_ENCODING_8BIT) {
const GByteArray *data; const GByteArray *data;
@@ -1102,7 +1101,8 @@ mm_sms_part_3gpp_util_split_text (const gchar *text,
/* Check if we can do GSM encoding */ /* Check if we can do GSM encoding */
if (!mm_charset_can_convert_to (text, MM_MODEM_CHARSET_GSM)) { if (!mm_charset_can_convert_to (text, MM_MODEM_CHARSET_GSM)) {
/* If cannot do it in GSM encoding, do it in UCS-2 */ /* If cannot do it in GSM encoding, do it in UCS-2 */
GByteArray *array; g_autoptr(GByteArray) array = NULL;
g_autoptr(GError) error = NULL;
*encoding = MM_SMS_ENCODING_UCS2; *encoding = MM_SMS_ENCODING_UCS2;
@@ -1112,8 +1112,9 @@ mm_sms_part_3gpp_util_split_text (const gchar *text,
if (!mm_modem_charset_byte_array_append (array, if (!mm_modem_charset_byte_array_append (array,
text, text,
FALSE, FALSE,
MM_MODEM_CHARSET_UCS2)) { MM_MODEM_CHARSET_UCS2,
g_byte_array_unref (array); &error)) {
mm_obj_warn (log_object, "failed to append UCS2: %s", error->message);
return NULL; return NULL;
} }
@@ -1145,7 +1146,6 @@ mm_sms_part_3gpp_util_split_text (const gchar *text,
log_object); log_object);
} }
} }
g_byte_array_unref (array);
} else { } else {
/* Do it with GSM encoding */ /* Do it with GSM encoding */
*encoding = MM_SMS_ENCODING_GSM7; *encoding = MM_SMS_ENCODING_GSM7;

View File

@@ -1377,14 +1377,16 @@ write_bearer_data_message_identifier (MMSmsPart *part,
static void static void
decide_best_encoding (const gchar *text, decide_best_encoding (const gchar *text,
gpointer log_object,
GByteArray **out, GByteArray **out,
guint *num_fields, guint *num_fields,
guint *num_bits_per_field, guint *num_bits_per_field,
Encoding *encoding) Encoding *encoding)
{ {
guint ascii_unsupported = 0; guint ascii_unsupported = 0;
guint i; guint i;
guint len; guint len;
g_autoptr(GError) error = NULL;
len = strlen (text); len = strlen (text);
@@ -1409,10 +1411,12 @@ decide_best_encoding (const gchar *text,
/* Check if we can do Latin encoding */ /* Check if we can do Latin encoding */
if (mm_charset_can_convert_to (text, MM_MODEM_CHARSET_8859_1)) { if (mm_charset_can_convert_to (text, MM_MODEM_CHARSET_8859_1)) {
*out = g_byte_array_sized_new (len); *out = g_byte_array_sized_new (len);
mm_modem_charset_byte_array_append (*out, if (!mm_modem_charset_byte_array_append (*out,
text, text,
FALSE, FALSE,
MM_MODEM_CHARSET_8859_1); MM_MODEM_CHARSET_8859_1,
&error))
mm_obj_warn (log_object, "failed to convert to latin encoding: %s", error->message);
*num_fields = (*out)->len; *num_fields = (*out)->len;
*num_bits_per_field = 8; *num_bits_per_field = 8;
*encoding = ENCODING_LATIN; *encoding = ENCODING_LATIN;
@@ -1421,10 +1425,12 @@ decide_best_encoding (const gchar *text,
/* If no Latin and no ASCII, default to UTF-16 */ /* If no Latin and no ASCII, default to UTF-16 */
*out = g_byte_array_sized_new (len * 2); *out = g_byte_array_sized_new (len * 2);
mm_modem_charset_byte_array_append (*out, if (!mm_modem_charset_byte_array_append (*out,
text, text,
FALSE, FALSE,
MM_MODEM_CHARSET_UCS2); MM_MODEM_CHARSET_UCS2,
&error))
mm_obj_warn (log_object, "failed to convert to UTF-16 encoding: %s", error->message);
*num_fields = (*out)->len / 2; *num_fields = (*out)->len / 2;
*num_bits_per_field = 16; *num_bits_per_field = 16;
*encoding = ENCODING_UNICODE; *encoding = ENCODING_UNICODE;
@@ -1472,6 +1478,7 @@ write_bearer_data_user_data (MMSmsPart *part,
/* Text or Data */ /* Text or Data */
if (text) { if (text) {
decide_best_encoding (text, decide_best_encoding (text,
log_object,
&converted, &converted,
&num_fields, &num_fields,
&num_bits_per_field, &num_bits_per_field,