From fe8e1b795d198da8743e719495570d13efa01782 Mon Sep 17 00:00:00 2001 From: Alban Browaeys Date: Thu, 3 Jan 2013 12:03:29 +0100 Subject: [PATCH] Fixes use of atof in non "C" locale environments. atof is local dependant. Ie passing 1.0 to atof with in a french environment leads to segfault in lcms for create-standard-space: primaries are all equal to 0 due to the dot not meaning decimal separator in this locale. Thus we get a null lcms profile from cmsCreateRGBProfile. Then as we pass this null profile to lcms, lcms segfault. This was with AdobeRGB1998.icc : ../../client/cd-create-profile --output AdobeRGB1998.icc \ create-standard-space \ --description "Adobe RGB (1998)" \ --metadata "License="CC0",DATA_source=standard,STANDARD_space=adobe-rgb" \ 2.2 D65 \ 0.6400 0.3300 0.297361 \ 0.2100 0.7100 0.627355 \ 0.1500 0.0600 0.075285 --- client/cd-create-profile.c | 46 +++++++++++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/client/cd-create-profile.c b/client/cd-create-profile.c index 84a1d72..05aa6a5 100644 --- a/client/cd-create-profile.c +++ b/client/cd-create-profile.c @@ -192,6 +192,22 @@ cd_fix_profile_error_cb (cmsContext ContextID, lcms_error_code = errorcode; } + +static double +atof_nol (const char *nptr) +{ + double res; + locale_t new_locale, prev_locale; + + new_locale = newlocale (LC_NUMERIC_MASK, "C", NULL); + prev_locale = uselocale (new_locale); + res = atof (nptr); + uselocale (prev_locale); + freelocale (new_locale); + + return res; +} + static gboolean add_nc_palette_srgb (cmsNAMEDCOLORLIST *nc2, const gchar *filename) { @@ -289,9 +305,9 @@ add_nc_palette_lab (cmsNAMEDCOLORLIST *nc2, const gchar *filename) if (g_strv_length (split) == 4) { g_strdelimit (split[0], "\"", ' '); name = g_strstrip (split[0]); - lab.L = atof (split[1]); - lab.a = atof (split[2]); - lab.b = atof (split[3]); + lab.L = atof_nol (split[1]); + lab.a = atof_nol (split[2]); + lab.b = atof_nol (split[3]); g_debug ("add %s, %f,%f,%f", name, @@ -414,7 +430,7 @@ cd_util_create_x11_gamma (CdUtilPrivate *priv, gchar **values, GError **error) /* parse floats */ for (j = 0; j < 3; j++) - points[j] = atof (values[j]); + points[j] = atof_nol (values[j]); /* create a bog-standard sRGB profile */ priv->lcms_profile = cmsCreate_sRGBProfile (); @@ -550,7 +566,7 @@ cd_util_create_standard_space (CdUtilPrivate *priv, transfer[1] = transfer[0]; transfer[2] = transfer[0]; } else { - tgamma = atof (values[0]); + tgamma = atof_nol (values[0]); transfer[0] = cmsBuildGamma (NULL, tgamma); transfer[1] = transfer[0]; transfer[2] = transfer[0]; @@ -576,15 +592,15 @@ cd_util_create_standard_space (CdUtilPrivate *priv, } /* get primaries */ - primaries.Red.x = atof (values[2]); - primaries.Red.y = atof (values[3]); - primaries.Red.Y = atof (values[4]); - primaries.Green.x = atof (values[5]); - primaries.Green.y = atof (values[6]); - primaries.Green.Y = atof (values[7]); - primaries.Blue.x = atof (values[8]); - primaries.Blue.y = atof (values[9]); - primaries.Blue.Y = atof (values[10]); + primaries.Red.x = atof_nol (values[2]); + primaries.Red.y = atof_nol (values[3]); + primaries.Red.Y = atof_nol (values[4]); + primaries.Green.x = atof_nol (values[5]); + primaries.Green.y = atof_nol (values[6]); + primaries.Green.Y = atof_nol (values[7]); + primaries.Blue.x = atof_nol (values[8]); + primaries.Blue.y = atof_nol (values[9]); + primaries.Blue.Y = atof_nol (values[10]); /* create profile */ priv->lcms_profile = cmsCreateRGBProfile (&white, @@ -631,7 +647,7 @@ cd_util_create_temperature (CdUtilPrivate *priv, /* generate the VCGT table */ temp = atoi (values[0]); - gamma = atof (values[1]); + gamma = atof_nol (values[1]); cd_color_get_blackbody_rgb (temp, &white_point); for (i = 0; i < size; i++) { data[0][i] = pow ((gdouble) i / size, 1.0 / gamma) * -- 1.8.1