Merge "Optional autogen.sh flag --enable-kdbus-transport added allowing to compile...
[platform/upstream/dbus.git] / bus / desktop-file.c
index 59f0f50..bfeb72e 100644 (file)
@@ -1,10 +1,10 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 /* desktop-file.c  .desktop file parser
  *
  * Copyright (C) 2003  CodeFactory AB
  * Copyright (C) 2003  Red Hat Inc.
  *
- * Licensed under the Academic Free License version 2.0
+ * Licensed under the Academic Free License version 2.1
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * 
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
+
+#include <config.h>
 #include <dbus/dbus-sysdeps.h>
 #include <dbus/dbus-internals.h>
 #include "desktop-file.h"
@@ -66,7 +68,7 @@ typedef struct
 
 #define VALID_KEY_CHAR 1
 #define VALID_LOCALE_CHAR 2
-unsigned char valid[256] = { 
+static unsigned char valid[256] = { 
    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 
    0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x0 , 0x3 , 0x2 , 0x0 , 
@@ -330,7 +332,7 @@ new_line (BusDesktopFileParser *parser)
 
   line = &section->lines[section->n_lines++];
 
-  memset (line, 0, sizeof (BusDesktopFileLine));
+  _DBUS_ZERO(*line);
     
   return line;
 }
@@ -360,15 +362,15 @@ is_blank_line (BusDesktopFileParser *parser)
 static void
 parse_comment_or_blank (BusDesktopFileParser *parser)
 {
-  int line_end;
+  int line_end, eol_len;
   
-  if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
+  if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len))
     line_end = parser->len;
 
   if (line_end == parser->len)
     parser->pos = parser->len;
   else
-    parser->pos = line_end + 1;
+    parser->pos = line_end + eol_len;
   
   parser->line_num += 1;
 }
@@ -393,12 +395,12 @@ is_valid_section_name (const char *name)
 static dbus_bool_t
 parse_section_start (BusDesktopFileParser *parser, DBusError *error)
 {
-  int line_end;
+  int line_end, eol_len;
   char *section_name;
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
-  
-  if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
+    
+  if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len))
     line_end = parser->len;
   
   if (line_end - parser->pos <= 2 ||
@@ -430,13 +432,15 @@ parse_section_start (BusDesktopFileParser *parser, DBusError *error)
   if (open_section (parser, section_name) == NULL)
     {
       dbus_free (section_name);
+      parser_free (parser);
+      BUS_SET_OOM (error);
       return FALSE;
     }
 
   if (line_end == parser->len)
     parser->pos = parser->len;
   else
-    parser->pos = line_end + 1;
+    parser->pos = line_end + eol_len;
   
   parser->line_num += 1;
 
@@ -448,7 +452,7 @@ parse_section_start (BusDesktopFileParser *parser, DBusError *error)
 static dbus_bool_t
 parse_key_value (BusDesktopFileParser *parser, DBusError *error)
 {
-  int line_end;
+  int line_end, eol_len;
   int key_start, key_end;
   int value_start;
   int p;
@@ -458,9 +462,9 @@ parse_key_value (BusDesktopFileParser *parser, DBusError *error)
 
   _DBUS_ASSERT_ERROR_IS_CLEAR (error);
   
-  if (!_dbus_string_find (&parser->data, parser->pos, "\n", &line_end))
+  if (!_dbus_string_find_eol (&parser->data, parser->pos, &line_end, &eol_len))
     line_end = parser->len;
-
+  
   p = parser->pos;
   key_start = p;
   while (p < line_end &&
@@ -476,6 +480,17 @@ parse_key_value (BusDesktopFileParser *parser, DBusError *error)
     }
 
   /* 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 + eol_len;
+         
+      parser->line_num += 1;
+
+      return TRUE;
+    }
   
   /* Skip space before '=' */
   while (p < line_end && _dbus_string_get_byte (&parser->data, p) == ' ')
@@ -514,26 +529,36 @@ parse_key_value (BusDesktopFileParser *parser, DBusError *error)
   line = new_line (parser);
   if (line == NULL)
     {
+      dbus_free (value);
       parser_free (parser);
+      BUS_SET_OOM (error);
       return FALSE;
     }
   
   if (!_dbus_string_init (&key))
     {
+      dbus_free (value);
       parser_free (parser);
+      BUS_SET_OOM (error);
       return FALSE;
     }
   
   if (!_dbus_string_copy_len (&parser->data, key_start, key_end - key_start,
                               &key, 0))
     {
+      _dbus_string_free (&key);
+      dbus_free (value);
       parser_free (parser);
+      BUS_SET_OOM (error);
       return FALSE;
     }
   
   if (!_dbus_string_steal_data (&key, &tmp))
     {
+      _dbus_string_free (&key);
+      dbus_free (value);
       parser_free (parser);
+      BUS_SET_OOM (error);
       return FALSE;
     }
   
@@ -545,7 +570,7 @@ parse_key_value (BusDesktopFileParser *parser, DBusError *error)
   if (line_end == parser->len)
     parser->pos = parser->len;
   else
-    parser->pos = line_end + 1;
+    parser->pos = line_end + eol_len;
   
   parser->line_num += 1;
 
@@ -618,7 +643,10 @@ bus_desktop_file_load (DBusString *filename,
     }
   
   if (!_dbus_string_init (&str))
-    return NULL;
+    {
+      BUS_SET_OOM (error);
+      return NULL;
+    }
   
   if (!_dbus_file_get_contents (&str, filename, error))
     {
@@ -647,25 +675,29 @@ bus_desktop_file_load (DBusString *filename,
   parser.pos = 0;
   parser.len = _dbus_string_get_length (&parser.data);
   parser.current_section = -1;
-  
+
   while (parser.pos < parser.len)
     {
       if (_dbus_string_get_byte (&parser.data, parser.pos) == '[')
        {
          if (!parse_section_start (&parser, error))
             {
-              _dbus_string_free (&parser.data);
               return NULL;
             }
        }
       else if (is_blank_line (&parser) ||
               _dbus_string_get_byte (&parser.data, parser.pos) == '#')
        parse_comment_or_blank (&parser);
+      else if (parser.current_section < 0)
+       {
+           dbus_set_error(error, DBUS_ERROR_FAILED,
+                          "invalid service file: key=value before [Section]");
+           return NULL;
+       }
       else
        {
          if (!parse_key_value (&parser, error))
             {
-              _dbus_string_free (&parser.data);
               return NULL;
             }
        }
@@ -748,22 +780,29 @@ dbus_bool_t
 bus_desktop_file_get_string (BusDesktopFile  *desktop_file,
                             const char      *section,
                             const char      *keyname,
-                            char           **val)
+                            char           **val,
+                            DBusError       *error)
 {
   const char *raw;
-  
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+
   *val = NULL;
   
   if (!bus_desktop_file_get_raw (desktop_file, section, keyname, &raw))
-    return FALSE;
+    {
+      dbus_set_error (error, DBUS_ERROR_FAILED,
+                      "No \"%s\" key in .service file\n", keyname);
+      return FALSE;
+    }
 
   *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;
+    {
+      BUS_SET_OOM (error);
+      return FALSE;
+    }
   
   return TRUE;
 }