Replace gsm_sms_char_ascii_decode() with gsm_sms_chars_to_utf8(), which
authorGuy Harris <guy@alum.mit.edu>
Mon, 28 Dec 2009 21:58:43 +0000 (21:58 -0000)
committerGuy Harris <guy@alum.mit.edu>
Mon, 28 Dec 2009 21:58:43 +0000 (21:58 -0000)
returns an ep_allocated string (and whose name reflects that what you
get out is UTF-8, not just ASCII).

svn path=/trunk/; revision=31376

asn1/gsm_map/gsm_map.cnf
epan/dissectors/packet-gsm_a_dtap.c
epan/dissectors/packet-gsm_map.c
epan/dissectors/packet-gsm_sms.c
epan/dissectors/packet-gsm_sms.h

index 8b4f45173c3d64e8e03f6e2df2c48613bd4301c6..232c96ff75b881713d7e80686d2f57fd36b28e52 100644 (file)
@@ -418,10 +418,8 @@ actx->pinfo->p2p_dir = P2P_DIR_RECV;
   guint8               out_len;
   /* XXX - The maximum item label length is 240.  Does this really need to be 1024? 
    * use ep_alloc ?
-   * We need a input and an output buffer to gsm_sms_char_ascii_decode()
    */
   static unsigned char msgbuf[1024];
-  static unsigned char outbuf[1024];
   gchar *utf8_text = NULL;
   GIConv cd;   
   GError *l_conv_error = NULL;
@@ -439,9 +437,8 @@ actx->pinfo->p2p_dir = P2P_DIR_RECV;
                                                       msgbuf);
 
        msgbuf[out_len] = '\0';
-       gsm_sms_char_ascii_decode(outbuf, msgbuf, out_len);
-       msgbuf[1023] = '\0';
-       proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %%s", outbuf);
+       utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len);
+       proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %%s", utf8_text);
        break;
     case SMS_ENCODING_8BIT:
        proto_tree_add_text(tree, parameter_tvb , 0, length, "USSD String: %%s", tvb_get_ptr(parameter_tvb, 0, length));
index 61f0f67fa7909fceb14bfeae10d3b746eeb8ec01..0e8f3ae93fc57cc7f14d83d3f2fc520dbb968564 100644 (file)
@@ -726,23 +726,7 @@ de_network_name(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint len, gcha
                if (num_spare_bits == 7)
                        num_chars--;
                a_bigbuf[num_chars] = '\0';
-               /*
-                * The documentation for g_unichar_to_utf8() says that
-                * the output buffer "must have at least 6 bytes of space".
-                * I think that maximum is for some Korean characters, so
-                * perhaps that's overkill here, but there are at least
-                * some SMS characters whose UTF-8 encoding takes 3
-                * bytes.  We'll be safe and allocate 6 bytes.
-                *
-                * XXX - we could have a routine that takes a string of
-                * SMS characters and returns an ep_allocated UTF-8
-                * string.  g_unichar_to_utf8(), if passed a null
-                * buffer pointer, just returns the number of bytes
-                * required, so we could get the right buffer size
-                * by making two passes over the SMS string.
-                */
-               net_name = ep_alloc(6 * num_chars);
-               gsm_sms_char_ascii_decode(net_name, a_bigbuf, num_chars);
+               net_name = gsm_sms_chars_to_utf8(a_bigbuf, num_chars);
                proto_tree_add_text(tree, tvb , curr_offset, len - 1, "Text String: %s", net_name);
                break;
        case 1:
index 26cf5992ed326b05dabfda508e9937b92236f86e..661f92ee754055b64efe78b46262daa2b731f962 100644 (file)
@@ -2916,7 +2916,7 @@ static const ber_sequence_t gsm_map_ExternalSignalInfo_sequence[] = {
 
 static int
 dissect_gsm_map_ExternalSignalInfo(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 704 "gsm_map.cnf"
+#line 701 "gsm_map.cnf"
 /*
 -- Information about the internal structure is given in
 -- clause 7.6.9.
@@ -3242,7 +3242,7 @@ dissect_gsm_map_HLR_List(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offse
 
 int
 dissect_gsm_map_GlobalCellId(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 785 "gsm_map.cnf"
+#line 782 "gsm_map.cnf"
     tvbuff_t   *parameter_tvb; 
        proto_tree      *subtree;
 
@@ -3509,7 +3509,7 @@ dissect_gsm_map_CellGlobalIdOrServiceAreaIdFixedLength(gboolean implicit_tag _U_
 
 int
 dissect_gsm_map_LAIFixedLength(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 564 "gsm_map.cnf"
+#line 561 "gsm_map.cnf"
 
         tvbuff_t        *parameter_tvb; 
         proto_tree *subtree; 
@@ -3792,7 +3792,7 @@ dissect_gsm_map_ss_ForwardingOptions(gboolean implicit_tag _U_, tvbuff_t *tvb _U
   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
                                        NULL);
 
-#line 471 "gsm_map.cnf"
+#line 468 "gsm_map.cnf"
 
        proto_tree_add_item(tree, hf_gsm_map_notification_to_forwarding_party, tvb, 0,1,FALSE);
        proto_tree_add_item(tree, hf_gsm_map_redirecting_presentation, tvb, 0,1,FALSE);
@@ -4144,10 +4144,8 @@ dissect_gsm_map_ss_USSD_String(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int
   guint8               out_len;
   /* XXX - The maximum item label length is 240.  Does this really need to be 1024? 
    * use ep_alloc ?
-   * We need a input and an output buffer to gsm_sms_char_ascii_decode()
    */
   static unsigned char msgbuf[1024];
-  static unsigned char outbuf[1024];
   gchar *utf8_text = NULL;
   GIConv cd;   
   GError *l_conv_error = NULL;
@@ -4167,9 +4165,8 @@ dissect_gsm_map_ss_USSD_String(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int
                                                       msgbuf);
 
        msgbuf[out_len] = '\0';
-       gsm_sms_char_ascii_decode(outbuf, msgbuf, out_len);
-       msgbuf[1023] = '\0';
-       proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %s", outbuf);
+       utf8_text = gsm_sms_chars_to_utf8(msgbuf, out_len);
+       proto_tree_add_text(tree, parameter_tvb, 0, length, "USSD String: %s", utf8_text);
        break;
     case SMS_ENCODING_8BIT:
        proto_tree_add_text(tree, parameter_tvb , 0, length, "USSD String: %s", tvb_get_ptr(parameter_tvb, 0, length));
@@ -6495,7 +6492,7 @@ dissect_gsm_map_ms_VLR_Capability(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
 
 int
 dissect_gsm_map_ms_GSN_Address(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 528 "gsm_map.cnf"
+#line 525 "gsm_map.cnf"
 
        tvbuff_t        *parameter_tvb;
        guint8          octet;
@@ -7351,7 +7348,7 @@ dissect_gsm_map_ms_UpdateGprsLocationRes(gboolean implicit_tag _U_, tvbuff_t *tv
 
 static int
 dissect_gsm_map_ms_IntegrityProtectionInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 600 "gsm_map.cnf"
+#line 597 "gsm_map.cnf"
     tvbuff_t        *parameter_tvb;
        asn1_ctx_t              asn1_ctx;
 
@@ -7374,7 +7371,7 @@ dissect_gsm_map_ms_IntegrityProtectionInformation(gboolean implicit_tag _U_, tvb
 
 static int
 dissect_gsm_map_ms_EncryptionInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 612 "gsm_map.cnf"
+#line 609 "gsm_map.cnf"
     tvbuff_t        *parameter_tvb;
        asn1_ctx_t              asn1_ctx;
 
@@ -7459,7 +7456,7 @@ dissect_gsm_map_ms_AllowedUMTS_Algorithms(gboolean implicit_tag _U_, tvbuff_t *t
 
 static int
 dissect_gsm_map_ms_RadioResourceInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 576 "gsm_map.cnf"
+#line 573 "gsm_map.cnf"
     tvbuff_t        *parameter_tvb; 
        proto_tree *subtree;
 
@@ -7530,7 +7527,7 @@ dissect_gsm_map_ms_BSSMAP_ServiceHandover(gboolean implicit_tag _U_, tvbuff_t *t
 
 static int
 dissect_gsm_map_ms_RANAP_ServiceHandover(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 588 "gsm_map.cnf"
+#line 585 "gsm_map.cnf"
     tvbuff_t        *parameter_tvb;
        asn1_ctx_t              asn1_ctx;
 
@@ -8310,7 +8307,7 @@ static int
 dissect_gsm_map_ms_T_forwardingOptions(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
   offset = dissect_gsm_map_ms_Ext_ForwOptions(implicit_tag, tvb, offset, actx, tree, hf_index);
 
-#line 477 "gsm_map.cnf"
+#line 474 "gsm_map.cnf"
 
        proto_tree_add_item(tree, hf_gsm_map_notification_to_forwarding_party, tvb, 0,1,FALSE);
        proto_tree_add_item(tree, hf_gsm_map_redirecting_presentation, tvb, 0,1,FALSE);
@@ -9496,7 +9493,7 @@ dissect_gsm_map_ms_VlrCamelSubscriptionInfo(gboolean implicit_tag _U_, tvbuff_t
 
 static int
 dissect_gsm_map_ms_PDP_Type(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 485 "gsm_map.cnf"
+#line 482 "gsm_map.cnf"
        guint8 pdp_type_org;
        tvbuff_t        *parameter_tvb;
 
@@ -9529,7 +9526,7 @@ dissect_gsm_map_ms_PDP_Type(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int of
 
 int
 dissect_gsm_map_ms_QoS_Subscribed(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 507 "gsm_map.cnf"
+#line 504 "gsm_map.cnf"
 
 
        tvbuff_t        *parameter_tvb;
@@ -9551,7 +9548,7 @@ dissect_gsm_map_ms_QoS_Subscribed(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
 
 int
 dissect_gsm_map_ms_Ext_QoS_Subscribed(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 518 "gsm_map.cnf"
+#line 515 "gsm_map.cnf"
 
        tvbuff_t        *parameter_tvb;
 
@@ -11019,7 +11016,7 @@ dissect_gsm_map_ms_SubscriberState(gboolean implicit_tag _U_, tvbuff_t *tvb _U_,
 
 int
 dissect_gsm_map_ms_RAIdentity(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 552 "gsm_map.cnf"
+#line 549 "gsm_map.cnf"
 
        tvbuff_t        *parameter_tvb;
        proto_tree *subtree;
@@ -13334,7 +13331,7 @@ dissect_gsm_map_lcs_ProvideSubscriberLocation_Arg(gboolean implicit_tag _U_, tvb
 
 int
 dissect_gsm_map_lcs_Ext_GeographicalInformation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 797 "gsm_map.cnf"
+#line 794 "gsm_map.cnf"
     tvbuff_t   *parameter_tvb; 
        proto_tree      *subtree;
 
@@ -14680,7 +14677,7 @@ static const ber_sequence_t gsm_old_Bss_APDU_sequence[] = {
 
 static int
 dissect_gsm_old_Bss_APDU(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
-#line 625 "gsm_map.cnf"
+#line 622 "gsm_map.cnf"
  guint8                octet;
  guint8                length;
  tvbuff_t      *next_tvb;
index 4fd2b0cf82003abd28cbc7ee4bb17cf42874aba5..150d093a050e8cd3cae3073e95392fbc4fcc6c9b 100644 (file)
@@ -337,6 +337,7 @@ dis_field_addr(tvbuff_t *tvb, proto_tree *tree, guint32 *offset_p, const gchar *
     guint32            length;
     guint32            i, j;
     char                addrbuf[MAX_ADDR_SIZE+1];
+    gchar               *addrstr;
 
     offset = *offset_p;
 
@@ -429,37 +430,38 @@ dis_field_addr(tvbuff_t *tvb, proto_tree *tree, guint32 *offset_p, const gchar *
     case 0x05: /* "Alphanumeric (coded according to 3GPP TS 23.038 GSM 7-bit default alphabet)" */
        i = gsm_sms_char_7bit_unpack(0, numdigocts, MAX_ADDR_SIZE, tvb_get_ptr(tvb, offset, numdigocts), addrbuf);
        addrbuf[i] = '\0';
-       gsm_sms_char_ascii_decode(bigbuf, addrbuf, i);
+       addrstr = gsm_sms_chars_to_utf8(addrbuf, i);
        break;
     default:
+       addrstr = ep_alloc(numdigocts*2 + 1);
        for (i = 0; i < numdigocts; i++)
        {
            oct = tvb_get_guint8(tvb, offset + i);
 
-           bigbuf[j++] = digit_table[oct & 0x0f];
-           bigbuf[j++] = digit_table[(oct & 0xf0) >> 4];
+           addrstr[j++] = digit_table[oct & 0x0f];
+           addrstr[j++] = digit_table[(oct & 0xf0) >> 4];
        }
-       bigbuf[j++] = '\0';
+       addrstr[j++] = '\0';
        break;
     }
 
     if (g_ascii_strncasecmp(title, "TP-O", 4) == 0) {
        proto_tree_add_string(subtree, hf_gsm_sms_tp_oa, tvb,
-               offset, numdigocts, bigbuf);
+               offset, numdigocts, addrstr);
     } else if (g_ascii_strncasecmp(title, "TP-D", 4) == 0) {
        proto_tree_add_string(subtree, hf_gsm_sms_tp_da, tvb,
-               offset, numdigocts, bigbuf);
+               offset, numdigocts, addrstr);
     } else if (g_ascii_strncasecmp(title, "TP-R", 4) == 0) {
        proto_tree_add_string(subtree, hf_gsm_sms_tp_ra, tvb,
-               offset, numdigocts, bigbuf);
+               offset, numdigocts, addrstr);
     } else {
        proto_tree_add_text(subtree,
        tvb, offset, numdigocts,
        "Digits: %s",
-       bigbuf);
+       addrstr);
     }
 
-    proto_item_append_text(item, " - (%s)", bigbuf);
+    proto_item_append_text(item, " - (%s)", addrstr);
 
     *offset_p = offset + numdigocts;
 }
@@ -1637,26 +1639,45 @@ char_def_alphabet_decode(unsigned char value)
     }
 }
 
-void
-gsm_sms_char_ascii_decode(unsigned char * dest, const unsigned char* src, int len)
+gchar *
+gsm_sms_chars_to_utf8(const unsigned char* src, int len)
 {
-    int i, j;
-    gunichar buf;
+    gint outlen, i, j;
+    gunichar c;
+    gchar *outbuf;
 
+    /* Scan the input string to see how long the output string will be */
+    for (outlen = 0, j = 0; j < len;  j++)
+    {
+       if (char_is_escape(src[j])) {
+           j++;
+           if (j == len)
+               c = '?';        /* escape with nothing following it - error */
+           else
+               c = char_def_alphabet_ext_decode(src[j]);
+       }
+       else
+           c = char_def_alphabet_decode(src[j]);
+        outlen += g_unichar_to_utf8(c,NULL);
+    }
 
+    /* Now allocate a buffer for the output string and fill it in */
+    outbuf = ep_alloc(outlen + 1);
     for (i = 0, j = 0; j < len;  j++)
     {
        if (char_is_escape(src[j])) {
-           buf = char_def_alphabet_ext_decode(src[++j]);
-           i += g_unichar_to_utf8(buf,&(dest[i]));
-       }
-       else {
-           buf = char_def_alphabet_decode(src[j]);
-           i += g_unichar_to_utf8(buf,&(dest[i]));
+           j++;
+           if (j == len)
+               c = '?';        /* escape with nothing following it - error */
+           else
+               c = char_def_alphabet_ext_decode(src[j]);
        }
+       else
+           c = char_def_alphabet_decode(src[j]);
+        i += g_unichar_to_utf8(c,&(outbuf[i]));
     }
-    dest[i]=0;
-    return;
+    outbuf[i] = '\0';
+    return outbuf;
 }
 
 /*
@@ -2649,8 +2670,8 @@ dis_field_ud(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, gb
                                        gsm_sms_char_7bit_unpack(fill_bits, length , SMS_MAX_MESSAGE_SIZE,
                                        tvb_get_ptr(tvb , offset , length) , messagebuf);
                                        messagebuf[out_len] = '\0';
-                                       gsm_sms_char_ascii_decode(bigbuf, messagebuf, out_len);
-                                       proto_tree_add_text(subtree, tvb , offset , length , "%s", bigbuf);
+                                       proto_tree_add_text(subtree, tvb , offset , length , "%s",
+                                           gsm_sms_chars_to_utf8(messagebuf, out_len));
                                }
                                else
                                {
@@ -2672,8 +2693,8 @@ dis_field_ud(tvbuff_t *tvb, proto_tree *tree, guint32 offset, guint32 length, gb
                                                tvb_get_ptr(sm_tvb , i * MAX_SMS_FRAG_LEN  , len_sms) , messagebuf);
                                                
                                                messagebuf[out_len] = '\0';
-                                               gsm_sms_char_ascii_decode(bigbuf, messagebuf, out_len);
-                                               proto_tree_add_text(subtree, sm_tvb , i * MAX_SMS_FRAG_LEN , len_sms , "%s", bigbuf);
+                                               proto_tree_add_text(subtree, sm_tvb , i * MAX_SMS_FRAG_LEN , len_sms , "%s",
+                                                   gsm_sms_chars_to_utf8(messagebuf, out_len));
                                        }
                                }
                        }
index 33c67372150de10561740794609469f37c1ad43b..1186b29dcc2476786f9ac1fc81ef0c26ca5ecc3b 100644 (file)
 
 extern int gsm_sms_char_7bit_unpack(unsigned int offset, unsigned int in_length, unsigned int out_length,
                     const guint8 *input, unsigned char *output);
-extern void gsm_sms_char_ascii_decode(unsigned char* dest, const unsigned char* src, int len);
+
+/* Convert an unpacked SMS string to UTF-8.
+ *
+ * @param src The string to convert.
+ * @param len Length of the string to convert, in bytes.
+ * @return An ep_allocated UTF-8 string.
+ */
+
+extern gchar *gsm_sms_chars_to_utf8(const unsigned char* src, int len);