app: in plug-ins, fix invalid parameter names instead of rejecting procedure
Instead of rejecting plug-in procedures with invalid parameter- or return-value names (see issues #4392 and 4641), simply fix the invalid name and allow the procedure to register. Apparently, there are plug-ins out there that use invalid parameter names (in particular, liquid-rescale), so let's keep them working in 2.10. Show appropriate warning/error for invalid parameter names when not in PDB compat mode.
This commit is contained in:
@ -33,143 +33,154 @@
|
||||
#include "gimp-pdb-compat.h"
|
||||
|
||||
|
||||
/* local function prototypes */
|
||||
|
||||
static gchar * gimp_pdb_compat_fix_param_name (const gchar *name);
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
GParamSpec *
|
||||
gimp_pdb_compat_param_spec (Gimp *gimp,
|
||||
GimpPDBArgType arg_type,
|
||||
const gchar *name,
|
||||
const gchar *desc)
|
||||
const gchar *desc,
|
||||
gboolean *name_valid)
|
||||
{
|
||||
GParamSpec *pspec = NULL;
|
||||
gchar *real_name;
|
||||
|
||||
g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
|
||||
g_return_val_if_fail (name != NULL, NULL);
|
||||
|
||||
real_name = gimp_pdb_compat_fix_param_name (name);
|
||||
|
||||
if (name_valid) *name_valid = ! strcmp (name, real_name);
|
||||
|
||||
switch (arg_type)
|
||||
{
|
||||
case GIMP_PDB_INT32:
|
||||
pspec = gimp_param_spec_int32 (name, name, desc,
|
||||
pspec = gimp_param_spec_int32 (real_name, real_name, desc,
|
||||
G_MININT32, G_MAXINT32, 0,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_INT16:
|
||||
pspec = gimp_param_spec_int16 (name, name, desc,
|
||||
pspec = gimp_param_spec_int16 (real_name, real_name, desc,
|
||||
G_MININT16, G_MAXINT16, 0,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_INT8:
|
||||
pspec = gimp_param_spec_int8 (name, name, desc,
|
||||
pspec = gimp_param_spec_int8 (real_name, real_name, desc,
|
||||
0, G_MAXUINT8, 0,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_FLOAT:
|
||||
pspec = g_param_spec_double (name, name, desc,
|
||||
pspec = g_param_spec_double (real_name, real_name, desc,
|
||||
-G_MAXDOUBLE, G_MAXDOUBLE, 0.0,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_STRING:
|
||||
pspec = gimp_param_spec_string (name, name, desc,
|
||||
pspec = gimp_param_spec_string (real_name, real_name, desc,
|
||||
TRUE, TRUE, FALSE,
|
||||
NULL,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_INT32ARRAY:
|
||||
pspec = gimp_param_spec_int32_array (name, name, desc,
|
||||
pspec = gimp_param_spec_int32_array (real_name, real_name, desc,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_INT16ARRAY:
|
||||
pspec = gimp_param_spec_int16_array (name, name, desc,
|
||||
pspec = gimp_param_spec_int16_array (real_name, real_name, desc,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_INT8ARRAY:
|
||||
pspec = gimp_param_spec_int8_array (name, name, desc,
|
||||
pspec = gimp_param_spec_int8_array (real_name, real_name, desc,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_FLOATARRAY:
|
||||
pspec = gimp_param_spec_float_array (name, name, desc,
|
||||
pspec = gimp_param_spec_float_array (real_name, real_name, desc,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_STRINGARRAY:
|
||||
pspec = gimp_param_spec_string_array (name, name, desc,
|
||||
pspec = gimp_param_spec_string_array (real_name, real_name, desc,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_COLOR:
|
||||
pspec = gimp_param_spec_rgb (name, name, desc,
|
||||
pspec = gimp_param_spec_rgb (real_name, real_name, desc,
|
||||
TRUE, NULL,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_ITEM:
|
||||
pspec = gimp_param_spec_item_id (name, name, desc,
|
||||
pspec = gimp_param_spec_item_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_DISPLAY:
|
||||
pspec = gimp_param_spec_display_id (name, name, desc,
|
||||
pspec = gimp_param_spec_display_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_IMAGE:
|
||||
pspec = gimp_param_spec_image_id (name, name, desc,
|
||||
pspec = gimp_param_spec_image_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_LAYER:
|
||||
pspec = gimp_param_spec_layer_id (name, name, desc,
|
||||
pspec = gimp_param_spec_layer_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_CHANNEL:
|
||||
pspec = gimp_param_spec_channel_id (name, name, desc,
|
||||
pspec = gimp_param_spec_channel_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_DRAWABLE:
|
||||
pspec = gimp_param_spec_drawable_id (name, name, desc,
|
||||
pspec = gimp_param_spec_drawable_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_SELECTION:
|
||||
pspec = gimp_param_spec_selection_id (name, name, desc,
|
||||
pspec = gimp_param_spec_selection_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_COLORARRAY:
|
||||
pspec = gimp_param_spec_color_array (name, name, desc,
|
||||
pspec = gimp_param_spec_color_array (real_name, real_name, desc,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_VECTORS:
|
||||
pspec = gimp_param_spec_vectors_id (name, name, desc,
|
||||
pspec = gimp_param_spec_vectors_id (real_name, real_name, desc,
|
||||
gimp, TRUE,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_PARASITE:
|
||||
pspec = gimp_param_spec_parasite (name, name, desc,
|
||||
pspec = gimp_param_spec_parasite (real_name, real_name, desc,
|
||||
G_PARAM_READWRITE);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_STATUS:
|
||||
pspec = g_param_spec_enum (name, name, desc,
|
||||
pspec = g_param_spec_enum (real_name, real_name, desc,
|
||||
GIMP_TYPE_PDB_STATUS_TYPE,
|
||||
GIMP_PDB_EXECUTION_ERROR,
|
||||
G_PARAM_READWRITE);
|
||||
@ -180,8 +191,14 @@ gimp_pdb_compat_param_spec (Gimp *gimp,
|
||||
}
|
||||
|
||||
if (! pspec)
|
||||
g_warning ("%s: returning NULL for %s (%s)",
|
||||
G_STRFUNC, name, gimp_pdb_compat_arg_type_to_string (arg_type));
|
||||
{
|
||||
g_warning ("%s: returning NULL for %s (%s)",
|
||||
G_STRFUNC,
|
||||
real_name,
|
||||
gimp_pdb_compat_arg_type_to_string (arg_type));
|
||||
}
|
||||
|
||||
g_free (real_name);
|
||||
|
||||
return pspec;
|
||||
}
|
||||
@ -501,3 +518,45 @@ gimp_pdb_compat_procs_register (GimpPDB *pdb,
|
||||
compat_procs[i].new_name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* private functions */
|
||||
|
||||
/* Since GLib 2.63.3, invalid param-spec names are rejected upon creation.
|
||||
* This impacts procedure parameters and return-values, which are stored as
|
||||
* param-specs internally. Since this requirement wasn't previously enforced,
|
||||
* keep supporting arbitrary parameter names in gimp-2.
|
||||
*
|
||||
* See issues #4392 and #4641.
|
||||
*/
|
||||
static gchar *
|
||||
gimp_pdb_compat_fix_param_name (const gchar *name)
|
||||
{
|
||||
GString *new_name;
|
||||
|
||||
new_name = g_string_new (NULL);
|
||||
|
||||
/* First character must be a letter. */
|
||||
if ((name[0] < 'A' || name[0] > 'Z') &&
|
||||
(name[0] < 'a' || name[0] > 'z'))
|
||||
{
|
||||
g_string_append (new_name, "param-");
|
||||
}
|
||||
|
||||
for (; *name; name++)
|
||||
{
|
||||
gchar c = *name;
|
||||
|
||||
if ((c < 'A' || c > 'Z') &&
|
||||
(c < 'a' || c > 'z') &&
|
||||
(c < '0' || c > '9') &&
|
||||
c != '-' && c != '_')
|
||||
{
|
||||
c = '-';
|
||||
}
|
||||
|
||||
g_string_append_c (new_name, c);
|
||||
}
|
||||
|
||||
return g_string_free (new_name, FALSE);
|
||||
}
|
||||
|
@ -22,7 +22,8 @@
|
||||
GParamSpec * gimp_pdb_compat_param_spec (Gimp *gimp,
|
||||
GimpPDBArgType arg_type,
|
||||
const gchar *name,
|
||||
const gchar *desc);
|
||||
const gchar *desc,
|
||||
gboolean *name_valid);
|
||||
|
||||
GType gimp_pdb_compat_arg_type_to_gtype (GimpPDBArgType type);
|
||||
GimpPDBArgType gimp_pdb_compat_arg_type_from_gtype (GType type);
|
||||
|
@ -76,7 +76,6 @@ static void gimp_plug_in_handle_proc_uninstall (GimpPlugIn *plug_in,
|
||||
static void gimp_plug_in_handle_extension_ack (GimpPlugIn *plug_in);
|
||||
static void gimp_plug_in_handle_has_init (GimpPlugIn *plug_in);
|
||||
|
||||
static gboolean gimp_plug_in_is_valid_property_name (const gchar *name);
|
||||
|
||||
/* public functions */
|
||||
|
||||
@ -863,49 +862,105 @@ gimp_plug_in_handle_proc_install (GimpPlugIn *plug_in,
|
||||
for (i = 0; i < proc_install->nparams; i++)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
gboolean name_valid;
|
||||
|
||||
if (! gimp_plug_in_is_valid_property_name (proc_install->params[i].name))
|
||||
{
|
||||
gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
|
||||
"Plug-in \"%s\"\n(%s)\n"
|
||||
"attempted to install procedure \"%s\" with "
|
||||
"invalid parameter name \"%s\".",
|
||||
gimp_object_get_name (plug_in),
|
||||
gimp_file_get_utf8_name (plug_in->file),
|
||||
canonical, proc_install->params[i].name);
|
||||
g_object_unref (procedure);
|
||||
return;
|
||||
}
|
||||
pspec = gimp_pdb_compat_param_spec (plug_in->manager->gimp,
|
||||
proc_install->params[i].type,
|
||||
proc_install->params[i].name,
|
||||
proc_install->params[i].description);
|
||||
proc_install->params[i].description,
|
||||
&name_valid);
|
||||
|
||||
gimp_procedure_add_argument (procedure, pspec);
|
||||
|
||||
if (pspec && ! name_valid)
|
||||
{
|
||||
switch (plug_in->manager->gimp->pdb_compat_mode)
|
||||
{
|
||||
case GIMP_PDB_COMPAT_ON:
|
||||
break;
|
||||
|
||||
case GIMP_PDB_COMPAT_WARN:
|
||||
gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_WARNING,
|
||||
"Plug-in \"%s\"\n(%s)\n"
|
||||
"attempted to install procedure \"%s\" "
|
||||
"with invalid parameter name \"%s\".\n"
|
||||
"This is deprecated.\n"
|
||||
"The parameter name was changed to \"%s\".",
|
||||
gimp_object_get_name (plug_in),
|
||||
gimp_file_get_utf8_name (plug_in->file),
|
||||
gimp_object_get_name (proc),
|
||||
proc_install->params[i].name,
|
||||
pspec->name);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_COMPAT_OFF:
|
||||
gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
|
||||
"Plug-in \"%s\"\n(%s)\n"
|
||||
"attempted to install procedure \"%s\" "
|
||||
"with invalid parameter name \"%s\".\n"
|
||||
"This is not allowed.",
|
||||
gimp_object_get_name (plug_in),
|
||||
gimp_file_get_utf8_name (plug_in->file),
|
||||
gimp_object_get_name (proc),
|
||||
proc_install->params[i].name);
|
||||
|
||||
g_object_unref (proc);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < proc_install->nreturn_vals; i++)
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
gboolean name_valid;
|
||||
|
||||
if (! gimp_plug_in_is_valid_property_name (proc_install->return_vals[i].name))
|
||||
{
|
||||
gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
|
||||
"Plug-in \"%s\"\n(%s)\n"
|
||||
"attempted to install procedure \"%s\" with "
|
||||
"invalid return value name \"%s\".",
|
||||
gimp_object_get_name (plug_in),
|
||||
gimp_file_get_utf8_name (plug_in->file),
|
||||
canonical, proc_install->return_vals[i].name);
|
||||
g_object_unref (procedure);
|
||||
return;
|
||||
}
|
||||
pspec = gimp_pdb_compat_param_spec (plug_in->manager->gimp,
|
||||
proc_install->return_vals[i].type,
|
||||
proc_install->return_vals[i].name,
|
||||
proc_install->return_vals[i].description);
|
||||
proc_install->return_vals[i].description,
|
||||
&name_valid);
|
||||
|
||||
gimp_procedure_add_return_value (procedure, pspec);
|
||||
|
||||
if (pspec && ! name_valid)
|
||||
{
|
||||
switch (plug_in->manager->gimp->pdb_compat_mode)
|
||||
{
|
||||
case GIMP_PDB_COMPAT_ON:
|
||||
break;
|
||||
|
||||
case GIMP_PDB_COMPAT_WARN:
|
||||
gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_WARNING,
|
||||
"Plug-in \"%s\"\n(%s)\n"
|
||||
"attempted to install procedure \"%s\" "
|
||||
"with invalid return-value name \"%s\".\n"
|
||||
"This is deprecated.\n"
|
||||
"The return-value name was changed to \"%s\".",
|
||||
gimp_object_get_name (plug_in),
|
||||
gimp_file_get_utf8_name (plug_in->file),
|
||||
gimp_object_get_name (proc),
|
||||
proc_install->return_vals[i].name,
|
||||
pspec->name);
|
||||
break;
|
||||
|
||||
case GIMP_PDB_COMPAT_OFF:
|
||||
gimp_message (plug_in->manager->gimp, NULL, GIMP_MESSAGE_ERROR,
|
||||
"Plug-in \"%s\"\n(%s)\n"
|
||||
"attempted to install procedure \"%s\" "
|
||||
"with invalid return-value name \"%s\".\n"
|
||||
"This is not allowed.",
|
||||
gimp_object_get_name (plug_in),
|
||||
gimp_file_get_utf8_name (plug_in->file),
|
||||
gimp_object_get_name (proc),
|
||||
proc_install->return_vals[i].name);
|
||||
|
||||
g_object_unref (proc);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Sanity check menu path */
|
||||
@ -1006,33 +1061,3 @@ gimp_plug_in_handle_has_init (GimpPlugIn *plug_in)
|
||||
gimp_plug_in_close (plug_in, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: this function should be removed when/if it becomes public in
|
||||
* glib, i.e. when this patch is merged:
|
||||
* https://gitlab.gnome.org/GNOME/glib/merge_requests/1302
|
||||
* See #4392.
|
||||
*/
|
||||
static gboolean
|
||||
gimp_plug_in_is_valid_property_name (const gchar *name)
|
||||
{
|
||||
const gchar *p;
|
||||
|
||||
/* First character must be a letter. */
|
||||
if ((name[0] < 'A' || name[0] > 'Z') &&
|
||||
(name[0] < 'a' || name[0] > 'z'))
|
||||
return FALSE;
|
||||
|
||||
for (p = name; *p != 0; p++)
|
||||
{
|
||||
const gchar c = *p;
|
||||
|
||||
if (c != '-' && c != '_' &&
|
||||
(c < '0' || c > '9') &&
|
||||
(c < 'A' || c > 'Z') &&
|
||||
(c < 'a' || c > 'z'))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -784,7 +784,7 @@ plug_in_proc_arg_deserialize (GScanner *scanner,
|
||||
|
||||
token = G_TOKEN_LEFT_PAREN;
|
||||
|
||||
pspec = gimp_pdb_compat_param_spec (gimp, arg_type, name, desc);
|
||||
pspec = gimp_pdb_compat_param_spec (gimp, arg_type, name, desc, NULL);
|
||||
|
||||
if (return_value)
|
||||
gimp_procedure_add_return_value (procedure, pspec);
|
||||
|
Reference in New Issue
Block a user