app, libgimp, pdb: add g_return*_if_fail() test for array size args.

Generated libgimp functions' arguments are normally tested through the
PDB, so that you get proper error messages when trying to call a
function with invalid arguments.
This is not true anymore for array arguments since the size argument is
not a PDB arg, only in the C function. Therefore I'm adding an
infrastructure asserting on invalid size, using the same PDB type
annotations as other args. It is important to assert valid input on
plug-in side (i.e. libgimp) so that the core doesn't make any assumption
on having received valid input when it has not.

Also changing size argument of gimppainttools PDB-generated functions to
proper gsize.
This commit is contained in:
Jehan 2024-10-25 16:56:48 +02:00
parent 253db343a6
commit 48cb7e76d3
10 changed files with 134 additions and 57 deletions

View File

@ -51,7 +51,7 @@ gimp_paint_core_stroke (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpCoords *strokes,
gint n_strokes,
gsize n_strokes,
gboolean push_undo,
GError **error)
{

View File

@ -23,7 +23,7 @@ gboolean gimp_paint_core_stroke (GimpPaintCore *core,
GimpDrawable *drawable,
GimpPaintOptions *paint_options,
GimpCoords *strokes,
gint n_strokes,
gsize n_strokes,
gboolean push_undo,
GError **error);
gboolean gimp_paint_core_stroke_boundary (GimpPaintCore *core,

View File

@ -54,7 +54,7 @@ paint_tools_stroke (Gimp *gimp,
GimpContext *context,
GimpPaintOptions *options,
GimpDrawable *drawable,
gint n_strokes,
gsize n_strokes,
const gdouble *strokes,
GError **error,
const gchar *first_property_name,
@ -113,7 +113,7 @@ airbrush_invoker (GimpProcedure *procedure,
gboolean success = TRUE;
GimpDrawable *drawable;
gdouble pressure;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -160,7 +160,7 @@ airbrush_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -206,7 +206,7 @@ clone_invoker (GimpProcedure *procedure,
gint clone_type;
gdouble src_x;
gdouble src_y;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -263,7 +263,7 @@ clone_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -307,7 +307,7 @@ convolve_invoker (GimpProcedure *procedure,
GimpDrawable *drawable;
gdouble pressure;
gint convolve_type;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -356,7 +356,7 @@ convolve_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -401,7 +401,7 @@ dodgeburn_invoker (GimpProcedure *procedure,
gdouble exposure;
gint dodgeburn_type;
gint dodgeburn_mode;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -452,7 +452,7 @@ dodgeburn_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -494,7 +494,7 @@ eraser_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
gint hardness;
gint method;
@ -545,7 +545,7 @@ eraser_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -590,7 +590,7 @@ heal_invoker (GimpProcedure *procedure,
GimpDrawable *src_drawable;
gdouble src_x;
gdouble src_y;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -645,7 +645,7 @@ heal_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -688,7 +688,7 @@ paintbrush_invoker (GimpProcedure *procedure,
gboolean success = TRUE;
GimpDrawable *drawable;
gdouble fade_out;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
gint method;
gdouble gradient_length;
@ -771,7 +771,7 @@ paintbrush_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -813,7 +813,7 @@ pencil_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -856,7 +856,7 @@ smudge_invoker (GimpProcedure *procedure,
gboolean success = TRUE;
GimpDrawable *drawable;
gdouble pressure;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));
@ -903,7 +903,7 @@ smudge_default_invoker (GimpProcedure *procedure,
{
gboolean success = TRUE;
GimpDrawable *drawable;
gint num_strokes;
gsize num_strokes;
const gdouble *strokes;
drawable = g_value_get_object (gimp_value_array_index (args, 0));

View File

@ -214,6 +214,9 @@ gimp_drawable_curves_explicit (GimpDrawable *drawable,
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_values >= 256, FALSE);
g_return_val_if_fail (num_values <= 2096, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_HISTOGRAM_CHANNEL, channel,
@ -264,6 +267,9 @@ gimp_drawable_curves_spline (GimpDrawable *drawable,
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_points >= 4, FALSE);
g_return_val_if_fail (num_points <= 2048, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_HISTOGRAM_CHANNEL, channel,

View File

@ -235,6 +235,8 @@ gimp_gradient_get_custom_samples (GimpGradient *gradient,
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_samples >= 1, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_GRADIENT, gradient,
GIMP_TYPE_FLOAT_ARRAY, NULL,

View File

@ -379,6 +379,8 @@ gimp_image_select_polygon (GimpImage *image,
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_segs >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_IMAGE, image,
GIMP_TYPE_CHANNEL_OPS, operation,

View File

@ -56,13 +56,15 @@
gboolean
gimp_airbrush (GimpDrawable *drawable,
gdouble pressure,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
G_TYPE_DOUBLE, pressure,
@ -100,13 +102,15 @@ gimp_airbrush (GimpDrawable *drawable,
**/
gboolean
gimp_airbrush_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -158,13 +162,15 @@ gimp_clone (GimpDrawable *drawable,
GimpCloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_DRAWABLE, src_drawable,
@ -206,13 +212,15 @@ gimp_clone (GimpDrawable *drawable,
**/
gboolean
gimp_clone_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -252,13 +260,15 @@ gboolean
gimp_convolve (GimpDrawable *drawable,
gdouble pressure,
GimpConvolveType convolve_type,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
G_TYPE_DOUBLE, pressure,
@ -297,13 +307,15 @@ gimp_convolve (GimpDrawable *drawable,
**/
gboolean
gimp_convolve_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -342,13 +354,15 @@ gimp_dodgeburn (GimpDrawable *drawable,
gdouble exposure,
GimpDodgeBurnType dodgeburn_type,
GimpTransferMode dodgeburn_mode,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
G_TYPE_DOUBLE, exposure,
@ -387,13 +401,15 @@ gimp_dodgeburn (GimpDrawable *drawable,
**/
gboolean
gimp_dodgeburn_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -432,7 +448,7 @@ gimp_dodgeburn_default (GimpDrawable *drawable,
**/
gboolean
gimp_eraser (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes,
GimpBrushApplicationMode hardness,
GimpPaintApplicationMode method)
@ -441,6 +457,8 @@ gimp_eraser (GimpDrawable *drawable,
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -479,13 +497,15 @@ gimp_eraser (GimpDrawable *drawable,
**/
gboolean
gimp_eraser_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -531,13 +551,15 @@ gimp_heal (GimpDrawable *drawable,
GimpDrawable *src_drawable,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_DRAWABLE, src_drawable,
@ -580,13 +602,15 @@ gimp_heal (GimpDrawable *drawable,
**/
gboolean
gimp_heal_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -632,7 +656,7 @@ gimp_heal_default (GimpDrawable *drawable,
gboolean
gimp_paintbrush (GimpDrawable *drawable,
gdouble fade_out,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes,
GimpPaintApplicationMode method,
gdouble gradient_length)
@ -641,6 +665,8 @@ gimp_paintbrush (GimpDrawable *drawable,
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
G_TYPE_DOUBLE, fade_out,
@ -689,13 +715,15 @@ gimp_paintbrush (GimpDrawable *drawable,
**/
gboolean
gimp_paintbrush_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -733,13 +761,15 @@ gimp_paintbrush_default (GimpDrawable *drawable,
**/
gboolean
gimp_pencil (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,
@ -776,13 +806,15 @@ gimp_pencil (GimpDrawable *drawable,
gboolean
gimp_smudge (GimpDrawable *drawable,
gdouble pressure,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
G_TYPE_DOUBLE, pressure,
@ -819,13 +851,15 @@ gimp_smudge (GimpDrawable *drawable,
**/
gboolean
gimp_smudge_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes)
{
GimpValueArray *args;
GimpValueArray *return_vals;
gboolean success = TRUE;
g_return_val_if_fail (num_strokes >= 2, FALSE);
args = gimp_value_array_new_from_types (NULL,
GIMP_TYPE_DRAWABLE, drawable,
GIMP_TYPE_FLOAT_ARRAY, NULL,

View File

@ -34,73 +34,73 @@ G_BEGIN_DECLS
gboolean gimp_airbrush (GimpDrawable *drawable,
gdouble pressure,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_airbrush_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_clone (GimpDrawable *drawable,
GimpDrawable *src_drawable,
GimpCloneType clone_type,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_clone_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_convolve (GimpDrawable *drawable,
gdouble pressure,
GimpConvolveType convolve_type,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_convolve_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_dodgeburn (GimpDrawable *drawable,
gdouble exposure,
GimpDodgeBurnType dodgeburn_type,
GimpTransferMode dodgeburn_mode,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_dodgeburn_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_eraser (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes,
GimpBrushApplicationMode hardness,
GimpPaintApplicationMode method);
gboolean gimp_eraser_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_heal (GimpDrawable *drawable,
GimpDrawable *src_drawable,
gdouble src_x,
gdouble src_y,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_heal_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_paintbrush (GimpDrawable *drawable,
gdouble fade_out,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes,
GimpPaintApplicationMode method,
gdouble gradient_length);
gboolean gimp_paintbrush_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_pencil (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_smudge (GimpDrawable *drawable,
gdouble pressure,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);
gboolean gimp_smudge_default (GimpDrawable *drawable,
gint num_strokes,
gsize num_strokes,
const gdouble *strokes);

View File

@ -20,7 +20,7 @@ sub stroke_arg () {
{ name => 'strokes', type => 'floatarray',
desc => 'Array of stroke coordinates: { s1.x, s1.y, s2.x, s2.y, ...,
sn.x, sn.y }',
array => { type => '2 <= int32',
array => { type => '2 <= size',
desc => 'Number of stroke control points (count each
coordinate as 2 points)' } }
}
@ -1002,7 +1002,7 @@ paint_tools_stroke (Gimp *gimp,
GimpContext *context,
GimpPaintOptions *options,
GimpDrawable *drawable,
gint n_strokes,
gsize n_strokes,
const gdouble *strokes,
GError **error,
const gchar *first_property_name,

View File

@ -188,6 +188,7 @@ sub generate_fun {
my $arglist = "";
my $argdesc = "";
my $sincedesc = "";
my $inargs_testing = "";
my $value_array = "";
my $arg_array = "";
my $argc = 0;
@ -201,6 +202,34 @@ sub generate_fun {
if (exists $_->{nopdb}) {
$argc--;
if (defined $typeinfo[0]) {
$min = ($typeinfo[1] eq '<') ? ($typeinfo[0] + 1) : $typeinfo[0];
# gsize is positive, no need to test for >= 0.
if ($min > 0) {
if ($rettype eq 'void') {
# void rettype is in fact boolean.
$inargs_testing .= "\n" . ' ' x 2 . "g_return_val_if_fail ($_->{name} >= $min, FALSE);";
}
else {
# TODO: I should in fact test the exact return
# type. E.g. it could be int or float. But since
# we have no such case (while also generating in
# argument testing) so far, I took the easy way
# out. To be completed if needed.
$inargs_testing .= "\n" . ' ' x 2 . "g_return_val_if_fail ($_->{name} >= $min, NULL);";
}
}
}
if (defined $typeinfo[2]) {
$max = ($typeinfo[3] eq '<') ? ($typeinfo[2] - 1) : $typeinfo[2];
if ($rettype eq 'void') {
$inargs_testing .= "\n" . ' ' x 2 . "g_return_val_if_fail ($_->{name} <= $max, FALSE);";
}
else {
$inargs_testing .= "\n" . ' ' x 2 . "g_return_val_if_fail ($_->{name} <= $max, NULL);";
}
}
}
else {
# This gets passed to gimp_value_array_new_with_types()
@ -276,6 +305,10 @@ sub generate_fun {
$argc++;
}
if ($inargs_testing ne "") {
$inargs_testing .= "\n";
}
# This marshals the return value(s)
my $return_args = "";
my $return_marshal = "gimp_value_array_unref (return_vals);";
@ -553,7 +586,7 @@ $wrapped$funcname ($clist)
{
GimpValueArray *args;
GimpValueArray *return_vals;$return_args
$inargs_testing
args = gimp_value_array_new_from_types (NULL,
${value_array}G_TYPE_NONE);
$arg_array