diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm index 1da69fae2..426a272cc 100644 --- a/Bugzilla/Field.pm +++ b/Bugzilla/Field.pm @@ -551,7 +551,8 @@ sub can_tweak return 1; } -# Return valid values for this field, arrayref of Bugzilla::Field::Choice objects. +# Return valid values for this field, arrayref of Bugzilla::Field::Choice objects, +# filtered by the current user's permissions. # Includes disabled values is $include_disabled == true sub legal_values { @@ -943,24 +944,24 @@ sub touch sub set_visibility_values { my $self = shift; - my ($value_ids) = @_; - $self->update_visibility_values(FLAG_VISIBLE, $value_ids); + my ($value_ids, $skip_invisible) = @_; + $self->update_visibility_values(FLAG_VISIBLE, $value_ids, $skip_invisible); return $value_ids && @$value_ids; } sub set_null_visibility_values { my $self = shift; - my ($value_ids) = @_; - $self->update_visibility_values(FLAG_NULLABLE, $value_ids); + my ($value_ids, $skip_invisible) = @_; + $self->update_visibility_values(FLAG_NULLABLE, $value_ids, $skip_invisible); return $value_ids && @$value_ids; } sub set_clone_visibility_values { my $self = shift; - my ($value_ids) = @_; - $self->update_visibility_values(FLAG_CLONED, $value_ids); + my ($value_ids, $skip_invisible) = @_; + $self->update_visibility_values(FLAG_CLONED, $value_ids, $skip_invisible); return $value_ids && @$value_ids; } @@ -992,7 +993,7 @@ sub clear_default_values sub update_visibility_values { my $self = shift; - my ($controlled_value_id, $visibility_value_ids) = @_; + my ($controlled_value_id, $visibility_value_ids, $skip_invisible) = @_; $visibility_value_ids ||= []; my $vis_field = $self->flag_field($controlled_value_id); if (!$vis_field) @@ -1014,6 +1015,16 @@ sub update_visibility_values $h = $h->{null}->{$self->id} if $controlled_value_id == FLAG_NULLABLE; $h = $h->{clone}->{$self->id} if $controlled_value_id == FLAG_CLONED; $h = $h ? { %$h } : {}; + if ($skip_invisible) + { + # Do not affect visibility values the user can't see + # so he can't damage other user's visibility values for the same field value + my $allowed = { map { $_->id => 1 } @{$vis_field->legal_values} }; + for (keys %$h) + { + delete $h->{$_} if !$allowed->{$_}; + } + } my $add = []; for (@$visibility_value_ids) { diff --git a/Bugzilla/Field/Choice.pm b/Bugzilla/Field/Choice.pm index a7c850066..11e33f918 100644 --- a/Bugzilla/Field/Choice.pm +++ b/Bugzilla/Field/Choice.pm @@ -413,8 +413,8 @@ sub set_sortkey { $_[0]->set('sortkey', $_[1]); } sub set_visibility_values { my $self = shift; - my ($value_ids) = @_; - $self->field->update_visibility_values($self->id, $value_ids); + my ($value_ids, $skip_invisible) = @_; + $self->field->update_visibility_values($self->id, $value_ids, $skip_invisible); delete $self->{visibility_values}; return $value_ids; } diff --git a/editfields.cgi b/editfields.cgi index ac0b421f5..3c54d3c62 100755 --- a/editfields.cgi +++ b/editfields.cgi @@ -148,7 +148,7 @@ elsif ($action eq 'update') } else { - $field->${\$_->[2]}([ list $ARGS->{$_->[3]} ]); + $field->${\$_->[2]}([ list $ARGS->{$_->[3]} ], 'SKIP_INVISIBLE'); } } } diff --git a/editvalues.cgi b/editvalues.cgi index a8d236552..cef076cd6 100755 --- a/editvalues.cgi +++ b/editvalues.cgi @@ -165,7 +165,7 @@ if ($action eq 'update') } if ($value->field->value_field) { - $vars->{changes}->{visibility_values} = $value->set_visibility_values([ list $ARGS->{visibility_value_id} ]); + $vars->{changes}->{visibility_values} = $value->set_visibility_values([ list $ARGS->{visibility_value_id} ], 'SKIP_INVISIBLE'); } $vars->{changes}->{control_lists} = 1 if $field->update_control_lists($value->id, $ARGS); delete_token($token);