diff options
author | Havoc Pennington <hp@redhat.com> | 2003-03-13 00:56:43 +0000 |
---|---|---|
committer | Havoc Pennington <hp@redhat.com> | 2003-03-13 00:56:43 +0000 |
commit | 29560adcc79a259a0be3511c056ee7453aa26c04 (patch) | |
tree | 57e72dd26b5876da48379e5ff910c63e66cb7001 /bus/desktop-file.c | |
parent | 799a3ff443f5357ae7857ebe989a7f92f7bd84df (diff) | |
download | dbus-29560adcc79a259a0be3511c056ee7453aa26c04.tar.gz |
2003-03-12 Havoc Pennington <hp@redhat.com>
Mega-patch that gets the message bus daemon initially handling
out-of-memory. Work still needed. Also lots of random
moving stuff to DBusError instead of ResultCode.
* dbus/dbus-list.c (_dbus_list_length_is_one): new function
* dbus/dbus-connection.c
(dbus_connection_send_with_reply_and_block): use DBusError
* dbus/dbus-bus.c: adapt to API changes, make it use DBusError not
DBusResultCode
* dbus/dbus-connection.c (dbus_connection_send): drop the result
code here, as the only failure possible is OOM.
* bus/connection.c (bus_connection_disconnect):
rename bus_connection_disconnected as it's a notification only
* bus/driver.c (bus_driver_handle_acquire_service): don't free
"name" on get_args failure, should be done by get_args;
don't disconnect client for bad args, just return an error.
(bus_driver_handle_service_exists): ditto
* bus/services.c (bus_services_list): NULL-terminate returned array
* bus/driver.c (bus_driver_send_service_lost)
(bus_driver_send_service_acquired): send messages from driver to a
specific client to the client's unique name, not to the broadcast
service.
* dbus/dbus-message.c (decode_header_data): reject messages that
contain no name field
(_dbus_message_get_client_serial): rename to
dbus_message_get_serial and make public
(_dbus_message_set_serial): rename from set_client_serial
(_dbus_message_set_reply_serial): make public
(_dbus_message_get_reply_serial): make public
* bus/connection.c (bus_connection_foreach): allow stopping
iteration by returning FALSE from foreach function.
* dbus/dbus-connection.c (dbus_connection_send_preallocated)
(dbus_connection_free_preallocated_send)
(dbus_connection_preallocate_send): new API for sending a message
without possibility of malloc failure.
(dbus_connection_send_message): rename to just
dbus_connection_send (and same for whole function family)
* dbus/dbus-errors.c (dbus_error_free): make this reinit the error
* dbus/dbus-sysdeps.c (_dbus_exit): new function
* bus/activation.c: handle/return errors
* dbus/dbus-errors.h: add more DBUS_ERROR #define
* dbus/dbus-sysdeps.c (_dbus_directory_open) (_dbus_file_get_contents)
(_dbus_directory_get_next_file): use DBusError instead of DBusResultCode
(_dbus_result_from_errno): move to this file
Diffstat (limited to 'bus/desktop-file.c')
-rw-r--r-- | bus/desktop-file.c | 180 |
1 files changed, 134 insertions, 46 deletions
diff --git a/bus/desktop-file.c b/bus/desktop-file.c index 0ab6afc8..65a0d76f 100644 --- a/bus/desktop-file.c +++ b/bus/desktop-file.c @@ -125,7 +125,7 @@ bus_desktop_file_free (BusDesktopFile *desktop_file) dbus_free (desktop_file); } -static void +static dbus_bool_t grow_lines_in_section (BusDesktopFileSection *section) { BusDesktopFileLine *lines; @@ -137,14 +137,19 @@ grow_lines_in_section (BusDesktopFileSection *section) else new_n_lines = section->n_allocated_lines*2; - BUS_HANDLE_OOM (lines = dbus_realloc (section->lines, - sizeof (BusDesktopFileLine) * new_n_lines)); - section->lines = lines; + lines = dbus_realloc (section->lines, + sizeof (BusDesktopFileLine) * new_n_lines); + + if (lines == NULL) + return FALSE; + section->lines = lines; section->n_allocated_lines = new_n_lines; + + return TRUE; } -static void +static dbus_bool_t grow_sections (BusDesktopFile *desktop_file) { int new_n_sections; @@ -155,21 +160,36 @@ grow_sections (BusDesktopFile *desktop_file) else new_n_sections = desktop_file->n_allocated_sections*2; - BUS_HANDLE_OOM (sections = dbus_realloc (desktop_file->sections, - sizeof (BusDesktopFileSection) * new_n_sections)); + sections = dbus_realloc (desktop_file->sections, + sizeof (BusDesktopFileSection) * new_n_sections); + if (sections == NULL) + return FALSE; + desktop_file->sections = sections; desktop_file->n_allocated_sections = new_n_sections; + + return TRUE; } static char * -unescape_string (const DBusString *str, int pos, int end_pos) +unescape_string (BusDesktopFileParser *parser, + const DBusString *str, + int pos, + int end_pos, + DBusError *error) { char *retval, *q; /* len + 1 is enough, because unescaping never makes the - * string longer */ - BUS_HANDLE_OOM (retval = dbus_malloc (end_pos - pos + 1)); + * string longer + */ + retval = dbus_malloc (end_pos - pos + 1); + if (retval == NULL) + { + BUS_SET_OOM (error); + return NULL; + } q = retval; @@ -179,6 +199,8 @@ unescape_string (const DBusString *str, int pos, int end_pos) { /* Found an embedded null */ dbus_free (retval); + report_error (parser, "Text to be unescaped contains embedded nul", + BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); return NULL; } @@ -190,6 +212,8 @@ unescape_string (const DBusString *str, int pos, int end_pos) { /* Escape at end of string */ dbus_free (retval); + report_error (parser, "Text to be unescaped ended in \\", + BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); return NULL; } @@ -213,7 +237,9 @@ unescape_string (const DBusString *str, int pos, int end_pos) default: /* Invalid escape code */ dbus_free (retval); - return NULL; + report_error (parser, "Text to be unescaped had invalid escape sequence", + BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); + return NULL; } pos++; } @@ -235,20 +261,34 @@ new_section (BusDesktopFile *desktop_file, const char *name) { int n; + char *name_copy; if (desktop_file->n_allocated_sections == desktop_file->n_sections) - grow_sections (desktop_file); - - n = desktop_file->n_sections++; + { + if (!grow_sections (desktop_file)) + return NULL; + } - BUS_HANDLE_OOM (desktop_file->sections[n].section_name = _dbus_strdup (name)); + name_copy = _dbus_strdup (name); + if (name_copy == NULL) + return NULL; + + n = desktop_file->n_sections + 1; + desktop_file->sections[n].section_name = name_copy; desktop_file->sections[n].n_lines = 0; desktop_file->sections[n].lines = NULL; desktop_file->sections[n].n_allocated_lines = 0; - grow_lines_in_section (&desktop_file->sections[n]); + if (!grow_lines_in_section (&desktop_file->sections[n])) + { + dbus_free (desktop_file->sections[n].section_name); + desktop_file->sections[n].section_name = NULL; + return NULL; + } + desktop_file->n_sections = n; + return &desktop_file->sections[n]; } @@ -277,7 +317,10 @@ new_line (BusDesktopFileParser *parser) section = &parser->desktop_file->sections[parser->current_section]; if (section->n_allocated_lines == section->n_lines) - grow_lines_in_section (section); + { + if (!grow_lines_in_section (section)) + return NULL; + } line = §ion->lines[section->n_lines++]; @@ -358,11 +401,12 @@ parse_section_start (BusDesktopFileParser *parser, DBusError *error) return FALSE; } - section_name = unescape_string (&parser->data, parser->pos + 1, line_end - 1); + section_name = unescape_string (parser, + &parser->data, parser->pos + 1, line_end - 1, + error); if (section_name == NULL) { - report_error (parser, "Invalid escaping in section name", BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); parser_free (parser); return FALSE; } @@ -450,20 +494,39 @@ parse_key_value (BusDesktopFileParser *parser, DBusError *error) value_start = p; - value = unescape_string (&parser->data, value_start, line_end); + value = unescape_string (parser, &parser->data, value_start, line_end, error); if (value == NULL) { - report_error (parser, "Invalid escaping in value", BUS_DESKTOP_PARSE_ERROR_INVALID_ESCAPES, error); parser_free (parser); return FALSE; } line = new_line (parser); - - BUS_HANDLE_OOM (_dbus_string_init (&key, key_end - key_start)); - BUS_HANDLE_OOM (_dbus_string_copy_len (&parser->data, key_start, key_end - key_start, - &key, 0)); - BUS_HANDLE_OOM (_dbus_string_steal_data (&key, &tmp)); + if (line == NULL) + { + parser_free (parser); + return FALSE; + } + + if (!_dbus_string_init (&key, key_end - key_start)) + { + 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; @@ -491,11 +554,11 @@ report_error (BusDesktopFileParser *parser, section_name = parser->desktop_file->sections[parser->current_section].section_name; if (section_name) - BUS_HANDLE_OOM (dbus_set_error (error, error_name, - "Error in section %s at line %d: %s\n", section_name, parser->line_num, message)); + dbus_set_error (error, error_name, + "Error in section %s at line %d: %s\n", section_name, parser->line_num, message); else - BUS_HANDLE_OOM (dbus_set_error (error, error_name, - "Error at line %d: %s\n", parser->line_num, message)); + dbus_set_error (error, error_name, + "Error at line %d: %s\n", parser->line_num, message); } #if 0 @@ -519,39 +582,52 @@ dump_desktop_file (BusDesktopFile *file) } #endif -BusDesktopFile * +BusDesktopFile* bus_desktop_file_load (DBusString *filename, DBusError *error) { DBusString str; - DBusResultCode result_code; BusDesktopFileParser parser; + DBusStat sb; - /* FIXME: Check file size so we don't try to load a ridicously large file. */ + /* Clearly there's a race here, but it's just to make it unlikely + * that we do something silly, we still handle doing it below. + */ + if (!_dbus_stat (filename, &sb, error)) + return NULL; - BUS_HANDLE_OOM (_dbus_string_init (&str, _DBUS_INT_MAX)); + if (sb.size > _DBUS_ONE_KILOBYTE * 128) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Desktop file size (%ld bytes) is too large", (long) sb.size); + return NULL; + } - BUS_HANDLE_OOM ((result_code = _dbus_file_get_contents (&str, filename)) != - DBUS_RESULT_NO_MEMORY); + if (!_dbus_string_init (&str, _DBUS_INT_MAX)) + return NULL; - if (result_code != DBUS_RESULT_SUCCESS) + if (!_dbus_file_get_contents (&str, filename, error)) { _dbus_string_free (&str); - - /* FIXME: Set error */ return NULL; } if (!_dbus_string_validate_utf8 (&str, 0, _dbus_string_get_length (&str))) { _dbus_string_free (&str); - - /* FIXME: Set error */ + dbus_set_error (error, DBUS_ERROR_FAILED, + "invalid UTF-8"); + return NULL; + } + + parser.desktop_file = dbus_new0 (BusDesktopFile, 1); + if (parser.desktop_file == NULL) + { + _dbus_string_free (&str); + BUS_SET_OOM (error); return NULL; } - BUS_HANDLE_OOM (parser.desktop_file = dbus_malloc0 (sizeof (BusDesktopFile))); - parser.data = str; parser.line_num = 1; parser.pos = 0; @@ -563,7 +639,10 @@ bus_desktop_file_load (DBusString *filename, if (_dbus_string_get_byte (&parser.data, parser.pos) == '[') { if (!parse_section_start (&parser, error)) - return NULL; + { + _dbus_string_free (&parser.data); + return NULL; + } } else if (is_blank_line (&parser) || _dbus_string_get_byte (&parser.data, parser.pos) == '#') @@ -571,7 +650,10 @@ bus_desktop_file_load (DBusString *filename, else { if (!parse_key_value (&parser, error)) - return NULL; + { + _dbus_string_free (&parser.data); + return NULL; + } } } @@ -661,7 +743,13 @@ bus_desktop_file_get_string (BusDesktopFile *desktop_file, if (!bus_desktop_file_get_raw (desktop_file, section, keyname, &raw)) return FALSE; - BUS_HANDLE_OOM (*val = _dbus_strdup (raw)); + *val = _dbus_strdup (raw); + + /* FIXME we don't distinguish "key not found" from "out of memory" here, + * which is broken. + */ + if (*val == NULL) + return FALSE; return TRUE; } |