summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Auth/Login/Stack.pm10
-rw-r--r--Bugzilla/Util.pm55
2 files changed, 37 insertions, 28 deletions
diff --git a/Bugzilla/Auth/Login/Stack.pm b/Bugzilla/Auth/Login/Stack.pm
index 0f3661954..e8d9c4635 100644
--- a/Bugzilla/Auth/Login/Stack.pm
+++ b/Bugzilla/Auth/Login/Stack.pm
@@ -28,6 +28,7 @@ use fields qw(
);
use Hash::Util qw(lock_keys);
use Bugzilla::Hook;
+use Bugzilla::Constants;
use List::MoreUtils qw(any);
sub new {
@@ -60,8 +61,13 @@ sub get_login_info {
}
$result = $object->get_login_info(@_);
$self->{successful} = $object;
- last if !$result->{failure};
- # So that if none of them succeed, it's undef.
+
+ # We only carry on down the stack if this method denied all knowledge.
+ last unless ($result->{failure}
+ && ($result->{failure} eq AUTH_NODATA
+ || $result->{failure} eq AUTH_NO_SUCH_USER));
+
+ # If none of the methods succeed, it's undef.
$self->{successful} = undef;
}
return $result;
diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm
index ac6848bfa..4c268552b 100644
--- a/Bugzilla/Util.pm
+++ b/Bugzilla/Util.pm
@@ -308,36 +308,39 @@ sub use_attachbase {
sub diff_arrays {
my ($old_ref, $new_ref, $attrib) = @_;
-
- my @old = @$old_ref;
- my @new = @$new_ref;
$attrib ||= 'name';
- # For each pair of (old, new) entries:
- # If object arrays were passed then an attribute should be defined;
- # If they're equal, set them to empty. When done, @old contains entries
- # that were removed; @new contains ones that got added.
- foreach my $oldv (@old) {
- foreach my $newv (@new) {
- next if ($newv eq '' or $oldv eq '');
- if (blessed($oldv) and blessed($newv)) {
- if ($oldv->$attrib eq $newv->$attrib) {
- $newv = $oldv = '';
- }
- }
- else {
- if ($oldv eq $newv) {
- $newv = $oldv = ''
- }
- }
- }
+ my (%counts, %pos);
+ # We are going to alter the old array.
+ my @old = @$old_ref;
+ my $i = 0;
+
+ # $counts{foo}-- means old, $counts{foo}++ means new.
+ # If $counts{foo} becomes positive, then we are adding new items,
+ # else we simply cancel one old existing item. Remaining items
+ # in the old list have been removed.
+ foreach (@old) {
+ next unless defined $_;
+ my $value = blessed($_) ? $_->$attrib : $_;
+ $counts{$value}--;
+ push @{$pos{$value}}, $i++;
}
-
- my @removed;
my @added;
- @removed = grep { $_ ne '' } @old;
- @added = grep { $_ ne '' } @new;
-
+ foreach (@$new_ref) {
+ next unless defined $_;
+ my $value = blessed($_) ? $_->$attrib : $_;
+ if (++$counts{$value} > 0) {
+ # Ignore empty strings, but objects having an empty string
+ # as attribute are fine.
+ push(@added, $_) unless ($value eq '' && !blessed($_));
+ }
+ else {
+ my $old_pos = shift @{$pos{$value}};
+ $old[$old_pos] = undef;
+ }
+ }
+ # Ignore canceled items as well as empty strings.
+ my @removed = grep { defined $_ && $_ ne '' } @old;
return (\@removed, \@added);
}