From me via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7709
[metze/wireshark/wip.git] / epan / strutil.c
1 /* strutil.c
2  * String utility routines
3  *
4  * $Id$
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 2
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 # include "config.h"
27 #endif
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <ctype.h>
32 #include <glib.h>
33 #include "strutil.h"
34 #include "emem.h"
35 #include <../isprint.h>
36
37
38 #ifdef _WIN32
39 #include <windows.h>
40 #include <tchar.h>
41 #include <wchar.h>
42 #endif
43
44 static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
45                               '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
46
47 /*
48  * Given a pointer into a data buffer, and to the end of the buffer,
49  * find the end of the (putative) line at that position in the data
50  * buffer.
51  * Return a pointer to the EOL character(s) in "*eol".
52  */
53 const guchar *
54 find_line_end(const guchar *data, const guchar *dataend, const guchar **eol)
55 {
56   const guchar *lineend;
57
58   lineend = memchr(data, '\n', dataend - data);
59   if (lineend == NULL) {
60     /*
61      * No LF - line is probably continued in next TCP segment.
62      */
63     lineend = dataend;
64     *eol = dataend;
65   } else {
66     /*
67      * Is the LF at the beginning of the line?
68      */
69     if (lineend > data) {
70       /*
71        * No - is it preceded by a carriage return?
72        * (Perhaps it's supposed to be, but that's not guaranteed....)
73        */
74       if (*(lineend - 1) == '\r') {
75         /*
76          * Yes.  The EOL starts with the CR.
77          */
78         *eol = lineend - 1;
79       } else {
80         /*
81          * No.  The EOL starts with the LF.
82          */
83         *eol = lineend;
84
85         /*
86          * I seem to remember that we once saw lines ending with LF-CR
87          * in an HTTP request or response, so check if it's *followed*
88          * by a carriage return.
89          */
90         if (lineend < (dataend - 1) && *(lineend + 1) == '\r') {
91           /*
92            * It's <non-LF><LF><CR>; say it ends with the CR.
93            */
94           lineend++;
95         }
96       }
97     } else {
98       /*
99        * Yes - the EOL starts with the LF.
100        */
101       *eol = lineend;
102     }
103
104     /*
105      * Point to the character after the last character.
106      */
107     lineend++;
108   }
109   return lineend;
110 }
111
112 /*
113  * Get the length of the next token in a line, and the beginning of the
114  * next token after that (if any).
115  * Return 0 if there is no next token.
116  */
117 int
118 get_token_len(const guchar *linep, const guchar *lineend,
119               const guchar **next_token)
120 {
121   const guchar *tokenp;
122   int token_len;
123
124   tokenp = linep;
125
126   /*
127    * Search for a blank, a CR or an LF, or the end of the buffer.
128    */
129   while (linep < lineend && *linep != ' ' && *linep != '\r' && *linep != '\n')
130       linep++;
131   token_len = (int) (linep - tokenp);
132
133   /*
134    * Skip trailing blanks.
135    */
136   while (linep < lineend && *linep == ' ')
137     linep++;
138
139   *next_token = linep;
140
141   return token_len;
142 }
143
144
145 #define INITIAL_FMTBUF_SIZE     128
146
147 /*
148  * Given a string, generate a string from it that shows non-printable
149  * characters as C-style escapes, and return a pointer to it.
150  */
151 gchar *
152 format_text(const guchar *string, size_t len)
153 {
154   static gchar *fmtbuf[3];
155   static int fmtbuf_len[3];
156   static int idx;
157   int column;
158   const guchar *stringend = string + len;
159   guchar c;
160   int i;
161
162   idx = (idx + 1) % 3;
163
164   /*
165    * Allocate the buffer if it's not already allocated.
166    */
167   if (fmtbuf[idx] == NULL) {
168     fmtbuf[idx] = g_malloc(INITIAL_FMTBUF_SIZE);
169     fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
170   }
171   column = 0;
172   while (string < stringend) {
173     /*
174      * Is there enough room for this character, if it expands to
175      * a backslash plus 3 octal digits (which is the most it can
176      * expand to), and also enough room for a terminating '\0'?
177      */
178     if (column+3+1 >= fmtbuf_len[idx]) {
179       /*
180        * Double the buffer's size if it's not big enough.
181        * The size of the buffer starts at 128, so doubling its size
182        * adds at least another 128 bytes, which is more than enough
183        * for one more character plus a terminating '\0'.
184        */
185       fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
186       fmtbuf[idx] = g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
187     }
188     c = *string++;
189
190     if (isprint(c)) {
191       fmtbuf[idx][column] = c;
192       column++;
193     } else {
194       fmtbuf[idx][column] =  '\\';
195       column++;
196       switch (c) {
197
198       case '\a':
199         fmtbuf[idx][column] = 'a';
200         column++;
201         break;
202
203       case '\b':
204         fmtbuf[idx][column] = 'b'; /* BS */
205         column++;
206         break;
207
208       case '\f':
209         fmtbuf[idx][column] = 'f'; /* FF */
210         column++;
211         break;
212
213       case '\n':
214         fmtbuf[idx][column] = 'n'; /* NL */
215         column++;
216         break;
217
218       case '\r':
219         fmtbuf[idx][column] = 'r'; /* CR */
220         column++;
221         break;
222
223       case '\t':
224         fmtbuf[idx][column] = 't'; /* tab */
225         column++;
226         break;
227
228       case '\v':
229         fmtbuf[idx][column] = 'v';
230         column++;
231         break;
232
233       default:
234         i = (c>>6)&03;
235         fmtbuf[idx][column] = i + '0';
236         column++;
237         i = (c>>3)&07;
238         fmtbuf[idx][column] = i + '0';
239         column++;
240         i = (c>>0)&07;
241         fmtbuf[idx][column] = i + '0';
242         column++;
243         break;
244       }
245     }
246   }
247   fmtbuf[idx][column] = '\0';
248   return fmtbuf[idx];
249 }
250
251 /*
252  * Given a string, generate a string from it that shows non-printable
253  * characters as C-style escapes except a whitespace character
254  * (space, tab, carriage return, new line, vertical tab, or formfeed)
255  * which will be replaced by a space, and return a pointer to it.
256  */
257 gchar *
258 format_text_wsp(const guchar *string, size_t len)
259 {
260   static gchar *fmtbuf[3];
261   static int fmtbuf_len[3];
262   static int idx;
263   int column;
264   const guchar *stringend = string + len;
265   guchar c;
266   int i;
267
268   idx = (idx + 1) % 3;
269
270   /*
271    * Allocate the buffer if it's not already allocated.
272    */
273   if (fmtbuf[idx] == NULL) {
274     fmtbuf[idx] = g_malloc(INITIAL_FMTBUF_SIZE);
275     fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
276   }
277   column = 0;
278   while (string < stringend) {
279     /*
280      * Is there enough room for this character, if it expands to
281      * a backslash plus 3 octal digits (which is the most it can
282      * expand to), and also enough room for a terminating '\0'?
283      */
284     if (column+3+1 >= fmtbuf_len[idx]) {
285       /*
286        * Double the buffer's size if it's not big enough.
287        * The size of the buffer starts at 128, so doubling its size
288        * adds at least another 128 bytes, which is more than enough
289        * for one more character plus a terminating '\0'.
290        */
291       fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
292       fmtbuf[idx] = g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
293     }
294     c = *string++;
295
296     if (isprint(c)) {
297       fmtbuf[idx][column] = c;
298       column++;
299     } else if  (isspace(c)) {
300       fmtbuf[idx][column] = ' ';
301       column++;
302     } else {
303       fmtbuf[idx][column] =  '\\';
304       column++;
305       switch (c) {
306
307       case '\a':
308         fmtbuf[idx][column] = 'a';
309         column++;
310         break;
311
312       case '\b':
313         fmtbuf[idx][column] = 'b'; /* BS */
314         column++;
315         break;
316
317       case '\f':
318         fmtbuf[idx][column] = 'f'; /* FF */
319         column++;
320         break;
321
322       case '\n':
323         fmtbuf[idx][column] = 'n'; /* NL */
324         column++;
325         break;
326
327       case '\r':
328         fmtbuf[idx][column] = 'r'; /* CR */
329         column++;
330         break;
331
332       case '\t':
333         fmtbuf[idx][column] = 't'; /* tab */
334         column++;
335         break;
336
337       case '\v':
338         fmtbuf[idx][column] = 'v';
339         column++;
340         break;
341
342       default:
343         i = (c>>6)&03;
344         fmtbuf[idx][column] = i + '0';
345         column++;
346         i = (c>>3)&07;
347         fmtbuf[idx][column] = i + '0';
348         column++;
349         i = (c>>0)&07;
350         fmtbuf[idx][column] = i + '0';
351         column++;
352         break;
353       }
354     }
355   }
356   fmtbuf[idx][column] = '\0';
357   return fmtbuf[idx];
358 }
359
360 static gboolean
361 is_byte_sep(guint8 c)
362 {
363         return (c == '-' || c == ':' || c == '.');
364 }
365
366 /* Turn a string of hex digits with optional separators (defined by
367  * is_byte_sep() into a byte array.
368  */
369 gboolean
370 hex_str_to_bytes(const char *hex_str, GByteArray *bytes, gboolean force_separators) {
371         guint8          val;
372         const guchar    *p, *q, *r, *s, *punct;
373         char            four_digits_first_half[3];
374         char            four_digits_second_half[3];
375         char            two_digits[3];
376         char            one_digit[2];
377
378         if (! hex_str || ! bytes) {
379                 return FALSE;
380         }
381         g_byte_array_set_size(bytes, 0);
382         p = (const guchar *)hex_str;
383         while (*p) {
384                 q = p+1;
385                 r = p+2;
386                 s = p+3;
387
388                 if (*q && *r && *s
389                     && isxdigit(*p) && isxdigit(*q) &&
390                     isxdigit(*r) && isxdigit(*s)) {
391                         four_digits_first_half[0] = *p;
392                         four_digits_first_half[1] = *q;
393                         four_digits_first_half[2] = '\0';
394                         four_digits_second_half[0] = *r;
395                         four_digits_second_half[1] = *s;
396                         four_digits_second_half[2] = '\0';
397
398                         /*
399                          * Four or more hex digits in a row.
400                          */
401                         val = (guint8) strtoul(four_digits_first_half, NULL, 16);
402                         g_byte_array_append(bytes, &val, 1);
403                         val = (guint8) strtoul(four_digits_second_half, NULL, 16);
404                         g_byte_array_append(bytes, &val, 1);
405
406                         punct = s + 1;
407                         if (*punct) {
408                                 /*
409                                  * Make sure the character after
410                                  * the forth hex digit is a byte
411                                  * separator, i.e. that we don't have
412                                  * more than four hex digits, or a
413                                  * bogus character.
414                                  */
415                                 if (is_byte_sep(*punct)) {
416                                         p = punct + 1;
417                                         continue;
418                                 }
419                                 else if (force_separators) {
420                                         return FALSE;
421                                 }
422                         }
423                         p = punct;
424                         continue;
425                 }
426
427                 else if (*q && isxdigit(*p) && isxdigit(*q)) {
428                         two_digits[0] = *p;
429                         two_digits[1] = *q;
430                         two_digits[2] = '\0';
431
432                         /*
433                          * Two hex digits in a row.
434                          */
435                         val = (guint8) strtoul(two_digits, NULL, 16);
436                         g_byte_array_append(bytes, &val, 1);
437                         punct = q + 1;
438                         if (*punct) {
439                                 /*
440                                  * Make sure the character after
441                                  * the second hex digit is a byte
442                                  * separator, i.e. that we don't have
443                                  * more than two hex digits, or a
444                                  * bogus character.
445                                  */
446                                 if (is_byte_sep(*punct)) {
447                                         p = punct + 1;
448                                         continue;
449                                 }
450                                 else if (force_separators) {
451                                         return FALSE;
452                                 }
453                         }
454                         p = punct;
455                         continue;
456                 }
457                 else if (*q && isxdigit(*p) && is_byte_sep(*q)) {
458                         one_digit[0] = *p;
459                         one_digit[1] = '\0';
460
461                         /*
462                          * Only one hex digit (not at the end of the string)
463                          */
464                         val = (guint8) strtoul(one_digit, NULL, 16);
465                         g_byte_array_append(bytes, &val, 1);
466                         p = q + 1;
467                         continue;
468                 }
469                 else if (!*q && isxdigit(*p)) {
470                         one_digit[0] = *p;
471                         one_digit[1] = '\0';
472
473                         /*
474                          * Only one hex digit (at the end of the string)
475                          */
476                         val = (guint8) strtoul(one_digit, NULL, 16);
477                         g_byte_array_append(bytes, &val, 1);
478                         p = q;
479                         continue;
480                 }
481                 else {
482                         return FALSE;
483                 }
484         }
485         return TRUE;
486 }
487
488 /*
489  * Turn an RFC 3986 percent-encoded string into a byte array.
490  * XXX - We don't check for reserved characters.
491  */
492 #define HEX_DIGIT_BUF_LEN 3
493 gboolean
494 uri_str_to_bytes(const char *uri_str, GByteArray *bytes) {
495         guint8          val;
496         const guchar    *p;
497         guchar          hex_digit[HEX_DIGIT_BUF_LEN];
498
499         g_byte_array_set_size(bytes, 0);
500         if (! uri_str) {
501                 return FALSE;
502         }
503
504         p = (const guchar *)uri_str;
505
506         while (*p) {
507                 if (! isascii(*p) || ! isprint(*p))
508                         return FALSE;
509                 if (*p == '%') {
510                         p++;
511                         if (*p == '\0') return FALSE;
512                         hex_digit[0] = *p;
513                         p++;
514                         if (*p == '\0') return FALSE;
515                         hex_digit[1] = *p;
516                         hex_digit[2] = '\0';
517                         if (! isxdigit(hex_digit[0]) || ! isxdigit(hex_digit[1]))
518                                 return FALSE;
519                         val = (guint8) strtoul((char *)hex_digit, NULL, 16);
520                         g_byte_array_append(bytes, &val, 1);
521                 } else {
522                         g_byte_array_append(bytes, (const guint8 *) p, 1);
523                 }
524                 p++;
525
526         }
527         return TRUE;
528 }
529
530 /*
531  * Given a GByteArray, generate a string from it that shows non-printable
532  * characters as percent-style escapes, and return a pointer to it.
533  */
534 gchar *
535 format_uri(const GByteArray *bytes, const gchar *reserved_chars)
536 {
537   static gchar *fmtbuf[3];
538   static guint fmtbuf_len[3];
539   static guint idx;
540   const guchar *reserved_def = ":/?#[]@!$&'()*+,;= ";
541   const guchar *reserved = reserved_def;
542   guint8 c;
543   guint column, i;
544   gboolean is_reserved = FALSE;
545
546   if (! bytes)
547     return "";
548
549   idx = (idx + 1) % 3;
550   if (reserved_chars)
551     reserved = reserved_chars;
552
553   /*
554    * Allocate the buffer if it's not already allocated.
555    */
556   if (fmtbuf[idx] == NULL) {
557     fmtbuf[idx] = g_malloc(INITIAL_FMTBUF_SIZE);
558     fmtbuf_len[idx] = INITIAL_FMTBUF_SIZE;
559   }
560   for (column = 0; column < bytes->len; column++) {
561     /*
562      * Is there enough room for this character, if it expands to
563      * a percent plus 2 hex digits (which is the most it can
564      * expand to), and also enough room for a terminating '\0'?
565      */
566     if (column+2+1 >= fmtbuf_len[idx]) {
567       /*
568        * Double the buffer's size if it's not big enough.
569        * The size of the buffer starts at 128, so doubling its size
570        * adds at least another 128 bytes, which is more than enough
571        * for one more character plus a terminating '\0'.
572        */
573       fmtbuf_len[idx] = fmtbuf_len[idx] * 2;
574       fmtbuf[idx] = g_realloc(fmtbuf[idx], fmtbuf_len[idx]);
575     }
576     c = bytes->data[column];
577
578     if (!isascii(c) || !isprint(c) || c == '%') {
579       is_reserved = TRUE;
580     }
581
582     for (i = 0; reserved[i]; i++) {
583       if (c == reserved[i])
584         is_reserved = TRUE;
585     }
586
587     if (!is_reserved) {
588       fmtbuf[idx][column] = c;
589     } else {
590       fmtbuf[idx][column] = '%';
591       column++;
592       fmtbuf[idx][column] = hex[c >> 4];
593       column++;
594       fmtbuf[idx][column] = hex[c & 0xF];
595     }
596   }
597   fmtbuf[idx][column] = '\0';
598   return fmtbuf[idx];
599 }
600
601 /**
602  * Create a copy of a GByteArray
603  *
604  * @param ba The byte array to be copied.
605  * @return If ba exists, a freshly allocated copy.  NULL otherwise.
606  *
607  */
608 GByteArray *
609 byte_array_dup(GByteArray *ba) {
610     GByteArray *new_ba;
611
612     if (!ba)
613         return NULL;
614
615     new_ba = g_byte_array_new();
616     g_byte_array_append(new_ba, ba->data, ba->len);
617     return new_ba;
618 }
619
620 #define SUBID_BUF_LEN 5
621 gboolean
622 oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
623   guint32 subid0, subid, sicnt, i;
624   const char *p, *dot;
625   guint8 buf[SUBID_BUF_LEN];
626
627   g_byte_array_set_size(bytes, 0);
628
629   /* check syntax */
630   p = oid_str;
631   dot = NULL;
632   while (*p) {
633     if (!isdigit((guchar)*p) && (*p != '.')) return FALSE;
634     if (*p == '.') {
635       if (p == oid_str) return FALSE;
636       if (!*(p+1)) return FALSE;
637       if ((p-1) == dot) return FALSE;
638       dot = p;
639     }
640     p++;
641   }
642   if (!dot) return FALSE;
643
644   p = oid_str;
645   sicnt = 0;
646   subid0 = 0;   /* squelch GCC complaints */
647   while (*p) {
648     subid = 0;
649     while (isdigit((guchar)*p)) {
650       subid *= 10;
651       subid += *p - '0';
652       p++;
653     }
654     if (sicnt == 0) {
655       subid0 = subid;
656       if (subid0 > 2) return FALSE;
657     } else if (sicnt == 1) {
658       if ((subid0 < 2) && (subid > 39)) return FALSE;
659       subid += 40 * subid0;
660     }
661     if (sicnt) {
662       i = SUBID_BUF_LEN;
663       do {
664         i--;
665         buf[i] = 0x80 | (subid % 0x80);
666         subid >>= 7;
667       } while (subid && i);
668       buf[SUBID_BUF_LEN-1] &= 0x7F;
669       g_byte_array_append(bytes, buf + i, SUBID_BUF_LEN - i);
670     }
671     sicnt++;
672     if (*p) p++;
673   }
674
675   return TRUE;
676 }
677
678 /**
679  * Compare the contents of two GByteArrays
680  *
681  * @param ba1 A byte array
682  * @param ba2 A byte array
683  * @return If both arrays are non-NULL and their lengths are equal and
684  *         their contents are equal, returns TRUE.  Otherwise, returns
685  *         FALSE.
686  *
687  * XXX - Should this be in strutil.c?
688  */
689 gboolean
690 byte_array_equal(GByteArray *ba1, GByteArray *ba2) {
691     if (!ba1 || !ba2)
692         return FALSE;
693
694     if (ba1->len != ba2->len)
695         return FALSE;
696
697     if (memcmp(ba1->data, ba2->data, ba1->len) != 0)
698         return FALSE;
699
700     return TRUE;
701 }
702
703
704 /* Return a XML escaped representation of the unescaped string.
705  * The returned string must be freed when no longer in use. */
706 gchar *
707 xml_escape(const gchar *unescaped)
708 {
709         GString *buffer = g_string_sized_new(128);
710         const gchar *p;
711         gchar c;
712
713         p = unescaped;
714         while ( (c = *p++) ) {
715                 switch (c) {
716                         case '<':
717                                 g_string_append(buffer, "&lt;");
718                                 break;
719                         case '>':
720                                 g_string_append(buffer, "&gt;");
721                                 break;
722                         case '&':
723                                 g_string_append(buffer, "&amp;");
724                                 break;
725                         case '\'':
726                                 g_string_append(buffer, "&apos;");
727                                 break;
728                         case '"':
729                                 g_string_append(buffer, "&quot;");
730                                 break;
731                         default:
732                                 g_string_append_c(buffer, c);
733                                 break;
734                 }
735         }
736         /* Return the string value contained within the GString
737          * after getting rid of the GString structure.
738          * This is the way to do this, see the GLib reference. */
739         return g_string_free(buffer, FALSE);
740 }
741
742
743 /* Return the first occurrence of needle in haystack.
744  * If not found, return NULL.
745  * If either haystack or needle has 0 length, return NULL.
746  * Algorithm copied from GNU's glibc 2.3.2 memcmp() */
747 const guint8 *
748 epan_memmem(const guint8 *haystack, guint haystack_len,
749                 const guint8 *needle, guint needle_len)
750 {
751         const guint8 *begin;
752         const guint8 *const last_possible
753                 = haystack + haystack_len - needle_len;
754
755         if (needle_len == 0) {
756                 return NULL;
757         }
758
759         if (needle_len > haystack_len) {
760                 return NULL;
761         }
762
763         for (begin = haystack ; begin <= last_possible; ++begin) {
764                 if (begin[0] == needle[0] &&
765                         !memcmp(&begin[1], needle + 1,
766                                 needle_len - 1)) {
767                         return begin;
768                 }
769         }
770
771         return NULL;
772 }
773
774 /*
775  * Scan the search string to make sure it's valid hex.  Return the
776  * number of bytes in nbytes.
777  */
778 guint8 *
779 convert_string_to_hex(const char *string, size_t *nbytes)
780 {
781   size_t n_bytes;
782   const char *p;
783   guchar c;
784   guint8 *bytes, *q, byte_val;
785
786   n_bytes = 0;
787   p = &string[0];
788   for (;;) {
789     c = *p++;
790     if (c == '\0')
791       break;
792     if (isspace(c))
793       continue; /* allow white space */
794     if (c==':' || c=='.' || c=='-')
795       continue; /* skip any ':', '.', or '-' between bytes */
796     if (!isxdigit(c)) {
797       /* Not a valid hex digit - fail */
798       return NULL;
799     }
800
801     /*
802      * We can only match bytes, not nibbles; we must have a valid
803      * hex digit immediately after that hex digit.
804      */
805     c = *p++;
806     if (!isxdigit(c))
807       return NULL;
808
809     /* 2 hex digits = 1 byte */
810     n_bytes++;
811   }
812
813   /*
814    * Were we given any hex digits?
815    */
816   if (n_bytes == 0) {
817       /* No. */
818       return NULL;
819   }
820
821   /*
822    * OK, it's valid, and it generates "n_bytes" bytes; generate the
823    * raw byte array.
824    */
825   bytes = g_malloc(n_bytes);
826   p = &string[0];
827   q = &bytes[0];
828   for (;;) {
829     c = *p++;
830     if (c == '\0')
831       break;
832     if (isspace(c))
833       continue; /* allow white space */
834     if (c==':' || c=='.' || c=='-')
835       continue; /* skip any ':', '.', or '-' between bytes */
836     /* From the loop above, we know this is a hex digit */
837     if (isdigit(c))
838       byte_val = c - '0';
839     else if (c >= 'a')
840       byte_val = (c - 'a') + 10;
841     else
842       byte_val = (c - 'A') + 10;
843     byte_val <<= 4;
844
845     /* We also know this is a hex digit */
846     c = *p++;
847     if (isdigit(c))
848       byte_val |= c - '0';
849     else if (c >= 'a')
850       byte_val |= (c - 'a') + 10;
851     else if (c >= 'A')
852       byte_val |= (c - 'A') + 10;
853
854     *q++ = byte_val;
855   }
856   *nbytes = n_bytes;
857   return bytes;
858 }
859
860 /*
861  * Copy if if it's a case-sensitive search; uppercase it if it's
862  * a case-insensitive search.
863  */
864 char *
865 convert_string_case(const char *string, gboolean case_insensitive)
866 {
867
868   if (case_insensitive) {
869     return g_utf8_strup(string, -1);
870   } else {
871     return g_strdup(string);
872   }
873 }
874
875 char *
876 epan_strcasestr(const char *haystack, const char *needle)
877 {
878         gsize hlen = strlen(haystack);
879         gsize nlen = strlen(needle);
880
881         while (hlen-- >= nlen) {
882                 if (!g_ascii_strncasecmp(haystack, needle, nlen))
883                         return (char*) haystack;
884                 haystack++;
885         }
886         return NULL;
887 }
888
889 const char *
890 string_or_null(const char *string)
891 {
892   if (string)
893     return string;
894   return "[NULL]";
895 }
896
897 int
898 escape_string_len(const char *string)
899 {
900         const char *p;
901         gchar c;
902         int repr_len;
903
904         repr_len = 0;
905         for (p = string; (c = *p) != '\0'; p++) {
906                 /* Backslashes and double-quotes must
907                  * be escaped */
908                 if (c == '\\' || c == '"') {
909                         repr_len += 2;
910                 }
911                 /* Values that can't nicely be represented
912                  * in ASCII need to be escaped. */
913                 else if (!isprint((unsigned char)c)) {
914                         /* c --> \xNN */
915                         repr_len += 4;
916                 }
917                 /* Other characters are just passed through. */
918                 else {
919                         repr_len++;
920                 }
921         }
922         return repr_len + 2;    /* string plus leading and trailing quotes */
923 }
924
925 char *
926 escape_string(char *buf, const char *string)
927 {
928   const gchar *p;
929   gchar c;
930   char *bufp;
931   char hexbuf[3];
932
933   bufp = buf;
934   *bufp++ = '"';
935   for (p = string; (c = *p) != '\0'; p++) {
936         /* Backslashes and double-quotes must
937          * be escaped. */
938         if (c == '\\' || c == '"') {
939                 *bufp++ = '\\';
940                 *bufp++ = c;
941         }
942         /* Values that can't nicely be represented
943          * in ASCII need to be escaped. */
944         else if (!isprint((unsigned char)c)) {
945                 /* c --> \xNN */
946                 g_snprintf(hexbuf,sizeof(hexbuf), "%02x", (unsigned char) c);
947                 *bufp++ = '\\';
948                 *bufp++ = 'x';
949                 *bufp++ = hexbuf[0];
950                 *bufp++ = hexbuf[1];
951         }
952         /* Other characters are just passed through. */
953         else {
954                 *bufp++ = c;
955         }
956   }
957   *bufp++ = '"';
958   *bufp = '\0';
959   return buf;
960 }
961
962 #define GN_CHAR_ALPHABET_SIZE 128
963
964 static gunichar IA5_default_alphabet[GN_CHAR_ALPHABET_SIZE] = {
965
966     /*ITU-T recommendation T.50 specifies International Reference Alphabet 5 (IA5) */
967
968     '?', '?', '?', '?', '?', '?', '?', '?',
969     '?', '?', '?', '?', '?', '?', '?', '?',
970     '?', '?', '?', '?', '?', '?', '?', '?',
971     '?', '?', '?', '?', '?', '?', '?', '?',
972     ' ', '!', '\"','#', '$', '%', '&', '\'',
973     '(', ')', '*', '+', ',', '-', '.', '/',
974     '0', '1', '2', '3', '4', '5', '6', '7',
975     '8', '9', ':', ';', '<', '=', '>', '?',
976     '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
977     'H',  'I',  'J',  'K',  'L',  'M',  'N',  'O',
978     'P',  'Q',  'R',  'S',  'T',  'U',  'V',  'W',
979     'X',  'Y',  'Z',  '[',  '\\',  ']',  '^',  '_',
980     '`', 'a',  'b',  'c',  'd',  'e',  'f',  'g',
981     'h',  'i',  'j',  'k',  'l',  'm',  'n',  'o',
982     'p',  'q',  'r',  's',  't',  'u',  'v',  'w',
983     'x',  'y',  'z',  '{',  '|',  '}',  '~',  '?'
984 };
985
986 static gunichar
987 char_def_ia5_alphabet_decode(unsigned char value)
988 {
989     if (value < GN_CHAR_ALPHABET_SIZE)
990     {
991                 return IA5_default_alphabet[value];
992     }
993     else
994     {
995                 return '?';
996     }
997 }
998
999 void
1000 IA5_7BIT_decode(unsigned char * dest, const unsigned char* src, int len)
1001 {
1002     int i, j;
1003     gunichar buf;
1004
1005
1006     for (i = 0, j = 0; j < len;  j++)
1007     {
1008             buf = char_def_ia5_alphabet_decode(src[j]);
1009             i += g_unichar_to_utf8(buf,&(dest[i]));
1010     }
1011     dest[i]=0;
1012     return;
1013 }
1014
1015 /*
1016  * This function takes a string and copies it, inserting a 'chr' before
1017  * every 'chr' in it.
1018  */
1019 gchar*
1020 ws_strdup_escape_char (const gchar *str, const gchar chr)
1021 {
1022         const gchar *p;
1023         gchar *q, *new_str;
1024
1025         if(!str)
1026                 return NULL;
1027
1028         p = str;
1029         /* Worst case: A string that is full of 'chr' */
1030         q = new_str = g_malloc (strlen(str) * 2 + 1);
1031
1032         while(*p != 0)
1033         {
1034                 if(*p == chr)
1035                         *q++ = chr;
1036
1037                 *q++ = *p++;
1038         }
1039         *q = '\0';
1040
1041         return new_str;
1042 }
1043
1044 /*
1045  * This function takes a string and copies it, removing any occurences of double
1046  * 'chr' with a single 'chr'.
1047  */
1048 gchar*
1049 ws_strdup_unescape_char (const gchar *str, const char chr)
1050 {
1051         const gchar *p;
1052         gchar *q, *new_str;
1053
1054         if(!str)
1055                 return NULL;
1056
1057         p = str;
1058         /* Worst case: A string that contains no 'chr' */
1059         q = new_str = g_malloc (strlen(str) + 1);
1060
1061         while(*p != 0)
1062         {
1063                 *q++ = *p;
1064                 if ((*p == chr) && (*(p+1) == chr))
1065                         p += 2;
1066                 else
1067                         p++;
1068         }
1069         *q = '\0';
1070
1071         return new_str;
1072 }
1073
1074 /* Create a newly-allocated string with replacement values. */
1075 gchar *string_replace(const gchar* str, const gchar *old_val, const gchar *new_val) {
1076         gchar **str_parts;
1077         gchar *new_str;
1078
1079         if (!str || !old_val) {
1080                 return NULL;
1081         }
1082
1083         str_parts = g_strsplit(str, old_val, 0);
1084         new_str = g_strjoinv(new_val, str_parts);
1085         g_strfreev(str_parts);
1086
1087         return new_str;
1088 }