diff options
Diffstat (limited to 'Bugzilla')
-rw-r--r-- | Bugzilla/Auth/Verify/LDAP.pm | 2 | ||||
-rw-r--r-- | Bugzilla/CGI.pm | 12 | ||||
-rw-r--r-- | Bugzilla/Constants.pm | 2 | ||||
-rw-r--r-- | Bugzilla/DB/Oracle.pm | 70 | ||||
-rw-r--r-- | Bugzilla/DB/Schema/Oracle.pm | 64 | ||||
-rw-r--r-- | Bugzilla/DB/Schema/Pg.pm | 10 | ||||
-rw-r--r-- | Bugzilla/Search.pm | 56 | ||||
-rw-r--r-- | Bugzilla/Search/Saved.pm | 2 | ||||
-rw-r--r-- | Bugzilla/User.pm | 2 | ||||
-rw-r--r-- | Bugzilla/WebService/Bug.pm | 5 |
10 files changed, 181 insertions, 44 deletions
diff --git a/Bugzilla/Auth/Verify/LDAP.pm b/Bugzilla/Auth/Verify/LDAP.pm index cdc802ca0..0f10f9fbf 100644 --- a/Bugzilla/Auth/Verify/LDAP.pm +++ b/Bugzilla/Auth/Verify/LDAP.pm @@ -41,6 +41,7 @@ use Bugzilla::User; use Bugzilla::Util; use Net::LDAP; +use Net::LDAP::Util qw(escape_filter_value); use constant admin_can_create_account => 0; use constant user_can_create_account => 0; @@ -144,6 +145,7 @@ sub check_credentials { sub _bz_search_params { my ($username) = @_; + $username = escape_filter_value($username); return (base => Bugzilla->params->{"LDAPBaseDN"}, scope => "sub", filter => '(&(' . Bugzilla->params->{"LDAPuidattribute"} diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm index ce89a9e6d..7f98c1653 100644 --- a/Bugzilla/CGI.pm +++ b/Bugzilla/CGI.pm @@ -180,6 +180,16 @@ sub clean_search_url { # Delete leftovers from the login form $self->delete('Bugzilla_remember', 'GoAheadAndLogIn'); + # Delete the token if we're not performing an action which needs it + unless ((defined $self->param('remtype') + && ($self->param('remtype') eq 'asdefault' + || $self->param('remtype') eq 'asnamed')) + || (defined $self->param('remaction') + && $self->param('remaction') eq 'forget')) + { + $self->delete("token"); + } + foreach my $num (1,2,3) { # If there's no value in the email field, delete the related fields. if (!$self->param("email$num")) { @@ -368,7 +378,7 @@ sub param { sub _fix_utf8 { my $input = shift; # The is_utf8 is here in case CGI gets smart about utf8 someday. - utf8::decode($input) if defined $input && !utf8::is_utf8($input); + utf8::decode($input) if defined $input && !ref $input && !utf8::is_utf8($input); return $input; } diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm index efa1cde4e..aba988c18 100644 --- a/Bugzilla/Constants.pm +++ b/Bugzilla/Constants.pm @@ -202,7 +202,7 @@ use Memoize; # CONSTANTS # # Bugzilla version -use constant BUGZILLA_VERSION => "4.2.2+"; +use constant BUGZILLA_VERSION => "4.2.3+"; # Location of the remote and local XML files to track new releases. use constant REMOTE_FILE => 'http://updates.bugzilla.org/bugzilla-update.xml'; diff --git a/Bugzilla/DB/Oracle.pm b/Bugzilla/DB/Oracle.pm index 2cbd19a82..da263e084 100644 --- a/Bugzilla/DB/Oracle.pm +++ b/Bugzilla/DB/Oracle.pm @@ -310,8 +310,9 @@ sub adjust_statement { my $has_from = ($part =~ m/\bFROM\b/io) if $is_select; # Oracle recognizes CURRENT_DATE, but not CURRENT_DATE() - $part =~ s/\bCURRENT_DATE\b\(\)/CURRENT_DATE/io; - + # and its CURRENT_DATE is a date+time, so wrap in TRUNC() + $part =~ s/\bCURRENT_DATE\b(?:\(\))?/TRUNC(CURRENT_DATE)/io; + # Oracle use SUBSTR instead of SUBSTRING $part =~ s/\bSUBSTRING\b/SUBSTR/io; @@ -341,7 +342,8 @@ sub adjust_statement { if ($is_select and !$has_from); # Oracle recognizes CURRENT_DATE, but not CURRENT_DATE() - $nonstring =~ s/\bCURRENT_DATE\b\(\)/CURRENT_DATE/io; + # and its CURRENT_DATE is a date+time, so wrap in TRUNC() + $nonstring =~ s/\bCURRENT_DATE\b(?:\(\))?/TRUNC(CURRENT_DATE)/io; # Oracle use SUBSTR instead of SUBSTRING $nonstring =~ s/\bSUBSTRING\b/SUBSTR/io; @@ -635,11 +637,25 @@ sub bz_setup_database { $self->SUPER::bz_setup_database(@_); + my $sth = $self->prepare("SELECT OBJECT_NAME FROM USER_OBJECTS WHERE OBJECT_NAME = ?"); my @tables = $self->bz_table_list_real(); + foreach my $table (@tables) { my @columns = $self->bz_table_columns_real($table); foreach my $column (@columns) { my $def = $self->bz_column_info($table, $column); + # bz_add_column() before Bugzilla 4.2.3 didn't handle primary keys + # correctly (bug 731156). We have to add missing sequences and + # triggers ourselves. + if ($def->{TYPE} =~ /SERIAL/i) { + my $sequence = "${table}_${column}_SEQ"; + my $exists = $self->selectrow_array($sth, undef, $sequence); + if (!$exists) { + my @sql = $self->_get_create_seq_ddl($table, $column); + $self->do($_) foreach @sql; + } + } + if ($def->{REFERENCES}) { my $references = $def->{REFERENCES}; my $update = $references->{UPDATE} || 'CASCADE'; @@ -653,15 +669,13 @@ sub bz_setup_database { $to_table = 'tag'; } if ( $update =~ /CASCADE/i ){ - my $trigger_name = uc($fk_name . "_UC"); - my $exist_trigger = $self->selectcol_arrayref( - "SELECT OBJECT_NAME FROM USER_OBJECTS - WHERE OBJECT_NAME = ?", undef, $trigger_name); + my $trigger_name = uc($fk_name . "_UC"); + my $exist_trigger = $self->selectcol_arrayref($sth, undef, $trigger_name); if(@$exist_trigger) { $self->do("DROP TRIGGER $trigger_name"); } - my $tr_str = "CREATE OR REPLACE TRIGGER $trigger_name" + my $tr_str = "CREATE OR REPLACE TRIGGER $trigger_name" . " AFTER UPDATE OF $to_column ON $to_table " . " REFERENCING " . " NEW AS NEW " @@ -672,22 +686,46 @@ sub bz_setup_database { . " SET $column = :NEW.$to_column" . " WHERE $column = :OLD.$to_column;" . " END $trigger_name;"; - $self->do($tr_str); - } - } - } - } + $self->do($tr_str); + } + } + } + } # Drop the trigger which causes bug 541553 my $trigger_name = "PRODUCTS_MILESTONEURL"; - my $exist_trigger = $self->selectcol_arrayref( - "SELECT OBJECT_NAME FROM USER_OBJECTS - WHERE OBJECT_NAME = ?", undef, $trigger_name); + my $exist_trigger = $self->selectcol_arrayref($sth, undef, $trigger_name); if(@$exist_trigger) { $self->do("DROP TRIGGER $trigger_name"); } } +# These two methods have been copied from Bugzilla::DB::Schema::Oracle. +sub _get_create_seq_ddl { + my ($self, $table, $column) = @_; + + my $seq_name = "${table}_${column}_SEQ"; + my $seq_sql = "CREATE SEQUENCE $seq_name INCREMENT BY 1 START WITH 1 " . + "NOMAXVALUE NOCYCLE NOCACHE"; + my $trigger_sql = $self->_get_create_trigger_ddl($table, $column, $seq_name); + return ($seq_sql, $trigger_sql); +} + +sub _get_create_trigger_ddl { + my ($self, $table, $column, $seq_name) = @_; + + my $trigger_sql = "CREATE OR REPLACE TRIGGER ${table}_${column}_TR " + . " BEFORE INSERT ON $table " + . " FOR EACH ROW " + . " BEGIN " + . " SELECT ${seq_name}.NEXTVAL " + . " INTO :NEW.$column FROM DUAL; " + . " END;"; + return $trigger_sql; +} + +############################################################################ + package Bugzilla::DB::Oracle::st; use base qw(DBI::st); diff --git a/Bugzilla/DB/Schema/Oracle.pm b/Bugzilla/DB/Schema/Oracle.pm index f2d5b8be0..9fafc4515 100644 --- a/Bugzilla/DB/Schema/Oracle.pm +++ b/Bugzilla/DB/Schema/Oracle.pm @@ -199,6 +199,31 @@ sub _get_fk_name { return $fk_name; } +sub get_add_column_ddl { + my $self = shift; + my ($table, $column, $definition, $init_value) = @_; + my @sql; + + # Create sequences and triggers to emulate SERIAL datatypes. + if ($definition->{TYPE} =~ /SERIAL/i) { + # Clone the definition to not alter the original one. + my %def = %$definition; + # Oracle requires to define the column is several steps. + my $pk = delete $def{PRIMARYKEY}; + my $notnull = delete $def{NOTNULL}; + @sql = $self->SUPER::get_add_column_ddl($table, $column, \%def, $init_value); + push(@sql, $self->_get_create_seq_ddl($table, $column)); + push(@sql, "UPDATE $table SET $column = ${table}_${column}_SEQ.NEXTVAL"); + push(@sql, "ALTER TABLE $table MODIFY $column NOT NULL") if $notnull; + push(@sql, "ALTER TABLE $table ADD PRIMARY KEY ($column)") if $pk; + } + else { + @sql = $self->SUPER::get_add_column_ddl(@_); + } + + return @sql; +} + sub get_alter_column_ddl { my ($self, $table, $column, $new_def, $set_nulls_to) = @_; @@ -364,6 +389,29 @@ sub get_rename_column_ddl { return @sql; } +sub get_drop_column_ddl { + my $self = shift; + my ($table, $column) = @_; + my @sql; + push(@sql, $self->SUPER::get_drop_column_ddl(@_)); + my $dbh=Bugzilla->dbh; + my $trigger_name = uc($table . "_" . $column); + my $exist_trigger = $dbh->selectcol_arrayref( + "SELECT OBJECT_NAME FROM USER_OBJECTS + WHERE OBJECT_NAME = ?", undef, $trigger_name); + if(@$exist_trigger) { + push(@sql, "DROP TRIGGER $trigger_name"); + } + # If this column is of type SERIAL, we need to drop the sequence + # and trigger that went along with it. + my $def = $self->get_column_abstract($table, $column); + if ($def->{TYPE} =~ /SERIAL/i) { + push(@sql, "DROP SEQUENCE ${table}_${column}_SEQ"); + push(@sql, "DROP TRIGGER ${table}_${column}_TR"); + } + return @sql; +} + sub get_rename_table_sql { my ($self, $old_name, $new_name) = @_; if (lc($old_name) eq lc($new_name)) { @@ -465,20 +513,4 @@ sub get_set_serial_sql { return @sql; } -sub get_drop_column_ddl { - my $self = shift; - my ($table, $column) = @_; - my @sql; - push(@sql, $self->SUPER::get_drop_column_ddl(@_)); - my $dbh=Bugzilla->dbh; - my $trigger_name = uc($table . "_" . $column); - my $exist_trigger = $dbh->selectcol_arrayref( - "SELECT OBJECT_NAME FROM USER_OBJECTS - WHERE OBJECT_NAME = ?", undef, $trigger_name); - if(@$exist_trigger) { - push(@sql, "DROP TRIGGER $trigger_name"); - } - return @sql; -} - 1; diff --git a/Bugzilla/DB/Schema/Pg.pm b/Bugzilla/DB/Schema/Pg.pm index ef6e5671d..d21f5099c 100644 --- a/Bugzilla/DB/Schema/Pg.pm +++ b/Bugzilla/DB/Schema/Pg.pm @@ -90,6 +90,16 @@ sub _initialize { } #eosub--_initialize #-------------------------------------------------------------------- +sub get_create_database_sql { + my ($self, $name) = @_; + # We only create as utf8 if we have no params (meaning we're doing + # a new installation) or if the utf8 param is on. + my $create_utf8 = Bugzilla->params->{'utf8'} + || !defined Bugzilla->params->{'utf8'}; + my $charset = $create_utf8 ? "ENCODING 'UTF8' TEMPLATE template0" : ''; + return ("CREATE DATABASE $name $charset"); +} + sub get_rename_column_ddl { my ($self, $table, $old_name, $new_name) = @_; if (lc($old_name) eq lc($new_name)) { diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm index 8e70a9721..a4db2e05d 100644 --- a/Bugzilla/Search.pm +++ b/Bugzilla/Search.pm @@ -824,10 +824,19 @@ sub _add_extra_column { # These are the columns that we're going to be actually SELECTing. sub _display_columns { my ($self) = @_; - # Do not alter the list specified here at all, even if they are duplicated. - # Those are passed by the caller, and the caller expects to get them back - # in the exact same order. - $self->{display_columns} ||= [$self->_input_columns, $self->_extra_columns]; + return @{ $self->{display_columns} } if $self->{display_columns}; + + # Do not alter the list from _input_columns at all, even if there are + # duplicated columns. Those are passed by the caller, and the caller + # expects to get them back in the exact same order. + my @columns = $self->_input_columns; + + # Only add columns which are not already listed. + my %list = map { $_ => 1 } @columns; + foreach my $column ($self->_extra_columns) { + push(@columns, $column) unless $list{$column}++; + } + $self->{display_columns} = \@columns; return @{ $self->{display_columns} }; } @@ -2304,6 +2313,12 @@ sub _long_desc_changedbefore_after { }; push(@$joins, $join); $args->{term} = "$table.bug_when IS NOT NULL"; + + # If the user is not part of the insiders group, they cannot see + # private comments + if (!$self->_user->is_insider) { + $args->{term} .= " AND $table.isprivate = 0"; + } } sub _content_matches { @@ -2786,8 +2801,10 @@ sub _changedbefore_changedafter { extra => ["$table.fieldid = $field_id", "$table.bug_when $sql_operator $sql_date"], }; - push(@$joins, $join); + $args->{term} = "$table.bug_when IS NOT NULL"; + $self->_changed_security_check($args, $join); + push(@$joins, $join); } sub _changedfrom_changedto { @@ -2806,9 +2823,10 @@ sub _changedfrom_changedto { extra => ["$table.fieldid = $field_id", "$table.$column = $quoted"], }; - push(@$joins, $join); $args->{term} = "$table.bug_when IS NOT NULL"; + $self->_changed_security_check($args, $join); + push(@$joins, $join); } sub _changedby { @@ -2827,8 +2845,32 @@ sub _changedby { extra => ["$table.fieldid = $field_id", "$table.who = $user_id"], }; - push(@$joins, $join); + $args->{term} = "$table.bug_when IS NOT NULL"; + $self->_changed_security_check($args, $join); + push(@$joins, $join); +} + +sub _changed_security_check { + my ($self, $args, $join) = @_; + my ($chart_id, $field) = @$args{qw(chart_id field)}; + + my $field_object = $self->_chart_fields->{$field} + || ThrowCodeError("invalid_field_name", { field => $field }); + my $field_id = $field_object->id; + + # If the user is not part of the insiders group, they cannot see + # changes to attachments (including attachment flags) that are private + if ($field =~ /^(?:flagtypes\.name$|attach)/ and !$self->_user->is_insider) { + $join->{then_to} = { + as => "attach_${field_id}_$chart_id", + table => 'attachments', + from => "act_${field_id}_$chart_id.attach_id", + to => 'attach_id', + }; + + $args->{term} .= " AND COALESCE(attach_${field_id}_$chart_id.isprivate, 0) = 0"; + } } ###################### diff --git a/Bugzilla/Search/Saved.pm b/Bugzilla/Search/Saved.pm index fc773fcde..99194112a 100644 --- a/Bugzilla/Search/Saved.pm +++ b/Bugzilla/Search/Saved.pm @@ -109,7 +109,7 @@ sub check { if (!$search->shared_with_group or !$user->in_group($search->shared_with_group)) { - ThrowUserError('missing_query', { queryname => $search->name, + ThrowUserError('missing_query', { name => $search->name, sharer_id => $search->user->id }); } diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm index 9d736d585..0b4c1c867 100644 --- a/Bugzilla/User.pm +++ b/Bugzilla/User.pm @@ -1538,6 +1538,8 @@ sub match_field { my @logins; for my $query (@queries) { $query = trim($query); + next if $query eq ''; + my $users = match( $query, # match string $limit, # match limit diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm index 6b5d8e3ef..e62ad0570 100644 --- a/Bugzilla/WebService/Bug.pm +++ b/Bugzilla/WebService/Bug.pm @@ -2410,8 +2410,9 @@ B<STABLE> =item B<Description> This allows you to create a new bug in Bugzilla. If you specify any -invalid fields, they will be ignored. If you specify any fields you -are not allowed to set, they will just be set to their defaults or ignored. +invalid fields, an error will be thrown stating which field is invalid. +If you specify any fields you are not allowed to set, they will just be +set to their defaults or ignored. You cannot currently set all the items here that you can set on enter_bug.cgi. |