*/
#include "config.h"
-#include "galias.h"
#include "gkeyfile.h"
#include "gstrfuncs.h"
#include "gutils.h"
+#include "galias.h"
+
typedef struct _GKeyFileGroup GKeyFileGroup;
struct _GKeyFile
if (output_file != NULL && fd > 0)
*output_file = g_strdup (path);
+ g_free (path);
+
return fd;
}
GError **error)
{
GError *key_file_error = NULL;
- gsize bytes_read;
+ gssize bytes_read;
struct stat stat_buf;
gchar read_buf[4096];
found_file = FALSE;
data_dirs = all_data_dirs;
+ output_path = NULL;
while (*data_dirs != NULL && !found_file)
{
+ g_free (output_path);
+
fd = find_file_in_data_dirs (file, &output_path, &data_dirs,
&key_file_error);
{
if (key_file_error)
g_propagate_error (error, key_file_error);
- break;
+ break;
}
found_file = g_key_file_load_from_fd (key_file, fd, flags,
if (key_file_error)
{
g_propagate_error (error, key_file_error);
- g_free (output_path);
break;
}
-
- if (full_path)
- *full_path = output_path;
}
+ if (found_file && full_path)
+ *full_path = output_path;
+ else
+ g_free (output_path);
+
g_strfreev (all_data_dirs);
+
return found_file;
}
return NULL;
}
- num_keys = g_list_length (group->key_value_pairs);
+ num_keys = 0;
+ for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (pair->key)
+ num_keys++;
+ }
- keys = (gchar **) g_new0 (gchar **, num_keys + 1);
+ keys = g_new0 (gchar *, num_keys + 1);
- tmp = group->key_value_pairs;
- for (i = 1; i <= num_keys; i++)
+ i = num_keys - 1;
+ for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
{
GKeyFileKeyValuePair *pair;
pair = (GKeyFileKeyValuePair *) tmp->data;
- keys[num_keys - i] = g_strdup (pair->key);
- tmp = tmp->next;
+ if (pair->key)
+ {
+ keys[i] = g_strdup (pair->key);
+ i--;
+ }
}
+
keys[num_keys] = NULL;
if (length)
* event that the @group_name cannot be found, %NULL is returned
* and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
*
- * Return value: a string or %NULL if the specified key cannot be
- * found.
+ * Return value: a newly allocated string or %NULL if the specified
+ * key cannot be found.
*
* Since: 2.6
**/
* event that the @group_name cannot be found, %NULL is returned
* and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
*
- * Return value: a string or %NULL if the specified key cannot be
- * found.
+ * Return value: a newly allocated string or %NULL if the specified
+ * key cannot be found.
*
* Since: 2.6
**/
* with @key cannot be interpreted or no suitable translation can
* be found then the untranslated value is returned.
*
- * Return value: a string or %NULL if the specified key cannot be
- * found.
+ * Return value: a newly allocated string or %NULL if the specified
+ * key cannot be found.
+ *
* Since: 2.6
**/
gchar *
*
* Returns the values associated with @key under @group_name
* translated in the given @locale if available. If @locale is
- * %NULL then the current locale is assumed. If @group_name is
- * %NULL, then the start group is used.
+ * %NULL then the current locale is assumed.
* If @key cannot be found then %NULL is returned and @error is set to
* #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated
*
* Associates a list of string values for @key and @locale under
* @group_name. If the translation for @key cannot be found then
- * it is created. If @group_name is %NULL, the start group is
- * used.
+ * it is created.
*
* Since: 2.6
**/
* @error: return location for a #GError
*
* Returns the value associated with @key under @group_name as a
- * boolean. If @group_name is %NULL, the start group is used.
+ * boolean.
*
* If @key cannot be found then the return value is undefined and
* @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
* @value: %TRUE or %FALSE
*
* Associates a new boolean value with @key under @group_name.
- * If @key cannot be found then it is created. If @group_name
- * is %NULL, the start group is used.
+ * If @key cannot be found then it is created.
*
* Since: 2.6
**/
* @value: an integer value
*
* Associates a new integer value with @key under @group_name.
- * If @key cannot be found then it is created. If @group_name
- * is %NULL, the start group is used.
+ * If @key cannot be found then it is created.
*
* Since: 2.6
**/
* @error: return location for a #GError
*
* Returns the values associated with @key under @group_name as
- * integers. If @group_name is %NULL, the start group is used.
+ * integers.
*
* If @key cannot be found then the return value is undefined and
* @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if
*
* Associates a list of integer values with @key under
* @group_name. If @key cannot be found then it is created.
- * If @group_name is %NULL the start group is used.
*
* Since: 2.6
**/
GError **error)
{
GKeyFileGroup *group;
+ GKeyFileKeyValuePair *pair;
GList *key_node, *tmp;
GString *string;
gchar *comment;
* key and concatentate them.
*/
tmp = key_node->next;
- while (tmp != NULL)
- {
- GKeyFileKeyValuePair *pair;
+ if (!key_node->next)
+ return NULL;
- pair = (GKeyFileKeyValuePair *) tmp->data;
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+ if (pair->key != NULL)
+ return NULL;
+ while (tmp->next)
+ {
+ pair = (GKeyFileKeyValuePair *) tmp->next->data;
+
if (pair->key != NULL)
break;
+
+ tmp = tmp->next;
+ }
+
+ while (tmp != key_node)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
if (string == NULL)
- string = g_string_sized_new (512);
-
+ string = g_string_sized_new (512);
+
comment = g_key_file_parse_value_as_comment (key_file, pair->value);
g_string_append (string, comment);
g_free (comment);
-
- tmp = tmp->next;
+
+ tmp = tmp->prev;
}
if (string != NULL)
}
static gchar *
+get_group_comment (GKeyFile *key_file,
+ GKeyFileGroup *group,
+ GError **error)
+{
+ GString *string;
+ GList *tmp;
+ gchar *comment;
+
+ string = NULL;
+
+ tmp = group->key_value_pairs;
+ while (tmp)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (pair->key != NULL)
+ {
+ tmp = tmp->prev;
+ break;
+ }
+
+ if (tmp->next == NULL)
+ break;
+
+ tmp = tmp->next;
+ }
+
+ while (tmp != NULL)
+ {
+ GKeyFileKeyValuePair *pair;
+
+ pair = (GKeyFileKeyValuePair *) tmp->data;
+
+ if (string == NULL)
+ string = g_string_sized_new (512);
+
+ comment = g_key_file_parse_value_as_comment (key_file, pair->value);
+ g_string_append (string, comment);
+ g_free (comment);
+
+ tmp = tmp->prev;
+ }
+
+ if (string != NULL)
+ return g_string_free (string, FALSE);
+
+ return NULL;
+}
+
+static gchar *
g_key_file_get_group_comment (GKeyFile *key_file,
const gchar *group_name,
GError **error)
{
+ GList *group_node;
GKeyFileGroup *group;
- group = g_key_file_lookup_group (key_file, group_name);
+ group_node = g_key_file_lookup_group_node (key_file, group_name);
+ group = (GKeyFileGroup *)group_node->data;
if (!group)
{
g_set_error (error, G_KEY_FILE_ERROR,
if (group->comment)
return g_strdup (group->comment->value);
-
- return NULL;
+
+ group_node = group_node->next;
+ group = (GKeyFileGroup *)group_node->data;
+ return get_group_comment (key_file, group, error);
}
static gchar *
g_key_file_get_top_comment (GKeyFile *key_file,
GError **error)
{
- GList *group_node, *tmp;
+ GList *group_node;
GKeyFileGroup *group;
- GString *string;
- gchar *comment;
/* The last group in the list should be the top (comments only)
* group in the file
group = (GKeyFileGroup *) group_node->data;
g_assert (group->name == NULL);
- string = NULL;
-
- /* Then find all the comments already associated with the
- * key and concatentate them.
- */
- tmp = group->key_value_pairs;
- while (tmp != NULL)
- {
- GKeyFileKeyValuePair *pair;
-
- pair = (GKeyFileKeyValuePair *) tmp->data;
-
- if (pair->key != NULL)
- break;
-
- if (string == NULL)
- string = g_string_sized_new (512);
-
- comment = g_key_file_parse_value_as_comment (key_file, pair->value);
- g_string_append (string, comment);
- g_free (comment);
-
- tmp = tmp->next;
- }
-
- if (string != NULL)
- {
- comment = string->str;
- g_string_free (string, FALSE);
- }
- else
- comment = NULL;
-
- return comment;
+ return get_group_comment (key_file, group, error);
}
/**
* @key: a key
* @error: return location for a #GError
*
- * Retreives a comment above @key from @group_name.
+ * Retrieves a comment above @key from @group_name.
* @group_name. If @key is %NULL then @comment will
* be read from above @group_name. If both @key
* and @group_name are NULL, then @comment will
* be read from above the first group in the file.
*
- * Since: 2.6
* Returns: a comment that should be freed with g_free()
+ *
+ * Since: 2.6
**/
gchar *
g_key_file_get_comment (GKeyFile *key_file,
* @error: return location for a #GError
*
* Looks whether the key file has the key @key in the group
- * @group_name. If @group_name is %NULL, the start group is
- * used.
+ * @group_name.
*
* Return value: %TRUE if @key is a part of @group_name, %FALSE
* otherwise.
group_node = g_key_file_lookup_group_node (key_file, group_name);
if (!group_node)
- g_set_error (error, G_KEY_FILE_ERROR,
- G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
- _("Key file does not have group '%s'"),
- group_name);
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+ _("Key file does not have group '%s'"),
+ group_name);
+ return;
+ }
- g_key_file_remove_group_node (key_file, group_node);
+ g_key_file_remove_group_node (key_file, group_node);
}
static void
return;
}
- group->key_value_pairs = g_list_remove (group->key_value_pairs, key_file);
pair = g_key_file_lookup_key_value_pair (key_file, group, key);
if (!pair)
return;
}
- g_hash_table_remove (group->lookup_map, pair->key);
-
key_file->approximate_size -= strlen (pair->key) + strlen (pair->value) + 2;
+
+ group->key_value_pairs = g_list_remove (group->key_value_pairs, pair);
+ g_hash_table_remove (group->lookup_map, pair->key);
g_key_file_key_value_pair_free (pair);
}
*q = '\\';
break;
+ case '\0':
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Key file contains escape character "
+ "at end of line"));
+ break;
+
default:
if (pieces && *p == key_file->list_separator)
*q = key_file->list_separator;
}
}
+ if (*p == '\0')
+ break;
+
q++;
p++;
}
- if (p > value && p[-1] == '\\' && q[-1] != '\\' && *error == NULL)
- g_set_error (error, G_KEY_FILE_ERROR,
- G_KEY_FILE_ERROR_INVALID_VALUE,
- _("Key file contains escape character at end of line"));
-
*q = '\0';
if (pieces)
{
GError **error)
{
gchar *end_of_valid_int;
- gint int_value = 0;
+ glong long_value;
+ gint int_value;
- int_value = strtol (value, &end_of_valid_int, 10);
+ errno = 0;
+ long_value = strtol (value, &end_of_valid_int, 10);
- if (*end_of_valid_int != '\0')
- g_set_error (error, G_KEY_FILE_ERROR,
- G_KEY_FILE_ERROR_INVALID_VALUE,
- _("Value '%s' cannot be interpreted as a number."), value);
+ if (*value == '\0' || *end_of_valid_int != '\0')
+ {
+ g_set_error (error, G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Value '%s' cannot be interpreted as a number."), value);
+ return 0;
+ }
+ int_value = long_value;
+ if (int_value != long_value || errno == ERANGE)
+ {
+ g_set_error (error,
+ G_KEY_FILE_ERROR,
+ G_KEY_FILE_ERROR_INVALID_VALUE,
+ _("Integer value '%s' out of range"), value);
+ return 0;
+ }
+
return int_value;
}
return value;
}
-
+#define __G_KEY_FILE_C__
+#include "galiasdef.c"