diff options
Diffstat (limited to 'dbus/dbus-string.c')
| -rw-r--r-- | dbus/dbus-string.c | 478 | 
1 files changed, 26 insertions, 452 deletions
diff --git a/dbus/dbus-string.c b/dbus/dbus-string.c index 6a83398d..8820273d 100644 --- a/dbus/dbus-string.c +++ b/dbus/dbus-string.c @@ -2125,400 +2125,6 @@ _dbus_string_ends_with_c_str (const DBusString *a,    return TRUE;  } -static const signed char base64_table[] = { -  /* 0 */ 'A', -  /* 1 */ 'B', -  /* 2 */ 'C', -  /* 3 */ 'D', -  /* 4 */ 'E', -  /* 5 */ 'F', -  /* 6 */ 'G', -  /* 7 */ 'H', -  /* 8 */ 'I', -  /* 9 */ 'J', -  /* 10 */ 'K', -  /* 11 */ 'L', -  /* 12 */ 'M', -  /* 13 */ 'N', -  /* 14 */ 'O', -  /* 15 */ 'P', -  /* 16 */ 'Q', -  /* 17 */ 'R', -  /* 18 */ 'S', -  /* 19 */ 'T', -  /* 20 */ 'U', -  /* 21 */ 'V', -  /* 22 */ 'W', -  /* 23 */ 'X', -  /* 24 */ 'Y', -  /* 25 */ 'Z', -  /* 26 */ 'a', -  /* 27 */ 'b', -  /* 28 */ 'c', -  /* 29 */ 'd', -  /* 30 */ 'e', -  /* 31 */ 'f', -  /* 32 */ 'g', -  /* 33 */ 'h', -  /* 34 */ 'i', -  /* 35 */ 'j', -  /* 36 */ 'k', -  /* 37 */ 'l', -  /* 38 */ 'm', -  /* 39 */ 'n', -  /* 40 */ 'o', -  /* 41 */ 'p', -  /* 42 */ 'q', -  /* 43 */ 'r', -  /* 44 */ 's', -  /* 45 */ 't', -  /* 46 */ 'u', -  /* 47 */ 'v', -  /* 48 */ 'w', -  /* 49 */ 'x', -  /* 50 */ 'y', -  /* 51 */ 'z', -  /* 52 */ '0', -  /* 53 */ '1', -  /* 54 */ '2', -  /* 55 */ '3', -  /* 56 */ '4', -  /* 57 */ '5', -  /* 58 */ '6', -  /* 59 */ '7', -  /* 60 */ '8', -  /* 61 */ '9', -  /* 62 */ '+', -  /* 63 */ '/' -}; - -/** The minimum char that's a valid char in Base64-encoded text */ -#define UNBASE64_MIN_CHAR (43) -/** The maximum char that's a valid char in Base64-encoded text */ -#define UNBASE64_MAX_CHAR (122) -/** Must subtract this from a char's integer value before offsetting - * into unbase64_table - */ -#define UNBASE64_TABLE_OFFSET UNBASE64_MIN_CHAR -static const signed char unbase64_table[] = { -  /* 43 + */ 62, -  /* 44 , */ -1, -  /* 45 - */ -1, -  /* 46 . */ -1, -  /* 47 / */ 63, -  /* 48 0 */ 52, -  /* 49 1 */ 53, -  /* 50 2 */ 54, -  /* 51 3 */ 55, -  /* 52 4 */ 56, -  /* 53 5 */ 57, -  /* 54 6 */ 58, -  /* 55 7 */ 59, -  /* 56 8 */ 60, -  /* 57 9 */ 61, -  /* 58 : */ -1, -  /* 59 ; */ -1, -  /* 60 < */ -1, -  /* 61 = */ -1, -  /* 62 > */ -1, -  /* 63 ? */ -1, -  /* 64 @ */ -1, -  /* 65 A */ 0, -  /* 66 B */ 1, -  /* 67 C */ 2, -  /* 68 D */ 3, -  /* 69 E */ 4, -  /* 70 F */ 5, -  /* 71 G */ 6, -  /* 72 H */ 7, -  /* 73 I */ 8, -  /* 74 J */ 9, -  /* 75 K */ 10, -  /* 76 L */ 11, -  /* 77 M */ 12, -  /* 78 N */ 13, -  /* 79 O */ 14, -  /* 80 P */ 15, -  /* 81 Q */ 16, -  /* 82 R */ 17, -  /* 83 S */ 18, -  /* 84 T */ 19, -  /* 85 U */ 20, -  /* 86 V */ 21, -  /* 87 W */ 22, -  /* 88 X */ 23, -  /* 89 Y */ 24, -  /* 90 Z */ 25, -  /* 91 [ */ -1, -  /* 92 \ */ -1, -  /* 93 ] */ -1, -  /* 94 ^ */ -1, -  /* 95 _ */ -1, -  /* 96 ` */ -1, -  /* 97 a */ 26, -  /* 98 b */ 27, -  /* 99 c */ 28, -  /* 100 d */ 29, -  /* 101 e */ 30, -  /* 102 f */ 31, -  /* 103 g */ 32, -  /* 104 h */ 33, -  /* 105 i */ 34, -  /* 106 j */ 35, -  /* 107 k */ 36, -  /* 108 l */ 37, -  /* 109 m */ 38, -  /* 110 n */ 39, -  /* 111 o */ 40, -  /* 112 p */ 41, -  /* 113 q */ 42, -  /* 114 r */ 43, -  /* 115 s */ 44, -  /* 116 t */ 45, -  /* 117 u */ 46, -  /* 118 v */ 47, -  /* 119 w */ 48, -  /* 120 x */ 49, -  /* 121 y */ 50, -  /* 122 z */ 51 -}; - -/** - * Encodes a string using Base64, as documented in RFC 2045. - * - * @param source the string to encode - * @param start byte index to start encoding - * @param dest string where encoded data should be placed - * @param insert_at where to place encoded data - * @returns #TRUE if encoding was successful, #FALSE if no memory etc. - */ -dbus_bool_t -_dbus_string_base64_encode (const DBusString *source, -                            int               start, -                            DBusString       *dest, -                            int               insert_at) -{ -  int source_len; -  unsigned int dest_len; /* unsigned for overflow checks below */ -  const unsigned char *s; -  unsigned char *d; -  const unsigned char *triplet_end; -  const unsigned char *final_end; -  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at);   -  _dbus_assert (source != dest); -   -  /* For each 24 bits (3 bytes) of input, we have 4 bytes of -   * output. -   */ -  source_len = real_source->len - start; -  dest_len = (source_len / 3) * 4; -  if (source_len % 3 != 0) -    dest_len += 4; - -  if (dest_len > (unsigned int) real_dest->max_length) -    return FALSE; -   -  if (source_len == 0) -    return TRUE; -   -  if (!open_gap (dest_len, real_dest, insert_at)) -    return FALSE; - -  d = real_dest->str + insert_at; -  s = real_source->str + start; -  final_end = real_source->str + (start + source_len); -  triplet_end = final_end - (source_len % 3); -  _dbus_assert (triplet_end <= final_end); -  _dbus_assert ((final_end - triplet_end) < 3); - -#define ENCODE_64(v) (base64_table[ (unsigned char) (v) ]) -#define SIX_BITS_MASK (0x3f) -  _dbus_assert (SIX_BITS_MASK < _DBUS_N_ELEMENTS (base64_table)); -   -  while (s != triplet_end) -    { -      unsigned int triplet; - -      triplet = s[2] | (s[1] << 8) | (s[0] << 16); - -      /* Encode each 6 bits. */ - -      *d++ = ENCODE_64 (triplet >> 18); -      *d++ = ENCODE_64 ((triplet >> 12) & SIX_BITS_MASK); -      *d++ = ENCODE_64 ((triplet >> 6) & SIX_BITS_MASK); -      *d++ = ENCODE_64 (triplet & SIX_BITS_MASK); -       -      s += 3; -    } - -  switch (final_end - triplet_end) -    { -    case 2: -      { -        unsigned int doublet; -         -        doublet = s[1] | (s[0] << 8);         - -        *d++ = ENCODE_64 (doublet >> 12); -        *d++ = ENCODE_64 ((doublet >> 6) & SIX_BITS_MASK); -        *d++ = ENCODE_64 (doublet & SIX_BITS_MASK); -        *d++ = '='; -      } -      break; -    case 1: -      { -        unsigned int singlet; -         -        singlet = s[0]; - -        *d++ = ENCODE_64 ((singlet >> 6) & SIX_BITS_MASK); -        *d++ = ENCODE_64 (singlet & SIX_BITS_MASK); -        *d++ = '='; -        *d++ = '='; -      } -      break; -    case 0: -      break; -    } - -  _dbus_assert (d == (real_dest->str + (insert_at + dest_len))); - -  return TRUE; -} - -/** - * Decodes a string from Base64, as documented in RFC 2045. - * - * @todo sort out the AUDIT comment in here. The case it mentions - * ("====" or "x===") is not allowed in correct base64, so need to - * decide what to do with that kind of input. Probably ignore it - * since we ignore any other junk seen. - * - * @param source the string to decode - * @param start byte index to start decode - * @param dest string where decoded data should be placed - * @param insert_at where to place decoded data - * @returns #TRUE if decoding was successful, #FALSE if no memory etc. - */ -dbus_bool_t -_dbus_string_base64_decode (const DBusString *source, -                            int               start, -                            DBusString       *dest, -                            int               insert_at) -{ -  int source_len; -  const char *s; -  const char *end; -  DBusString result; -  unsigned int triplet = 0; -  int sextet_count; -  int pad_count; -  DBUS_STRING_COPY_PREAMBLE (source, start, dest, insert_at); -  _dbus_assert (source != dest); -   -  source_len = real_source->len - start; -  s = real_source->str + start; -  end = real_source->str + source_len; - -  if (source_len == 0) -    return TRUE; - -  if (!_dbus_string_init (&result)) -    return FALSE; - -  pad_count = 0; -  sextet_count = 0; -  while (s != end) -    { -      /* The idea is to just skip anything that isn't -       * a base64 char - it's allowed to have whitespace, -       * newlines, etc. in here. We also ignore trailing -       * base64 chars, though that's suspicious. -       */ -       -      if (*s >= UNBASE64_MIN_CHAR && -          *s <= UNBASE64_MAX_CHAR) -        { -          if (*s == '=') -            { -              /* '=' is padding, doesn't represent additional data -               * but does increment our count. -               */ -              pad_count += 1; -              sextet_count += 1; -            } -          else -            { -              int val; - -              val = unbase64_table[(*s) - UNBASE64_TABLE_OFFSET]; - -              if (val >= 0) -                { -                  triplet <<= 6; -                  triplet |= (unsigned int) val; -                  sextet_count += 1; -                } -            } - -          if (sextet_count == 4) -            { -              /* no pad = 3 bytes, 1 pad = 2 bytes, 2 pad = 1 byte */ - - -	      /* AUDIT: Comment doesn't mention 4 pad => 0, -	       *         3 pad => 1 byte, though the code should -	       *        work fine if those are the required outputs. -	       * -	       *        I assume that the spec requires dropping -	       *        the top two bits of, say, ///= which is > 2  -	       *        bytes worth of bits. (Or otherwise, you couldn't -	       *        actually represent 2 byte sequences. -	       */ -               -              if (pad_count < 1) -                { -                  if (!_dbus_string_append_byte (&result, -                                                 triplet >> 16)) -                    goto failed; -                } -               -              if (pad_count < 2) -                { -                  if (!_dbus_string_append_byte (&result, -                                                 (triplet >> 8) & 0xff)) -                    goto failed; -                } -               -              if (!_dbus_string_append_byte (&result, -                                             triplet & 0xff)) -                goto failed; -               -              sextet_count = 0; -              pad_count = 0; -              triplet = 0; -            } -        } -       -      ++s; -    } - -  if (!_dbus_string_move (&result, 0, dest, insert_at)) -    { -      _dbus_string_free (&result); -      return FALSE; -    } - -  _dbus_string_free (&result); - -  return TRUE; - - failed: -  _dbus_string_free (&result); - -  return FALSE; -} -  /**   * Encodes a string in hex, the way MD5 and SHA-1 are usually   * encoded. (Each byte is two hex digits.) @@ -2583,13 +2189,15 @@ _dbus_string_hex_encode (const DBusString *source,   *   * @param source the string to decode   * @param start byte index to start decode + * @param end_return return location of the end of the hex data, or #NULL   * @param dest string where decoded data should be placed   * @param insert_at where to place decoded data - * @returns #TRUE if decoding was successful, #FALSE if no memory etc. + * @returns #TRUE if decoding was successful, #FALSE if no memory.   */  dbus_bool_t  _dbus_string_hex_decode (const DBusString *source,                           int               start, +			 int              *end_return,                           DBusString       *dest,                           int               insert_at)  { @@ -2672,17 +2280,14 @@ _dbus_string_hex_decode (const DBusString *source,            val = 15;            break;          default: -          val = 0; -          _dbus_verbose ("invalid character '%c' in hex encoded text\n", -                         *p); -          goto out; +          goto done;          }        if (high_bits)          {            if (!_dbus_string_append_byte (&result,                                           val << 4)) -            goto out; +	    goto out;          }        else          { @@ -2703,9 +2308,13 @@ _dbus_string_hex_decode (const DBusString *source,        ++p;      } + done:    if (!_dbus_string_move (&result, 0, dest, insert_at))      goto out; +  if (end_return) +    *end_return = p - (const unsigned char*) _dbus_string_get_const_data (source); +    retval = TRUE;   out: @@ -3228,60 +2837,13 @@ test_max_len (DBusString *str,  }  static void -test_base64_roundtrip (const unsigned char *data, -                       int                  len) -{ -  DBusString orig; -  DBusString encoded; -  DBusString decoded; - -  if (len < 0) -    len = strlen (data); -   -  if (!_dbus_string_init (&orig)) -    _dbus_assert_not_reached ("could not init string"); - -  if (!_dbus_string_init (&encoded)) -    _dbus_assert_not_reached ("could not init string"); -   -  if (!_dbus_string_init (&decoded)) -    _dbus_assert_not_reached ("could not init string"); - -  if (!_dbus_string_append_len (&orig, data, len)) -    _dbus_assert_not_reached ("couldn't append orig data"); - -  if (!_dbus_string_base64_encode (&orig, 0, &encoded, 0)) -    _dbus_assert_not_reached ("could not encode"); - -  if (!_dbus_string_base64_decode (&encoded, 0, &decoded, 0)) -    _dbus_assert_not_reached ("could not decode"); - -  if (!_dbus_string_equal (&orig, &decoded)) -    { -      const char *s; -       -      printf ("Original string %d bytes encoded %d bytes decoded %d bytes\n", -              _dbus_string_get_length (&orig), -              _dbus_string_get_length (&encoded), -              _dbus_string_get_length (&decoded)); -      printf ("Original: %s\n", data); -      s = _dbus_string_get_const_data (&decoded); -      printf ("Decoded: %s\n", s); -      _dbus_assert_not_reached ("original string not the same as string decoded from base64"); -    } -   -  _dbus_string_free (&orig); -  _dbus_string_free (&encoded); -  _dbus_string_free (&decoded);   -} - -static void  test_hex_roundtrip (const unsigned char *data,                      int                  len)  {    DBusString orig;    DBusString encoded;    DBusString decoded; +  int end;    if (len < 0)      len = strlen (data); @@ -3301,9 +2863,11 @@ test_hex_roundtrip (const unsigned char *data,    if (!_dbus_string_hex_encode (&orig, 0, &encoded, 0))      _dbus_assert_not_reached ("could not encode"); -  if (!_dbus_string_hex_decode (&encoded, 0, &decoded, 0)) +  if (!_dbus_string_hex_decode (&encoded, 0, &end, &decoded, 0))      _dbus_assert_not_reached ("could not decode"); +  _dbus_assert (_dbus_string_get_length (&encoded) == end); +    if (!_dbus_string_equal (&orig, &decoded))      {        const char *s; @@ -3315,7 +2879,7 @@ test_hex_roundtrip (const unsigned char *data,        printf ("Original: %s\n", data);        s = _dbus_string_get_const_data (&decoded);        printf ("Decoded: %s\n", s); -      _dbus_assert_not_reached ("original string not the same as string decoded from base64"); +      _dbus_assert_not_reached ("original string not the same as string decoded from hex");      }    _dbus_string_free (&orig); @@ -3867,8 +3431,18 @@ _dbus_string_test (void)    _dbus_string_free (&str); -  /* Base 64 and Hex encoding */ -  test_roundtrips (test_base64_roundtrip); +  /* Hex encoding */ +  _dbus_string_init_const (&str, "cafebabe, this is a bogus hex string"); +  if (!_dbus_string_init (&other)) +    _dbus_assert_not_reached ("could not init string"); + +  if (!_dbus_string_hex_decode (&str, 0, &end, &other, 0)) +    _dbus_assert_not_reached ("deccoded bogus hex string with no error"); + +  _dbus_assert (end == 8); + +  _dbus_string_free (&other); +    test_roundtrips (test_hex_roundtrip);    /* Path validation */  | 
