Merge lp:~compiz-team/compiz/compiz.fix_1018602 into lp:compiz/0.9.8

Proposed by Sam Spilsbury
Status: Merged
Merged at revision: 3267
Proposed branch: lp:~compiz-team/compiz/compiz.fix_1018602
Merge into: lp:compiz/0.9.8
Diff against target: 497 lines (+120/-96)
1 file modified
compizconfig/gsettings/src/gsettings.c (+120/-96)
To merge this branch: bzr merge lp:~compiz-team/compiz/compiz.fix_1018602
Reviewer Review Type Date Requested Status
Daniel van Vugt Approve
Review via email: mp+112718@code.launchpad.net

This proposal supersedes a proposal from 2012-06-29.

Description of the change

Fixes LP (#1018602) : An invalid read when using g_variant_iter_loop.

No tests yet, tests will be added to gsettings in another commit when the lcc testing work lands.

To post a comment you must log in.
Revision history for this message
Daniel van Vugt (vanvugt) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Oops. There is a problem under case TypeMatch:
array is no longer initialized with zeros because you changed calloc to malloc. So the free() loop after it could potentially free an invalid pointer if g_variant_iter_loop doesn't find exactly nItems.

Also, strdup(value) is not necessary if you use:
     while (g_variant_iter_next (iter, "s", &value))
  *arrayCounter++ = value;
and then change the free() calls below it to g_free().

On that note, the variable variantType should be removed from readListValue. Just use "s", "i", "b" and "d" instead. It will be smaller, faster and more readable.

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Coolio, fixed the calloc issue, plugged a few other memleaks and fixed some gvariant errors I noticed.

I abstracted out the variantType stuff into a function - it should probably be transparent to the user as to the implementation detail of having to pass an arbitrary string to g_variant_get

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Thanks for the tip on using g_variant_iter_next ... that's now fixed too.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

The addition of compizconfigTypeToVariantType makes no sense.

We already have a tight coupling between:
    TYPE x;
and:
    g_variant_iter_loop (&iter, TYPESTRING, &x)

Using:
    g_variant_iter_loop (&iter, someVariable, &x)
only makes the code harder to read, with looser coupling and weaker cohesion.

Please remove compizconfigTypeToVariantType and just use:
    g_variant_iter_loop (&iter, "X", &x)

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

It's the same as:
    printf(secretFormatString, x, y, z);
It's too hard to read so adds maintenance risk.

Everyone would much prefer to read:
    printf("The results are: %d %s %f\n", x, y, z);

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I think the printf analogy in this case doesn't apply here, the type string is merely an implementation detail - we know from the code what we want to extract already, and the type string is there to operate the valist API.

In any case, I'll change it.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Maybe. But back to the actual case of g_variant_iter_loop(I, F, V)... F and V are tightly coupled and need to match up so you should see the explicit value of F and type of V within the same block of code...

int v;
g_variant_iter_loop(&x, "i", &v)

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

I had another look at the code and variantType is more or less used as a placeholder so that copypasting was easier and so that we could return if there was no variant type for that setting. The fact that we are copypasting is a problem, but I modified the function so that it returns a boolean for whether or not we can read that type of setting.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

It works OK, but I can see some potentially serious mistakes:

203: "f" should be "d"
(http://developer.gnome.org/glib/2.30/glib-GVariant.html#GVariantClass)

235: Missing g_free() loop:
    for (i = 0; i < nItems; i++)
        if (array[i])
            g_free(array[i]);

239: g_free() on calloc'd block (214). Either change g_free() to free(), or calloc() to g_malloc0().

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

> It works OK, but I can see some potentially serious mistakes:
>
> 203: "f" should be "d"
> (http://developer.gnome.org/glib/2.30/glib-GVariant.html#GVariantClass)

Thanks, fixed.

>
> 235: Missing g_free() loop:
> for (i = 0; i < nItems; i++)
> if (array[i])
> g_free(array[i]);

My understanding is that g_variant_iter_next returns a shallow copy of the array, so free () is sufficient in this case (unlike the previous code where we copied the values out of the array. Valgrind reports there are no leaks here.

>
> 239: g_free() on calloc'd block (214). Either change g_free() to free(), or
> calloc() to g_malloc0().

Fixed, although I think g_malloc is a wrapper around malloc itself (eg, doesn't use g_slice_alloc)

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

No, you still need the g_free loop to free each array element after g_variant_iter_next:
  http://developer.gnome.org/glib/2.32/glib-GVariant.html#g-variant-iter-next
It's possible valgrind doesn't see the leak because the memory is managed by glib and freed at exit. But it's still a leak even still.

Also, I was referring to g_malloc0() to replace calloc. Not g_malloc(). :)

review: Needs Fixing
Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

You're right, I was confusing the array with the values themselves. Fixing it now.

Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Still needs fixing. Please don't click resubmit till after you've pushed the changes.

review: Needs Fixing
Revision history for this message
Daniel van Vugt (vanvugt) wrote : Posted in a previous version of this proposal

Sorry, my fault. I commented on an old version of the proposal. But still needs fixing.

Revision history for this message
Sam Spilsbury (smspillaz) wrote : Posted in a previous version of this proposal

Fixed that, plugged other memleaks.

Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Thanks for the extra leak fixes but they're not part of fixing the crash.

I give up. It looks OK now but I don't want to manually test and valgrind it again. We'll be valgrinding a lot more in the near future.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'compizconfig/gsettings/src/gsettings.c'
--- compizconfig/gsettings/src/gsettings.c 2012-06-28 09:03:09 +0000
+++ compizconfig/gsettings/src/gsettings.c 2012-06-29 07:54:24 +0000
@@ -33,6 +33,31 @@
3333
34#include "gsettings.h"34#include "gsettings.h"
3535
36static gboolean
37compizconfigTypeHasVariantType (CCSSettingType type)
38{
39 gint i = 0;
40
41 static const unsigned int nVariantTypes = 6;
42 static const CCSSettingType variantTypes[] =
43 {
44 TypeString,
45 TypeMatch,
46 TypeColor,
47 TypeBool,
48 TypeInt,
49 TypeFloat
50 };
51
52 for (; i < nVariantTypes; i++)
53 {
54 if (variantTypes[i] == type)
55 return TRUE;
56 }
57
58 return FALSE;
59}
60
36static void61static void
37valueChanged (GSettings *settings,62valueChanged (GSettings *settings,
38 gchar *keyname,63 gchar *keyname,
@@ -121,10 +146,11 @@
121 GList *l = settingsList;146 GList *l = settingsList;
122 gchar *schemaName = getSchemaNameForPlugin (plugin);147 gchar *schemaName = getSchemaNameForPlugin (plugin);
123 GVariant *writtenPlugins;148 GVariant *writtenPlugins;
149 gsize writtenPluginsLen;
150 gsize newWrittenPluginsSize;
151 gchar **newWrittenPlugins;
124 char *plug;152 char *plug;
125 GVariant *newWrittenPlugins;153 GVariantIter iter;
126 GVariantBuilder *newWrittenPluginsBuilder;
127 GVariantIter *iter;
128 gboolean found = FALSE;154 gboolean found = FALSE;
129155
130 while (l)156 while (l)
@@ -143,6 +169,8 @@
143 return settingsObj;169 return settingsObj;
144 }170 }
145171
172 g_free (name);
173
146 l = g_list_next (l);174 l = g_list_next (l);
147 }175 }
148176
@@ -162,26 +190,31 @@
162190
163 writtenPlugins = g_settings_get_value (currentProfileSettings, "plugins-with-set-keys");191 writtenPlugins = g_settings_get_value (currentProfileSettings, "plugins-with-set-keys");
164192
165 newWrittenPluginsBuilder = g_variant_builder_new (G_VARIANT_TYPE ("as"));193 g_variant_iter_init (&iter, writtenPlugins);
194 newWrittenPluginsSize = g_variant_iter_n_children (&iter);
166195
167 iter = g_variant_iter_new (writtenPlugins);196 while (g_variant_iter_loop (&iter, "s", &plug))
168 while (g_variant_iter_loop (iter, "s", &plug))
169 {197 {
170 g_variant_builder_add (newWrittenPluginsBuilder, "s", plug);
171
172 if (!found)198 if (!found)
173 found = (g_strcmp0 (plug, plugin) == 0);199 found = (g_strcmp0 (plug, plugin) == 0);
174 }200 }
175201
176 if (!found)202 if (!found)
177 g_variant_builder_add (newWrittenPluginsBuilder, "s", plugin);203 newWrittenPluginsSize++;
178204
179 newWrittenPlugins = g_variant_new ("as", newWrittenPluginsBuilder);205 newWrittenPlugins = g_variant_dup_strv (writtenPlugins, &writtenPluginsLen);
180 g_settings_set_value (currentProfileSettings, "plugins-with-set-keys", newWrittenPlugins);206
181207 if (writtenPluginsLen > newWrittenPluginsSize)
182 g_variant_iter_free (iter);208 {
183 g_variant_unref (newWrittenPlugins);209 newWrittenPlugins = g_realloc (newWrittenPlugins, (newWrittenPluginsSize + 1) * sizeof (gchar *));
184 g_variant_builder_unref (newWrittenPluginsBuilder);210 newWrittenPlugins[writtenPluginsLen + 1] = g_strdup (plugin);
211 newWrittenPlugins[newWrittenPluginsSize] = NULL;
212 }
213
214 g_settings_set_strv (currentProfileSettings, "plugins-with-set-keys", (const gchar * const *)newWrittenPlugins);
215
216 g_free (schemaName);
217 g_strfreev (newWrittenPlugins);
185218
186 return settingsObj;219 return settingsObj;
187}220}
@@ -213,36 +246,52 @@
213{246{
214 CCSContext *context = (CCSContext *)user_data;247 CCSContext *context = (CCSContext *)user_data;
215 char *uncleanKeyName;248 char *uncleanKeyName;
216 char *path;249 char *path, *pathOrig;
217 char *token;250 char *token;
218 int index;251 int index;
219 unsigned int screenNum;252 unsigned int screenNum;
220 CCSPlugin *plugin;253 CCSPlugin *plugin;
221 CCSSetting *setting;254 CCSSetting *setting;
222255
223 g_object_get (G_OBJECT (settings), "path", &path, NULL);256 g_object_get (G_OBJECT (settings), "path", &pathOrig, NULL);
224257
258 path = pathOrig;
225 path += strlen (COMPIZ) + 1;259 path += strlen (COMPIZ) + 1;
226260
227 token = strsep (&path, "/"); /* Profile name */261 token = strsep (&path, "/"); /* Profile name */
228 if (!token)262 if (!token)
263 {
264 g_free (pathOrig);
229 return;265 return;
266 }
230267
231 token = strsep (&path, "/"); /* plugins */268 token = strsep (&path, "/"); /* plugins */
232 if (!token)269 if (!token)
270 {
271 g_free (pathOrig);
233 return;272 return;
273 }
234274
235 token = strsep (&path, "/"); /* plugin */275 token = strsep (&path, "/"); /* plugin */
236 if (!token)276 if (!token)
277 {
278 g_free (pathOrig);
237 return;279 return;
280 }
238281
239 plugin = ccsFindPlugin (context, token);282 plugin = ccsFindPlugin (context, token);
240 if (!plugin)283 if (!plugin)
284 {
285 g_free (pathOrig);
241 return;286 return;
287 }
242288
243 token = strsep (&path, "/"); /* screen%i */289 token = strsep (&path, "/"); /* screen%i */
244 if (!token)290 if (!token)
291 {
292 g_free (pathOrig);
245 return;293 return;
294 }
246295
247 sscanf (token, "screen%d", &screenNum);296 sscanf (token, "screen%d", &screenNum);
248297
@@ -253,6 +302,7 @@
253 {302 {
254 printf ("GSettings Backend: unable to find setting %s, for path %s\n", uncleanKeyName, path);303 printf ("GSettings Backend: unable to find setting %s, for path %s\n", uncleanKeyName, path);
255 free (uncleanKeyName);304 free (uncleanKeyName);
305 g_free (pathOrig);
256 return;306 return;
257 }307 }
258308
@@ -270,42 +320,24 @@
270 }320 }
271321
272 free (uncleanKeyName);322 free (uncleanKeyName);
323 g_free (pathOrig);
273}324}
274325
275static Bool326static Bool
276readListValue (CCSSetting *setting)327readListValue (CCSSetting *setting)
277{328{
278 GSettings *settings = getSettingsObjectForCCSSetting (setting);329 GSettings *settings = getSettingsObjectForCCSSetting (setting);
279 gchar *variantType;330 gboolean hasVariantType;
280 unsigned int nItems, i = 0;331 unsigned int nItems, i = 0;
281 CCSSettingValueList list = NULL;332 CCSSettingValueList list = NULL;
282 GVariant *value;333 GVariant *value;
283 GVariantIter *iter;334 GVariantIter iter;
284335
285 char *cleanSettingName = translateKeyForGSettings (setting->name);336 char *cleanSettingName = translateKeyForGSettings (setting->name);
286 337
287 switch (setting->info.forList.listType)338 hasVariantType = compizconfigTypeHasVariantType (setting->info.forList.listType);
288 {
289 case TypeString:
290 case TypeMatch:
291 case TypeColor:
292 variantType = g_strdup ("s");
293 break;
294 case TypeBool:
295 variantType = g_strdup ("b");
296 break;
297 case TypeInt:
298 variantType = g_strdup ("i");
299 break;
300 case TypeFloat:
301 variantType = g_strdup ("d");
302 break;
303 default:
304 variantType = NULL;
305 break;
306 }
307339
308 if (!variantType)340 if (!hasVariantType)
309 return FALSE;341 return FALSE;
310342
311 value = g_settings_get_value (settings, cleanSettingName);343 value = g_settings_get_value (settings, cleanSettingName);
@@ -315,8 +347,8 @@
315 return TRUE;347 return TRUE;
316 }348 }
317349
318 iter = g_variant_iter_new (value);350 g_variant_iter_init (&iter, value);
319 nItems = g_variant_iter_n_children (iter);351 nItems = g_variant_iter_n_children (&iter);
320352
321 switch (setting->info.forList.listType)353 switch (setting->info.forList.listType)
322 {354 {
@@ -324,14 +356,14 @@
324 {356 {
325 Bool *array = malloc (nItems * sizeof (Bool));357 Bool *array = malloc (nItems * sizeof (Bool));
326 Bool *arrayCounter = array;358 Bool *arrayCounter = array;
359 gboolean value;
327360
328 if (!array)361 if (!array)
329 break;362 break;
330 363
331 /* Reads each item from the variant into the position pointed364 /* Reads each item from the variant into arrayCounter */
332 * at by arrayCounter */365 while (g_variant_iter_loop (&iter, "b", &value))
333 while (g_variant_iter_loop (iter, variantType, arrayCounter))366 *arrayCounter++ = value;
334 arrayCounter++;
335367
336 list = ccsGetValueListFromBoolArray (array, nItems, setting);368 list = ccsGetValueListFromBoolArray (array, nItems, setting);
337 free (array);369 free (array);
@@ -341,14 +373,14 @@
341 {373 {
342 int *array = malloc (nItems * sizeof (int));374 int *array = malloc (nItems * sizeof (int));
343 int *arrayCounter = array;375 int *arrayCounter = array;
376 gint value;
344377
345 if (!array)378 if (!array)
346 break;379 break;
347 380
348 /* Reads each item from the variant into the position pointed381 /* Reads each item from the variant into arrayCounter */
349 * at by arrayCounter */382 while (g_variant_iter_loop (&iter, "i", &value))
350 while (g_variant_iter_loop (iter, variantType, arrayCounter))383 *arrayCounter++ = value;
351 arrayCounter++;
352384
353 list = ccsGetValueListFromIntArray (array, nItems, setting);385 list = ccsGetValueListFromIntArray (array, nItems, setting);
354 free (array);386 free (array);
@@ -358,14 +390,14 @@
358 {390 {
359 double *array = malloc (nItems * sizeof (double));391 double *array = malloc (nItems * sizeof (double));
360 double *arrayCounter = array;392 double *arrayCounter = array;
393 gdouble value;
361394
362 if (!array)395 if (!array)
363 break;396 break;
364 397
365 /* Reads each item from the variant into the position pointed398 /* Reads each item from the variant into arrayCounter */
366 * at by arrayCounter */399 while (g_variant_iter_loop (&iter, "d", &value))
367 while (g_variant_iter_loop (iter, variantType, arrayCounter))400 *arrayCounter++ = value;
368 arrayCounter++;
369401
370 list = ccsGetValueListFromFloatArray ((float *) array, nItems, setting);402 list = ccsGetValueListFromFloatArray ((float *) array, nItems, setting);
371 free (array);403 free (array);
@@ -374,24 +406,21 @@
374 case TypeString:406 case TypeString:
375 case TypeMatch:407 case TypeMatch:
376 {408 {
377 char **array = calloc (1, (nItems + 1) * sizeof (char *));409 gchar **array = g_malloc0 ((nItems + 1) * sizeof (gchar *));
378 char **arrayCounter = array;410 gchar **arrayCounter = array;
411 gchar *value;
379412
380 if (!array)413 if (!array)
381 {
382 break;414 break;
383 }415
384 416 array[nItems] = NULL;
385 /* Reads each item from the variant into the position pointed417
386 * at by arrayCounter */418 /* Reads each item from the variant into arrayCounter */
387 while (g_variant_iter_loop (iter, variantType, arrayCounter))419 while (g_variant_iter_next (&iter, "s", &value))
388 arrayCounter++;420 *arrayCounter++ = value;
389421
390 list = ccsGetValueListFromStringArray (array, nItems, setting);422 list = ccsGetValueListFromStringArray (array, nItems, setting);
391 for (i = 0; i < nItems; i++)423 g_strfreev (array);
392 if (array[i])
393 free (array[i]);
394 free (array);
395 }424 }
396 break;425 break;
397 case TypeColor:426 case TypeColor:
@@ -402,7 +431,7 @@
402 if (!array)431 if (!array)
403 break;432 break;
404433
405 while (g_variant_iter_loop (iter, variantType, &colorValue))434 while (g_variant_iter_loop (&iter, "s", &colorValue))
406 {435 {
407 memset (&array[i], 0, sizeof (CCSSettingColorValue));436 memset (&array[i], 0, sizeof (CCSSettingColorValue));
408 ccsStringToColor (colorValue,437 ccsStringToColor (colorValue,
@@ -417,7 +446,6 @@
417 }446 }
418447
419 free (cleanSettingName);448 free (cleanSettingName);
420 free (variantType);
421449
422 if (list)450 if (list)
423 {451 {
@@ -638,8 +666,7 @@
638 char *pathName)666 char *pathName)
639{667{
640 GSettings *settings = getSettingsObjectForCCSSetting (setting);668 GSettings *settings = getSettingsObjectForCCSSetting (setting);
641 GVariant *value;669 GVariant *value = NULL;
642 gchar *variantType = NULL;
643 CCSSettingValueList list;670 CCSSettingValueList list;
644671
645 char *cleanSettingName = translateKeyForGSettings (setting->name);672 char *cleanSettingName = translateKeyForGSettings (setting->name);
@@ -651,7 +678,6 @@
651 {678 {
652 case TypeBool:679 case TypeBool:
653 {680 {
654 variantType = "ab";
655 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ab"));681 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ab"));
656 while (list)682 while (list)
657 {683 {
@@ -664,7 +690,6 @@
664 break;690 break;
665 case TypeInt:691 case TypeInt:
666 {692 {
667 variantType = "ai";
668 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ai"));693 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ai"));
669 while (list)694 while (list)
670 {695 {
@@ -677,7 +702,6 @@
677 break;702 break;
678 case TypeFloat:703 case TypeFloat:
679 {704 {
680 variantType = "ad";
681 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ad"));705 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("ad"));
682 while (list)706 while (list)
683 {707 {
@@ -690,7 +714,6 @@
690 break;714 break;
691 case TypeString:715 case TypeString:
692 {716 {
693 variantType = "as";
694 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));717 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
695 while (list)718 while (list)
696 {719 {
@@ -703,7 +726,6 @@
703 break;726 break;
704 case TypeMatch:727 case TypeMatch:
705 {728 {
706 variantType = "as";
707 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));729 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
708 while (list)730 while (list)
709 {731 {
@@ -716,7 +738,6 @@
716 break;738 break;
717 case TypeColor:739 case TypeColor:
718 {740 {
719 variantType = "as";
720 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));741 GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
721 char *item;742 char *item;
722 while (list)743 while (list)
@@ -732,11 +753,10 @@
732 default:753 default:
733 printf("GSettings backend: attempt to write unsupported list type %d!\n",754 printf("GSettings backend: attempt to write unsupported list type %d!\n",
734 setting->info.forList.listType);755 setting->info.forList.listType);
735 variantType = NULL;
736 break;756 break;
737 }757 }
738758
739 if (variantType != NULL)759 if (value)
740 {760 {
741 g_settings_set_value (settings, cleanSettingName, value);761 g_settings_set_value (settings, cleanSettingName, value);
742 g_variant_unref (value);762 g_variant_unref (value);
@@ -911,7 +931,7 @@
911}931}
912932
913static void933static void
914updateCurrentProfileName (char *profile)934updateCurrentProfileName (const char *profile)
915{935{
916 GVariant *profiles;936 GVariant *profiles;
917 char *prof;937 char *prof;
@@ -919,15 +939,15 @@
919 char *currentProfilePath;939 char *currentProfilePath;
920 GVariant *newProfiles;940 GVariant *newProfiles;
921 GVariantBuilder *newProfilesBuilder;941 GVariantBuilder *newProfilesBuilder;
922 GVariantIter *iter;942 GVariantIter iter;
923 gboolean found = FALSE;943 gboolean found = FALSE;
924944
925 profiles = g_settings_get_value (compizconfigSettings, "existing-profiles");945 profiles = g_settings_get_value (compizconfigSettings, "existing-profiles");
926946
927 newProfilesBuilder = g_variant_builder_new (G_VARIANT_TYPE ("as"));947 newProfilesBuilder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
928948
929 iter = g_variant_iter_new (profiles);949 g_variant_iter_init (&iter, profiles);
930 while (g_variant_iter_loop (iter, "s", &prof))950 while (g_variant_iter_loop (&iter, "s", &prof))
931 {951 {
932 g_variant_builder_add (newProfilesBuilder, "s", prof);952 g_variant_builder_add (newProfilesBuilder, "s", prof);
933953
@@ -941,7 +961,6 @@
941 newProfiles = g_variant_new ("as", newProfilesBuilder);961 newProfiles = g_variant_new ("as", newProfilesBuilder);
942 g_settings_set_value (compizconfigSettings, "existing-profiles", newProfiles);962 g_settings_set_value (compizconfigSettings, "existing-profiles", newProfiles);
943963
944 g_variant_iter_free (iter);
945 g_variant_unref (newProfiles);964 g_variant_unref (newProfiles);
946 g_variant_builder_unref (newProfilesBuilder);965 g_variant_builder_unref (newProfilesBuilder);
947966
@@ -962,8 +981,14 @@
962{981{
963 char *profile = strdup (ccsGetProfile (context));982 char *profile = strdup (ccsGetProfile (context));
964983
965 if (!profile || !strlen (profile))984 if (!profile)
966 profile = strdup (DEFAULTPROF);985 profile = strdup (DEFAULTPROF);
986
987 if (!strlen (profile))
988 {
989 free (profile);
990 profile = strdup (DEFAULTPROF);
991 }
967992
968 if (g_strcmp0 (profile, currentProfile))993 if (g_strcmp0 (profile, currentProfile))
969 updateCurrentProfileName (profile);994 updateCurrentProfileName (profile);
@@ -1155,15 +1180,15 @@
1155 GVariant *newProfiles;1180 GVariant *newProfiles;
1156 GVariantBuilder *newProfilesBuilder;1181 GVariantBuilder *newProfilesBuilder;
1157 char *plugin, *prof;1182 char *plugin, *prof;
1158 GVariantIter *iter;1183 GVariantIter iter;
1159 char *profileSettingsPath = g_strconcat (PROFILEPATH, profile, "/", NULL);1184 char *profileSettingsPath = g_strconcat (PROFILEPATH, profile, "/", NULL);
1160 GSettings *profileSettings = g_settings_new_with_path (PROFILE_SCHEMA_ID, profileSettingsPath);1185 GSettings *profileSettings = g_settings_new_with_path (PROFILE_SCHEMA_ID, profileSettingsPath);
11611186
1162 plugins = g_settings_get_value (currentProfileSettings, "plugins-with-set-keys");1187 plugins = g_settings_get_value (currentProfileSettings, "plugins-with-set-keys");
1163 profiles = g_settings_get_value (compizconfigSettings, "existing-profiles");1188 profiles = g_settings_get_value (compizconfigSettings, "existing-profiles");
11641189
1165 iter = g_variant_iter_new (plugins);1190 g_variant_iter_init (&iter, plugins);
1166 while (g_variant_iter_loop (iter, "s", &plugin))1191 while (g_variant_iter_loop (&iter, "s", &plugin))
1167 {1192 {
1168 GSettings *settings;1193 GSettings *settings;
11691194
@@ -1189,13 +1214,12 @@
1189 }1214 }
11901215
1191 /* Remove the profile from existing-profiles */1216 /* Remove the profile from existing-profiles */
1192 g_variant_iter_free (iter);
1193 g_settings_reset (profileSettings, "plugins-with-set-values");1217 g_settings_reset (profileSettings, "plugins-with-set-values");
11941218
1195 iter = g_variant_iter_new (profiles);1219 g_variant_iter_init (&iter, profiles);
1196 newProfilesBuilder = g_variant_builder_new (G_VARIANT_TYPE ("as"));1220 newProfilesBuilder = g_variant_builder_new (G_VARIANT_TYPE ("as"));
11971221
1198 while (g_variant_iter_loop (iter, "s", &prof))1222 while (g_variant_iter_loop (&iter, "s", &prof))
1199 {1223 {
1200 if (g_strcmp0 (prof, profile))1224 if (g_strcmp0 (prof, profile))
1201 g_variant_builder_add (newProfilesBuilder, "s", prof);1225 g_variant_builder_add (newProfilesBuilder, "s", prof);

Subscribers

People subscribed via source and target branches