static dbus_bool_t parse_section_start (BusDesktopFileParser *parser, DBusError *error) { int line_end; char *section_name; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end)) line_end = parser->len; if (line_end - parser->pos <= 2 || _dbus_string_get_byte (&parser->data, line_end - 1) != ']') { report_error (parser, "Invalid syntax for section header", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); parser_free (parser); return FALSE; } section_name = unescape_string (parser, &parser->data, parser->pos + 1, line_end - 1, error); if (section_name == NULL) { parser_free (parser); return FALSE; } if (!is_valid_section_name (section_name)) { report_error (parser, "Invalid characters in section name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error); parser_free (parser); dbus_free (section_name); return FALSE; } if (open_section (parser, section_name) == NULL) { dbus_free (section_name); return FALSE; } if (line_end == parser->len) parser->pos = parser->len; else parser->pos = line_end + 1; parser->line_num += 1; dbus_free (section_name); return TRUE; }
static void parse_comment_or_blank (BusDesktopFileParser *parser) { int line_end; if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end)) line_end = parser->len; if (line_end == parser->len) parser->pos = parser->len; else parser->pos = line_end + 1; parser->line_num += 1; }
/** * Split paths into a list of char strings * * @param dirs string with pathes * @param suffix string concated to each path in dirs * @param dir_list contains a list of splitted pathes * return #TRUE is pathes could be splittes,#FALSE in oom case */ dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs, const char *suffix, DBusList **dir_list) { int start; int i; int len; char *cpath; DBusString file_suffix; start = 0; i = 0; _dbus_string_init_const (&file_suffix, suffix); len = _dbus_string_get_length (dirs); while (_dbus_string_find (dirs, start, _DBUS_PATH_SEPARATOR, &i)) { DBusString path; if (!_dbus_string_init (&path)) goto oom; if (!_dbus_string_copy_len (dirs, start, i - start, &path, 0)) { _dbus_string_free (&path); goto oom; } _dbus_string_chop_white (&path); /* check for an empty path */ if (_dbus_string_get_length (&path) == 0) goto next; if (!_dbus_concat_dir_and_file (&path, &file_suffix)) { _dbus_string_free (&path); goto oom; } if (!_dbus_string_copy_data(&path, &cpath)) { _dbus_string_free (&path); goto oom; } if (!_dbus_list_append (dir_list, cpath)) { _dbus_string_free (&path); dbus_free (cpath); goto oom; } next: _dbus_string_free (&path); start = i + 1; } if (start != len) { DBusString path; if (!_dbus_string_init (&path)) goto oom; if (!_dbus_string_copy_len (dirs, start, len - start, &path, 0)) { _dbus_string_free (&path); goto oom; } if (!_dbus_concat_dir_and_file (&path, &file_suffix)) { _dbus_string_free (&path); goto oom; } if (!_dbus_string_copy_data(&path, &cpath)) { _dbus_string_free (&path); goto oom; } if (!_dbus_list_append (dir_list, cpath)) { _dbus_string_free (&path); dbus_free (cpath); goto oom; } _dbus_string_free (&path); } return TRUE; oom: _dbus_list_foreach (dir_list, (DBusForeachFunction)dbus_free, NULL); _dbus_list_clear (dir_list); return FALSE; }
static dbus_bool_t parse_key_value (BusDesktopFileParser *parser, DBusError *error) { int line_end; int key_start, key_end; int value_start; int p; char *value, *tmp; DBusString key; BusDesktopFileLine *line; _DBUS_ASSERT_ERROR_IS_CLEAR (error); if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end)) line_end = parser->len; p = parser->pos; key_start = p; while (p < line_end && (valid[_dbus_string_get_byte (&parser->data, p)] & VALID_KEY_CHAR)) p++; key_end = p; if (key_start == key_end) { report_error (parser, "Empty key name", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); parser_free (parser); return FALSE; } /* We ignore locales for now */ if (p < line_end && _dbus_string_get_byte (&parser->data, p) == '[') { if (line_end == parser->len) parser->pos = parser->len; else parser->pos = line_end + 1; parser->line_num += 1; return TRUE; } /* Skip space before '=' */ while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ') p++; if (p < line_end && _dbus_string_get_byte (&parser->data, p) != '=') { report_error (parser, "Invalid characters in key name", BUS_DESKTOP_PARSE_ERROR_INVALID_CHARS, error); parser_free (parser); return FALSE; } if (p == line_end) { report_error (parser, "No '=' in key/value pair", BUS_DESKTOP_PARSE_ERROR_INVALID_SYNTAX, error); parser_free (parser); return FALSE; } /* Skip the '=' */ p++; /* Skip space after '=' */ while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ') p++; value_start = p; value = unescape_string (parser, &parser->data, value_start, line_end, error); if (value == NULL) { parser_free (parser); return FALSE; } line = new_line (parser); if (line == NULL) { parser_free (parser); return FALSE; } if (!_dbus_string_init (&key)) { parser_free (parser); return FALSE; } if (!_dbus_string_copy_len (&parser->data, key_start, key_end - key_start, &key, 0)) { parser_free (parser); return FALSE; } if (!_dbus_string_steal_data (&key, &tmp)) { parser_free (parser); return FALSE; } _dbus_string_free (&key); line->key = tmp; line->value = value; if (line_end == parser->len) parser->pos = parser->len; else parser->pos = line_end + 1; parser->line_num += 1; return TRUE; }
/** * @ingroup DBusStringInternals * Unit test for DBusString. * * @todo Need to write tests for _dbus_string_copy() and * _dbus_string_move() moving to/from each of start/middle/end of a * string. Also need tests for _dbus_string_move_len () * * @returns #TRUE on success. */ dbus_bool_t _dbus_string_test (void) { DBusString str; DBusString other; int i, end; long v; double d; int lens[] = { 0, 1, 2, 3, 4, 5, 10, 16, 17, 18, 25, 31, 32, 33, 34, 35, 63, 64, 65, 66, 67, 68, 69, 70, 71, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136 }; char *s; dbus_unichar_t ch; i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); test_max_len (&str, lens[i]); _dbus_string_free (&str); ++i; } /* Test shortening and setting length */ i = 0; while (i < _DBUS_N_ELEMENTS (lens)) { int j; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); set_max_length (&str, lens[i]); if (!_dbus_string_set_length (&str, lens[i])) _dbus_assert_not_reached ("failed to set string length"); j = lens[i]; while (j > 0) { _dbus_assert (_dbus_string_get_length (&str) == j); if (j > 0) { _dbus_string_shorten (&str, 1); _dbus_assert (_dbus_string_get_length (&str) == (j - 1)); } --j; } _dbus_string_free (&str); ++i; } /* Test equality */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("oom"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("oom"); _dbus_string_init_const (&other, "H"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 1, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 0, &other, 1)); _dbus_string_init_const (&other, "Hello"); _dbus_assert (_dbus_string_equal_substring (&str, 0, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 1, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 2, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 3, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 4, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 5, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 0)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 1)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 2)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 3)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 4)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 5)); _dbus_string_init_const (&other, "World"); _dbus_assert (_dbus_string_equal_substring (&str, 6, 5, &other, 0)); _dbus_assert (_dbus_string_equal_substring (&str, 7, 4, &other, 1)); _dbus_assert (_dbus_string_equal_substring (&str, 8, 3, &other, 2)); _dbus_assert (_dbus_string_equal_substring (&str, 9, 2, &other, 3)); _dbus_assert (_dbus_string_equal_substring (&str, 10, 1, &other, 4)); _dbus_assert (_dbus_string_equal_substring (&str, 11, 0, &other, 5)); _dbus_assert (_dbus_string_equal_substring (&other, 0, 5, &str, 6)); _dbus_assert (_dbus_string_equal_substring (&other, 1, 4, &str, 7)); _dbus_assert (_dbus_string_equal_substring (&other, 2, 3, &str, 8)); _dbus_assert (_dbus_string_equal_substring (&other, 3, 2, &str, 9)); _dbus_assert (_dbus_string_equal_substring (&other, 4, 1, &str, 10)); _dbus_assert (_dbus_string_equal_substring (&other, 5, 0, &str, 11)); _dbus_string_free (&str); /* Test appending data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); i = 0; while (i < 10) { if (!_dbus_string_append (&str, "a")) _dbus_assert_not_reached ("failed to append string to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 1); if (!_dbus_string_append_byte (&str, 'b')) _dbus_assert_not_reached ("failed to append byte to string\n"); _dbus_assert (_dbus_string_get_length (&str) == i * 2 + 2); ++i; } _dbus_string_free (&str); /* Check steal_data */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_steal_data (&str, &s)) _dbus_assert_not_reached ("failed to steal data"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (((int)strlen (s)) == i); dbus_free (s); /* Check move */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_move (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 2); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); if (!_dbus_string_move (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not move"); _dbus_assert (_dbus_string_get_length (&str) == 0); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_string_free (&other); /* Check copy */ if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_copy (&str, 0, &other, 0)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello World")); if (!_dbus_string_copy (&str, 0, &other, _dbus_string_get_length (&other) / 2)) _dbus_assert_not_reached ("could not copy"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 3); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello WorldHello WorldHello World")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check replace */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello World")) _dbus_assert_not_reached ("could not append to string"); i = _dbus_string_get_length (&str); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("could not init string"); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 0, _dbus_string_get_length (&other))) _dbus_assert_not_reached ("could not replace"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i); _dbus_assert (_dbus_string_equal_c_str (&other, "Hello World")); if (!_dbus_string_replace_len (&str, 0, _dbus_string_get_length (&str), &other, 5, 1)) _dbus_assert_not_reached ("could not replace center space"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorld")); if (!_dbus_string_replace_len (&str, 1, 1, &other, _dbus_string_get_length (&other) - 1, 1)) _dbus_assert_not_reached ("could not replace end character"); _dbus_assert (_dbus_string_get_length (&str) == i); _dbus_assert (_dbus_string_get_length (&other) == i * 2 - 1); _dbus_assert (_dbus_string_equal_c_str (&other, "HelloHello WorldWorle")); _dbus_string_free (&str); _dbus_string_free (&other); /* Check append/get unichar */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); ch = 0; if (!_dbus_string_append_unichar (&str, 0xfffc)) _dbus_assert_not_reached ("failed to append unichar"); _dbus_string_get_unichar (&str, 0, &ch, &i); _dbus_assert (ch == 0xfffc); _dbus_assert (i == _dbus_string_get_length (&str)); _dbus_string_free (&str); /* Check insert/set/get byte */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("failed to append Hello"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'e'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'o'); _dbus_string_set_byte (&str, 1, 'q'); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'q'); if (!_dbus_string_insert_bytes (&str, 0, 1, 255)) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, 2, 4, 'Z')) _dbus_assert_not_reached ("can't insert byte"); if (!_dbus_string_insert_bytes (&str, _dbus_string_get_length (&str), 1, 'W')) _dbus_assert_not_reached ("can't insert byte"); _dbus_assert (_dbus_string_get_byte (&str, 0) == 255); _dbus_assert (_dbus_string_get_byte (&str, 1) == 'H'); _dbus_assert (_dbus_string_get_byte (&str, 2) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 3) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 4) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 5) == 'Z'); _dbus_assert (_dbus_string_get_byte (&str, 6) == 'q'); _dbus_assert (_dbus_string_get_byte (&str, 7) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 8) == 'l'); _dbus_assert (_dbus_string_get_byte (&str, 9) == 'o'); _dbus_assert (_dbus_string_get_byte (&str, 10) == 'W'); _dbus_string_free (&str); /* Check append/parse int/double */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_int (&str, 27)) _dbus_assert_not_reached ("failed to append int"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_int (&str, 0, &v, &end)) _dbus_assert_not_reached ("failed to parse int"); _dbus_assert (v == 27); _dbus_assert (end == i); _dbus_string_free (&str); if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append_double (&str, 50.3)) _dbus_assert_not_reached ("failed to append float"); i = _dbus_string_get_length (&str); if (!_dbus_string_parse_double (&str, 0, &d, &end)) _dbus_assert_not_reached ("failed to parse float"); _dbus_assert (d > (50.3 - 1e-6) && d < (50.3 + 1e-6)); _dbus_assert (end == i); _dbus_string_free (&str); /* Test find */ if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("failed to init string"); if (!_dbus_string_append (&str, "Hello")) _dbus_assert_not_reached ("couldn't append to string"); if (!_dbus_string_find (&str, 0, "He", &i)) _dbus_assert_not_reached ("didn't find 'He'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "Hello", &i)) _dbus_assert_not_reached ("didn't find 'Hello'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "ello", &i)) _dbus_assert_not_reached ("didn't find 'ello'"); _dbus_assert (i == 1); if (!_dbus_string_find (&str, 0, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (!_dbus_string_find (&str, 2, "lo", &i)) _dbus_assert_not_reached ("didn't find 'lo'"); _dbus_assert (i == 3); if (_dbus_string_find (&str, 4, "lo", &i)) _dbus_assert_not_reached ("did find 'lo'"); if (!_dbus_string_find (&str, 0, "l", &i)) _dbus_assert_not_reached ("didn't find 'l'"); _dbus_assert (i == 2); if (!_dbus_string_find (&str, 0, "H", &i)) _dbus_assert_not_reached ("didn't find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find (&str, 0, "", &i)) _dbus_assert_not_reached ("didn't find ''"); _dbus_assert (i == 0); if (_dbus_string_find (&str, 0, "Hello!", NULL)) _dbus_assert_not_reached ("Did find 'Hello!'"); if (_dbus_string_find (&str, 0, "Oh, Hello", NULL)) _dbus_assert_not_reached ("Did find 'Oh, Hello'"); if (_dbus_string_find (&str, 0, "ill", NULL)) _dbus_assert_not_reached ("Did find 'ill'"); if (_dbus_string_find (&str, 0, "q", NULL)) _dbus_assert_not_reached ("Did find 'q'"); if (!_dbus_string_find_to (&str, 0, 2, "He", NULL)) _dbus_assert_not_reached ("Didn't find 'He'"); if (_dbus_string_find_to (&str, 0, 2, "Hello", NULL)) _dbus_assert_not_reached ("Did find 'Hello'"); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'H', &i)) _dbus_assert_not_reached ("Did not find 'H'"); _dbus_assert (i == 0); if (!_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str), 'o', &i)) _dbus_assert_not_reached ("Did not find 'o'"); _dbus_assert (i == _dbus_string_get_length (&str) - 1); if (_dbus_string_find_byte_backward (&str, _dbus_string_get_length (&str) - 1, 'o', &i)) _dbus_assert_not_reached ("Did find 'o'"); _dbus_assert (i == -1); if (_dbus_string_find_byte_backward (&str, 1, 'e', &i)) _dbus_assert_not_reached ("Did find 'e'"); _dbus_assert (i == -1); if (!_dbus_string_find_byte_backward (&str, 2, 'e', &i)) _dbus_assert_not_reached ("Didn't find 'e'"); _dbus_assert (i == 1); _dbus_string_free (&str); /* 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); _dbus_string_free (&str); { int found, found_len; _dbus_string_init_const (&str, "012\r\n567\n90"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len) || found != 3 || found_len != 2) _dbus_assert_not_reached ("Did not find '\\r\\n'"); if (found != 3 || found_len != 2) _dbus_assert_not_reached ("invalid return values"); if (!_dbus_string_find_eol (&str, 5, &found, &found_len)) _dbus_assert_not_reached ("Did not find '\\n'"); if (found != 8 || found_len != 1) _dbus_assert_not_reached ("invalid return values"); if (_dbus_string_find_eol (&str, 9, &found, &found_len)) _dbus_assert_not_reached ("Found not expected '\\n'"); else if (found != 11 || found_len != 0) _dbus_assert_not_reached ("invalid return values '\\n'"); found = -1; found_len = -1; _dbus_string_init_const (&str, ""); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found an eol in an empty string"); _dbus_assert (found == 0); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar"); if (_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("found eol in string that lacks one"); _dbus_assert (found == 6); _dbus_assert (found_len == 0); found = -1; found_len = -1; _dbus_string_init_const (&str, "foobar\n"); if (!_dbus_string_find_eol (&str, 0, &found, &found_len)) _dbus_assert_not_reached ("did not find eol in string that has one at end"); _dbus_assert (found == 6); _dbus_assert (found_len == 1); } { DBusString line; #define FIRST_LINE "this is a line" #define SECOND_LINE "this is a second line" /* third line is empty */ #define THIRD_LINE "" #define FOURTH_LINE "this is a fourth line" if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, FIRST_LINE "\n" SECOND_LINE "\r\n" THIRD_LINE "\n" FOURTH_LINE)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&line)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop first line"); _dbus_assert (_dbus_string_equal_c_str (&line, FIRST_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop second line"); _dbus_assert (_dbus_string_equal_c_str (&line, SECOND_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop third line"); _dbus_assert (_dbus_string_equal_c_str (&line, THIRD_LINE)); if (!_dbus_string_pop_line (&str, &line)) _dbus_assert_not_reached ("failed to pop fourth line"); _dbus_assert (_dbus_string_equal_c_str (&line, FOURTH_LINE)); _dbus_string_free (&str); _dbus_string_free (&line); } { if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); for (i = 0; i < 10000; i++) if (!_dbus_string_append (&str, "abcdefghijklmnopqrstuvwxyz")) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_set_length (&str, 10)) _dbus_assert_not_reached ("failed to set length"); /* actually compact */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact after set_length"); /* peek inside to make sure it worked */ if (((DBusRealString *)&str)->allocated > 30) _dbus_assert_not_reached ("compacting string didn't do anything"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after compact"); /* compact nothing */ if (!_dbus_string_compact (&str, 2048)) _dbus_assert_not_reached ("failed to compact 2nd time"); if (!_dbus_string_equal_c_str (&str, "abcdefghij")) _dbus_assert_not_reached ("unexpected content after 2nd compact"); /* and make sure it still works...*/ if (!_dbus_string_append (&str, "123456")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content after append"); /* after growing automatically, this should do nothing */ if (!_dbus_string_compact (&str, 20000)) _dbus_assert_not_reached ("failed to compact after grow"); /* but this one will do something */ if (!_dbus_string_compact (&str, 0)) _dbus_assert_not_reached ("failed to compact after grow"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456")) _dbus_assert_not_reached ("unexpected content"); if (!_dbus_string_append (&str, "!@#$%")) _dbus_assert_not_reached ("failed to append after compact"); if (!_dbus_string_equal_c_str (&str, "abcdefghij123456!@#$%")) _dbus_assert_not_reached ("unexpected content"); _dbus_string_free (&str); } { const char two_strings[] = "one\ttwo"; if (!_dbus_string_init (&str)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_init (&other)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_append (&str, two_strings)) _dbus_assert_not_reached ("no memory"); if (!_dbus_string_split_on_byte (&str, '\t', &other)) _dbus_assert_not_reached ("no memory or delimiter not found"); if (strcmp (_dbus_string_get_data (&str), "one") != 0) _dbus_assert_not_reached ("left side after split on tab is wrong"); if (strcmp (_dbus_string_get_data (&other), "two") != 0) _dbus_assert_not_reached ("right side after split on tab is wrong"); _dbus_string_free (&str); _dbus_string_free (&other); } return TRUE; }
/** * Runs an "auth script" which is a script for testing the * authentication protocol. Scripts send and receive data, and then * include assertions about the state of both ends of the connection * after processing the data. A script succeeds if these assertions * hold. * * @param filename the file containing the script to run * @returns #TRUE if the script succeeds, #FALSE otherwise */ dbus_bool_t _dbus_auth_script_run (const DBusString *filename) { DBusString file; DBusError error = DBUS_ERROR_INIT; DBusString line; dbus_bool_t retval; int line_no; DBusAuth *auth; DBusString from_auth; DBusAuthState state; DBusString context; DBusString guid; retval = FALSE; auth = NULL; _dbus_string_init_const (&guid, "5fa01f4202cd837709a3274ca0df9d00"); _dbus_string_init_const (&context, "org_freedesktop_test"); if (!_dbus_string_init (&file)) return FALSE; if (!_dbus_string_init (&line)) { _dbus_string_free (&file); return FALSE; } if (!_dbus_string_init (&from_auth)) { _dbus_string_free (&file); _dbus_string_free (&line); return FALSE; } if (!_dbus_file_get_contents (&file, filename, &error)) { _dbus_warn ("Getting contents of %s failed: %s\n", _dbus_string_get_const_data (filename), error.message); dbus_error_free (&error); goto out; } state = DBUS_AUTH_STATE_NEED_DISCONNECT; line_no = 0; next_iteration: while (_dbus_string_pop_line (&file, &line)) { line_no += 1; /* _dbus_warn ("%s\n", _dbus_string_get_const_data (&line)); */ _dbus_string_delete_leading_blanks (&line); if (auth != NULL) { while ((state = _dbus_auth_do_work (auth)) == DBUS_AUTH_STATE_HAVE_BYTES_TO_SEND) { const DBusString *tmp; if (_dbus_auth_get_bytes_to_send (auth, &tmp)) { int count = _dbus_string_get_length (tmp); if (_dbus_string_copy (tmp, 0, &from_auth, _dbus_string_get_length (&from_auth))) _dbus_auth_bytes_sent (auth, count); } } } if (_dbus_string_get_length (&line) == 0) { /* empty line */ goto next_iteration; } else if (_dbus_string_starts_with_c_str (&line, "#")) { /* Ignore this comment */ goto next_iteration; } #ifdef DBUS_WIN else if (_dbus_string_starts_with_c_str (&line, "WIN_ONLY")) { /* Ignore this line */ goto next_iteration; } else if (_dbus_string_starts_with_c_str (&line, "UNIX_ONLY")) { /* skip this file */ _dbus_warn ("skipping unix only auth script\n"); retval = TRUE; goto out; } #endif #ifdef DBUS_UNIX else if (_dbus_string_starts_with_c_str (&line, "UNIX_ONLY")) { /* Ignore this line */ goto next_iteration; } else if (_dbus_string_starts_with_c_str (&line, "WIN_ONLY")) { /* skip this file */ _dbus_warn ("skipping windows only auth script\n"); retval = TRUE; goto out; } #endif else if (_dbus_string_starts_with_c_str (&line, "CLIENT")) { DBusCredentials *creds; if (auth != NULL) { _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n"); goto out; } auth = _dbus_auth_client_new (); if (auth == NULL) { _dbus_warn ("no memory to create DBusAuth\n"); goto out; } /* test ref/unref */ _dbus_auth_ref (auth); _dbus_auth_unref (auth); creds = _dbus_credentials_new_from_current_process (); if (creds == NULL) { _dbus_warn ("no memory for credentials\n"); _dbus_auth_unref (auth); auth = NULL; goto out; } if (!_dbus_auth_set_credentials (auth, creds)) { _dbus_warn ("no memory for setting credentials\n"); _dbus_auth_unref (auth); auth = NULL; _dbus_credentials_unref (creds); goto out; } _dbus_credentials_unref (creds); } else if (_dbus_string_starts_with_c_str (&line, "SERVER")) { DBusCredentials *creds; if (auth != NULL) { _dbus_warn ("already created a DBusAuth (CLIENT or SERVER given twice)\n"); goto out; } auth = _dbus_auth_server_new (&guid); if (auth == NULL) { _dbus_warn ("no memory to create DBusAuth\n"); goto out; } /* test ref/unref */ _dbus_auth_ref (auth); _dbus_auth_unref (auth); creds = _dbus_credentials_new_from_current_process (); if (creds == NULL) { _dbus_warn ("no memory for credentials\n"); _dbus_auth_unref (auth); auth = NULL; goto out; } if (!_dbus_auth_set_credentials (auth, creds)) { _dbus_warn ("no memory for setting credentials\n"); _dbus_auth_unref (auth); auth = NULL; _dbus_credentials_unref (creds); goto out; } _dbus_credentials_unref (creds); _dbus_auth_set_context (auth, &context); } else if (auth == NULL) { _dbus_warn ("must specify CLIENT or SERVER\n"); goto out; } else if (_dbus_string_starts_with_c_str (&line, "NO_CREDENTIALS")) { auth_set_unix_credentials (auth, DBUS_UID_UNSET, DBUS_PID_UNSET); } else if (_dbus_string_starts_with_c_str (&line, "ROOT_CREDENTIALS")) { auth_set_unix_credentials (auth, 0, DBUS_PID_UNSET); } else if (_dbus_string_starts_with_c_str (&line, "SILLY_CREDENTIALS")) { auth_set_unix_credentials (auth, 4312, DBUS_PID_UNSET); } else if (_dbus_string_starts_with_c_str (&line, "ALLOWED_MECHS")) { char **mechs; _dbus_string_delete_first_word (&line); mechs = split_string (&line); _dbus_auth_set_mechanisms (auth, (const char **) mechs); dbus_free_string_array (mechs); } else if (_dbus_string_starts_with_c_str (&line, "SEND")) { DBusString to_send; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&to_send)) { _dbus_warn ("no memory to allocate string\n"); goto out; } if (!append_quoted_string (&to_send, &line)) { _dbus_warn ("failed to append quoted string line %d\n", line_no); _dbus_string_free (&to_send); goto out; } _dbus_verbose ("Sending '%s'\n", _dbus_string_get_const_data (&to_send)); if (!_dbus_string_append (&to_send, "\r\n")) { _dbus_warn ("failed to append \r\n from line %d\n", line_no); _dbus_string_free (&to_send); goto out; } /* Replace USERID_HEX with our username in hex */ { int where; if (_dbus_string_find (&to_send, 0, "USERID_HEX", &where)) { DBusString username; if (!_dbus_string_init (&username)) { _dbus_warn ("no memory for userid\n"); _dbus_string_free (&to_send); goto out; } if (!_dbus_append_user_from_current_process (&username)) { _dbus_warn ("no memory for userid\n"); _dbus_string_free (&username); _dbus_string_free (&to_send); goto out; } _dbus_string_delete (&to_send, where, (int) strlen ("USERID_HEX")); if (!_dbus_string_hex_encode (&username, 0, &to_send, where)) { _dbus_warn ("no memory to subst USERID_HEX\n"); _dbus_string_free (&username); _dbus_string_free (&to_send); goto out; } _dbus_string_free (&username); } else if (_dbus_string_find (&to_send, 0, "USERNAME_HEX", &where)) { DBusString username; if (!_dbus_string_init (&username)) { _dbus_warn ("no memory for username\n"); _dbus_string_free (&to_send); goto out; } if (!_dbus_append_user_from_current_process (&username)) { _dbus_warn ("no memory for username\n"); _dbus_string_free (&username); _dbus_string_free (&to_send); goto out; } _dbus_string_delete (&to_send, where, (int) strlen ("USERNAME_HEX")); if (!_dbus_string_hex_encode (&username, 0, &to_send, where)) { _dbus_warn ("no memory to subst USERNAME_HEX\n"); _dbus_string_free (&username); _dbus_string_free (&to_send); goto out; } _dbus_string_free (&username); } } { DBusString *buffer; _dbus_auth_get_buffer (auth, &buffer); if (!_dbus_string_copy (&to_send, 0, buffer, _dbus_string_get_length (buffer))) { _dbus_warn ("not enough memory to call bytes_received, or can't add bytes to auth object already in end state\n"); _dbus_string_free (&to_send); _dbus_auth_return_buffer (auth, buffer); goto out; } _dbus_auth_return_buffer (auth, buffer); } _dbus_string_free (&to_send); } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_STATE")) { DBusAuthState expected; _dbus_string_delete_first_word (&line); expected = auth_state_from_string (&line); if (expected < 0) { _dbus_warn ("bad auth state given to EXPECT_STATE\n"); goto parse_failed; } if (expected != state) { _dbus_warn ("expected auth state %s but got %s on line %d\n", auth_state_to_string (expected), auth_state_to_string (state), line_no); goto out; } } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_COMMAND")) { DBusString received; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&received)) { _dbus_warn ("no mem to allocate string received\n"); goto out; } if (!_dbus_string_pop_line (&from_auth, &received)) { _dbus_warn ("no line popped from the DBusAuth being tested, expected command %s on line %d\n", _dbus_string_get_const_data (&line), line_no); _dbus_string_free (&received); goto out; } if (!same_first_word (&received, &line)) { _dbus_warn ("line %d expected command '%s' and got '%s'\n", line_no, _dbus_string_get_const_data (&line), _dbus_string_get_const_data (&received)); _dbus_string_free (&received); goto out; } _dbus_string_free (&received); } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_UNUSED")) { DBusString expected; const DBusString *unused; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&expected)) { _dbus_warn ("no mem to allocate string expected\n"); goto out; } if (!append_quoted_string (&expected, &line)) { _dbus_warn ("failed to append quoted string line %d\n", line_no); _dbus_string_free (&expected); goto out; } _dbus_auth_get_unused_bytes (auth, &unused); if (_dbus_string_equal (&expected, unused)) { _dbus_auth_delete_unused_bytes (auth); _dbus_string_free (&expected); } else { _dbus_warn ("Expected unused bytes '%s' and have '%s'\n", _dbus_string_get_const_data (&expected), _dbus_string_get_const_data (unused)); _dbus_string_free (&expected); goto out; } } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_HAVE_NO_CREDENTIALS")) { DBusCredentials *authorized_identity; authorized_identity = _dbus_auth_get_identity (auth); if (!_dbus_credentials_are_anonymous (authorized_identity)) { _dbus_warn ("Expected anonymous login or failed login, but some credentials were authorized\n"); goto out; } } else if (_dbus_string_starts_with_c_str (&line, "EXPECT_HAVE_SOME_CREDENTIALS")) { DBusCredentials *authorized_identity; authorized_identity = _dbus_auth_get_identity (auth); if (_dbus_credentials_are_anonymous (authorized_identity)) { _dbus_warn ("Expected to have some credentials, but we don't\n"); goto out; } } else if (_dbus_string_starts_with_c_str (&line, "EXPECT")) { DBusString expected; _dbus_string_delete_first_word (&line); if (!_dbus_string_init (&expected)) { _dbus_warn ("no mem to allocate string expected\n"); goto out; } if (!append_quoted_string (&expected, &line)) { _dbus_warn ("failed to append quoted string line %d\n", line_no); _dbus_string_free (&expected); goto out; } if (_dbus_string_equal_len (&expected, &from_auth, _dbus_string_get_length (&expected))) { _dbus_string_delete (&from_auth, 0, _dbus_string_get_length (&expected)); _dbus_string_free (&expected); } else { _dbus_warn ("Expected exact string '%s' and have '%s'\n", _dbus_string_get_const_data (&expected), _dbus_string_get_const_data (&from_auth)); _dbus_string_free (&expected); goto out; } } else goto parse_failed; goto next_iteration; /* skip parse_failed */ parse_failed: { _dbus_warn ("couldn't process line %d \"%s\"\n", line_no, _dbus_string_get_const_data (&line)); goto out; } } if (auth == NULL) { _dbus_warn ("Auth script is bogus, did not even have CLIENT or SERVER\n"); goto out; } else if (state == DBUS_AUTH_STATE_AUTHENTICATED) { const DBusString *unused; _dbus_auth_get_unused_bytes (auth, &unused); if (_dbus_string_get_length (unused) > 0) { _dbus_warn ("did not expect unused bytes (scripts must specify explicitly if they are expected)\n"); goto out; } } if (_dbus_string_get_length (&from_auth) > 0) { _dbus_warn ("script did not have EXPECT_ statements for all the data received from the DBusAuth\n"); _dbus_warn ("Leftover data: %s\n", _dbus_string_get_const_data (&from_auth)); goto out; } retval = TRUE; out: if (auth) _dbus_auth_unref (auth); _dbus_string_free (&file); _dbus_string_free (&line); _dbus_string_free (&from_auth); return retval; }