Commit d320ac0e authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 288663: The inclusion and exclusion lists behave incorrectly when a product…

Bug 288663: The inclusion and exclusion lists behave incorrectly when a product or a component is called "Any" - Patch by Frédéric Buclin <LpSolit@gmail.com> r=myk a=myk
parent dfbc39b0
......@@ -184,7 +184,9 @@ sub get_exclusions {
=item C<get_clusions($id, $type)>
Someone please document this
Return a hash of product/component IDs and names
associated with the flagtype:
$clusions{'product_name:component_name'} = "product_ID:component_ID"
=back
......@@ -192,23 +194,29 @@ Someone please document this
sub get_clusions {
my ($id, $type) = @_;
&::PushGlobalSQLState();
&::SendSQL("SELECT products.name, components.name " .
"FROM flagtypes, flag${type}clusions " .
"LEFT OUTER JOIN products ON flag${type}clusions.product_id = products.id " .
"LEFT OUTER JOIN components ON flag${type}clusions.component_id = components.id " .
"WHERE flagtypes.id = $id AND flag${type}clusions.type_id = flagtypes.id");
my @clusions = ();
while (&::MoreSQLData()) {
my ($product, $component) = &::FetchSQLData();
$product ||= "Any";
$component ||= "Any";
push(@clusions, "$product:$component");
my $dbh = Bugzilla->dbh;
my $list =
$dbh->selectall_arrayref("SELECT products.id, products.name, " .
" components.id, components.name " .
"FROM flagtypes, flag${type}clusions " .
"LEFT OUTER JOIN products " .
" ON flag${type}clusions.product_id = products.id " .
"LEFT OUTER JOIN components " .
" ON flag${type}clusions.component_id = components.id " .
"WHERE flagtypes.id = ? " .
" AND flag${type}clusions.type_id = flagtypes.id",
undef, $id);
my %clusions;
foreach my $data (@$list) {
my ($product_id, $product_name, $component_id, $component_name) = @$data;
$product_id ||= 0;
$product_name ||= "__Any__";
$component_id ||= 0;
$component_name ||= "__Any__";
$clusions{"$product_name:$component_name"} = "$product_id:$component_id";
}
&::PopGlobalSQLState();
return \@clusions;
return \%clusions;
}
=pod
......
......@@ -146,9 +146,11 @@ sub edit {
# Otherwise set the target type (the minimal information about the type
# that the template needs to know) from the URL parameter and default
# the list of inclusions to all categories.
else {
else {
my %inclusions;
$inclusions{"__Any__:__Any__"} = "0:0";
$vars->{'type'} = { 'target_type' => scalar $cgi->param('target_type'),
'inclusions' => ["__Any__:__Any__"] };
'inclusions' => \%inclusions };
}
# Return the appropriate HTTP response headers.
......@@ -171,13 +173,13 @@ sub processCategoryChange {
if ($categoryAction eq 'include') {
validateProduct();
validateComponent();
my $category = ($cgi->param('product') || "__Any__") . ":" . ($cgi->param('component') || "__Any__");
my $category = ($product_id || 0) . ":" . ($component_id || 0);
push(@inclusions, $category) unless grep($_ eq $category, @inclusions);
}
elsif ($categoryAction eq 'exclude') {
validateProduct();
validateComponent();
my $category = ($cgi->param('product') || "__Any__") . ":" . ($cgi->param('component') || "__Any__");
my $category = ($product_id || 0) . ":" . ($component_id || 0);
push(@exclusions, $category) unless grep($_ eq $category, @exclusions);
}
elsif ($categoryAction eq 'removeInclusion') {
......@@ -187,6 +189,11 @@ sub processCategoryChange {
@exclusions = map(($_ eq $cgi->param('exclusion_to_remove') ? () : $_), @exclusions);
}
# Convert the array @clusions('prod_ID:comp_ID') back to a hash of
# the form %clusions{'prod_name:comp_name'} = 'prod_ID:comp_ID'
my %inclusions = clusion_array_to_hash(\@inclusions);
my %exclusions = clusion_array_to_hash(\@exclusions);
# Get this installation's products and components.
GetVersionTable();
......@@ -199,8 +206,8 @@ sub processCategoryChange {
$vars->{'action'} = $cgi->param('action');
my $type = {};
foreach my $key ($cgi->param()) { $type->{$key} = $cgi->param($key) }
$type->{'inclusions'} = \@inclusions;
$type->{'exclusions'} = \@exclusions;
$type->{'inclusions'} = \%inclusions;
$type->{'exclusions'} = \%exclusions;
$vars->{'type'} = $type;
# Return the appropriate HTTP response headers.
......@@ -211,6 +218,21 @@ sub processCategoryChange {
|| ThrowTemplateError($template->error());
}
# Convert the array @clusions('prod_ID:comp_ID') back to a hash of
# the form %clusions{'prod_name:comp_name'} = 'prod_ID:comp_ID'
sub clusion_array_to_hash {
my $array = shift;
my %hash;
foreach my $ids (@$array) {
trick_taint($ids);
my ($product_id, $component_id) = split(":", $ids);
my $product_name = get_product_name($product_id) || "__Any__";
my $component_name = get_component_name($component_id) || "__Any__";
$hash{"$product_name:$component_name"} = $ids;
}
return %hash;
}
sub insert {
validateName();
validateDescription();
......@@ -253,16 +275,7 @@ sub insert {
$cgi->param('request_gid') . ")");
# Populate the list of inclusions/exclusions for this flag type.
foreach my $category_type ("inclusions", "exclusions") {
foreach my $category ($cgi->param($category_type)) {
my ($product, $component) = split(/:/, $category);
my $product_id = get_product_id($product) || "NULL";
my $component_id =
get_component_id($product_id, $component) || "NULL";
SendSQL("INSERT INTO flag$category_type (type_id, product_id, " .
"component_id) VALUES ($id, $product_id, $component_id)");
}
}
validateAndSubmit($id);
$dbh->bz_unlock_tables();
......@@ -314,17 +327,7 @@ sub update {
WHERE id = $id");
# Update the list of inclusions/exclusions for this flag type.
foreach my $category_type ("inclusions", "exclusions") {
SendSQL("DELETE FROM flag$category_type WHERE type_id = $id");
foreach my $category ($cgi->param($category_type)) {
my ($product, $component) = split(/:/, $category);
my $product_id = get_product_id($product) || "NULL";
my $component_id =
get_component_id($product_id, $component) || "NULL";
SendSQL("INSERT INTO flag$category_type (type_id, product_id, " .
"component_id) VALUES ($id, $product_id, $component_id)");
}
}
validateAndSubmit($id);
$dbh->bz_unlock_tables();
......@@ -558,3 +561,37 @@ sub validateGroups {
$cgi->param($col, $gid);
}
}
# At this point, values either come the DB itself or have been recently
# added by the user and have passed all validation tests.
# The only way to have invalid product/component combinations is to
# hack the URL. So we silently ignore them, if any.
sub validateAndSubmit ($) {
my ($id) = @_;
my $dbh = Bugzilla->dbh;
foreach my $category_type ("inclusions", "exclusions") {
# Will be used several times below.
my $sth = $dbh->prepare("INSERT INTO flag$category_type " .
"(type_id, product_id, component_id) " .
"VALUES (?, ?, ?)");
$dbh->do("DELETE FROM flag$category_type WHERE type_id = ?", undef, $id);
foreach my $category ($cgi->param($category_type)) {
trick_taint($category);
my ($product_id, $component_id) = split(":", $category);
# The product does not exist.
next if ($product_id && !get_product_name($product_id));
# A component was selected without a product being selected.
next if (!$product_id && $component_id);
# The component does not belong to this product.
next if ($component_id
&& !$dbh->selectrow_array("SELECT id FROM components
WHERE id = ? AND product_id = ?",
undef, ($component_id, $product_id)));
$product_id ||= undef;
$component_id ||= undef;
$sth->execute($id, $product_id, $component_id);
}
}
}
......@@ -64,10 +64,10 @@
<input type="hidden" name="id" value="[% type.id %]">
<input type="hidden" name="target_type" value="[% type.target_type %]">
[% FOREACH category = type.inclusions %]
<input type="hidden" name="inclusions" value="[% category FILTER html %]">
<input type="hidden" name="inclusions" value="[% category.value FILTER html %]">
[% END %]
[% FOREACH category = type.exclusions %]
<input type="hidden" name="exclusions" value="[% category FILTER html %]">
<input type="hidden" name="exclusions" value="[% category.value FILTER html %]">
[% END %]
<table id="form" cellspacing="0" cellpadding="4" border="0">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment