Commit 054be7c4 authored by dmose%mozilla.org's avatar dmose%mozilla.org

a bug fix or two and a whole bunch of sanity-checking of form submissions stuff

parent 1e216d4e
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
# Rights Reserved. # Rights Reserved.
# #
# Contributor(s): Terry Weissman <terry@mozilla.org> # Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
# Contains some global routines used throughout the CGI scripts of Bugzilla. # Contains some global routines used throughout the CGI scripts of Bugzilla.
...@@ -169,10 +170,56 @@ sub ProcessMultipartFormFields { ...@@ -169,10 +170,56 @@ sub ProcessMultipartFormFields {
$::FORM{$i} =~ s/\r$//; $::FORM{$i} =~ s/\r$//;
} }
} }
# check and see if a given field exists, is non-empty, and is set to a
# legal value. assume a browser bug and abort appropriately if not.
# if $legalsRef is not passed, just check to make sure the value exists and
# is non-NULL
#
sub CheckFormField (\%$;\@) {
my ($formRef, # a reference to the form to check (a hash)
$fieldname, # the fieldname to check
$legalsRef # (optional) ref to a list of legal values
) = @_;
if ( !defined $formRef->{$fieldname} ||
trim($formRef->{$fieldname}) eq "" ||
(defined($legalsRef) &&
lsearch($legalsRef, $formRef->{$fieldname})<0) ){
print "A legal $fieldname was not set; ";
print Param("browserbugmessage");
exit 0;
}
}
# check and see if a given field is defined, and abort if not
#
sub CheckFormFieldDefined (\%$) {
my ($formRef, # a reference to the form to check (a hash)
$fieldname, # the fieldname to check
) = @_;
if ( !defined $formRef->{$fieldname} ) {
print "$fieldname was not defined; ";
print Param("browserbugmessage");
exit 0;
}
}
# check and see if a given string actually represents a positive
# integer, and abort if not.
#
sub CheckPosInt($) {
my ($number) = @_; # the fieldname to check
if ( $number !~ /^[1-9][0-9]*$/ ) {
print "Received string \"$number\" when postive integer expected; ";
print Param("browserbugmessage");
exit 0;
}
}
sub FormData { sub FormData {
my ($field) = (@_); my ($field) = (@_);
...@@ -247,7 +294,17 @@ sub make_options { ...@@ -247,7 +294,17 @@ sub make_options {
} }
} }
if (!$found && $default ne "") { if (!$found && $default ne "") {
if ( Param("strictvaluechecks") &&
($default ne $::dontchange) && ($default ne "-All-") ) {
print "Possible bug database corruption has been detected. " .
"Please send mail to " . Param("maintainer") . " with " .
"details of what you were doing when this message " .
"appeared. Thank you.\n";
exit 0;
} else {
$popup .= "<OPTION SELECTED>$default"; $popup .= "<OPTION SELECTED>$default";
}
} }
return $popup; return $popup;
} }
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
# Rights Reserved. # Rights Reserved.
# #
# Contributor(s): Terry Weissman <terry@mozilla.org> # Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
use diagnostics; use diagnostics;
use strict; use strict;
...@@ -755,7 +756,7 @@ document.write(\" <input type=button value=\\\"Uncheck All\\\" onclick=\\\"SetCh ...@@ -755,7 +756,7 @@ document.write(\" <input type=button value=\\\"Uncheck All\\\" onclick=\\\"SetCh
<BR> <BR>
<TEXTAREA WRAP=HARD NAME=comment ROWS=5 COLS=80></TEXTAREA><BR>"; <TEXTAREA WRAP=HARD NAME=comment ROWS=5 COLS=80></TEXTAREA><BR>";
if ($::usergroupset ne '0' && $buggroupset =~ /^\d*$/) { if ($::usergroupset ne '0' && $buggroupset =~ /^\d+$/) {
SendSQL("select bit, description, (bit & $buggroupset != 0) from groups where bit & $::usergroupset != 0 and isbuggroup != 0 order by bit"); SendSQL("select bit, description, (bit & $buggroupset != 0) from groups where bit & $::usergroupset != 0 and isbuggroup != 0 order by bit");
while (MoreSQLData()) { while (MoreSQLData()) {
my ($bit, $description, $ison) = (FetchSQLData()); my ($bit, $description, $ison) = (FetchSQLData());
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
# #
# Contributor(s): Terry Weissman <terry@mozilla.org> # Contributor(s): Terry Weissman <terry@mozilla.org>
# Dawn Endico <endico@mozilla.org> # Dawn Endico <endico@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
# This file defines all the parameters that we have a GUI to edit within # This file defines all the parameters that we have a GUI to edit within
...@@ -368,7 +369,14 @@ DefParam("allowbugdeletion", ...@@ -368,7 +369,14 @@ DefParam("allowbugdeletion",
"b", "b",
0); 0);
DefParam("strictvaluechecks",
"Do stricter integrity checking on both form submission values and values read in from the database.",
"b",
0);
DefParam("browserbugmessage",
"If strictvaluechecks is on, and the bugzilla gets unexpected data from the browser, in addition to displaying the cause of the problem, it will output this HTML as well.",
"l",
"this may indicate a bug in your browser.\n");
1; 1;
...@@ -19,7 +19,7 @@ ...@@ -19,7 +19,7 @@
# Rights Reserved. # Rights Reserved.
# #
# Contributor(s): Terry Weissman <terry@mozilla.org> # Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
use diagnostics; use diagnostics;
use strict; use strict;
...@@ -63,7 +63,6 @@ if (!defined $::FORM{'component'} || $::FORM{'component'} eq "") { ...@@ -63,7 +63,6 @@ if (!defined $::FORM{'component'} || $::FORM{'component'} eq "") {
print "and choose a component.\n"; print "and choose a component.\n";
exit 0 exit 0
} }
if (!defined $::FORM{'short_desc'} || trim($::FORM{'short_desc'}) eq "") { if (!defined $::FORM{'short_desc'} || trim($::FORM{'short_desc'}) eq "") {
print "You must enter a summary for this bug. Please hit the\n"; print "You must enter a summary for this bug. Please hit the\n";
...@@ -71,6 +70,22 @@ if (!defined $::FORM{'short_desc'} || trim($::FORM{'short_desc'}) eq "") { ...@@ -71,6 +70,22 @@ if (!defined $::FORM{'short_desc'} || trim($::FORM{'short_desc'}) eq "") {
exit; exit;
} }
if ( Param("strictvaluechecks") ) {
GetVersionTable();
CheckFormField(\%::FORM, 'reporter');
CheckFormField(\%::FORM, 'product', \@::legal_product);
CheckFormField(\%::FORM, 'version', \@{$::versions{$::FORM{'product'}}});
CheckFormField(\%::FORM, 'rep_platform', \@::legal_platform);
CheckFormField(\%::FORM, 'bug_severity', \@::legal_severity);
CheckFormField(\%::FORM, 'priority', \@::legal_priority);
CheckFormField(\%::FORM, 'op_sys', \@::legal_opsys);
CheckFormFieldDefined(\%::FORM, 'assigned_to');
CheckFormField(\%::FORM, 'bug_status', \@::legal_bug_status);
CheckFormFieldDefined(\%::FORM, 'bug_file_loc');
CheckFormField(\%::FORM, 'component',
\@{$::components{$::FORM{'product'}}});
CheckFormFieldDefined(\%::FORM, 'comment');
}
my $forceAssignedOK = 0; my $forceAssignedOK = 0;
if ($::FORM{'assigned_to'} eq "") { if ($::FORM{'assigned_to'} eq "") {
...@@ -87,8 +102,7 @@ $::FORM{'reporter'} = DBNameToIdAndCheck($::FORM{'reporter'}); ...@@ -87,8 +102,7 @@ $::FORM{'reporter'} = DBNameToIdAndCheck($::FORM{'reporter'});
my @bug_fields = ("reporter", "product", "version", "rep_platform", my @bug_fields = ("reporter", "product", "version", "rep_platform",
"bug_severity", "priority", "op_sys", "assigned_to", "bug_severity", "priority", "op_sys", "assigned_to",
"bug_status", "bug_file_loc", "short_desc", "component", "bug_status", "bug_file_loc", "short_desc", "component");
"status_whiteboard", "target_milestone");
if (Param("useqacontact")) { if (Param("useqacontact")) {
SendSQL("select initialqacontact from components where program=" . SendSQL("select initialqacontact from components where program=" .
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
# Rights Reserved. # Rights Reserved.
# #
# Contributor(s): Terry Weissman <terry@mozilla.org> # Contributor(s): Terry Weissman <terry@mozilla.org>
# Dan Mosedale <dmose@mozilla.org>
use diagnostics; use diagnostics;
use strict; use strict;
...@@ -39,8 +40,26 @@ PutHeader ("Bug processed"); ...@@ -39,8 +40,26 @@ PutHeader ("Bug processed");
GetVersionTable(); GetVersionTable();
if ( Param("strictvaluechecks") ) {
CheckFormFieldDefined(\%::FORM, 'product');
CheckFormFieldDefined(\%::FORM, 'version');
CheckFormFieldDefined(\%::FORM, 'component');
}
if ($::FORM{'product'} ne $::dontchange) { if ($::FORM{'product'} ne $::dontchange) {
if ( Param("strictvaluechecks") ) {
CheckFormField(\%::FORM, 'product', \@::legal_product);
}
my $prod = $::FORM{'product'}; my $prod = $::FORM{'product'};
# note that when this script is called from buglist.cgi (rather
# than show_bug.cgi), it's possible that the product will be changed
# but that the version and/or component will be set to
# "--dont_change--" but still happen to be correct. in this case,
# the if statement will incorrectly trigger anyway. this is a
# pretty weird case, and not terribly unreasonable behavior, but
# worthy of a comment, perhaps.
#
my $vok = lsearch($::versions{$prod}, $::FORM{'version'}) >= 0; my $vok = lsearch($::versions{$prod}, $::FORM{'version'}) >= 0;
my $cok = lsearch($::components{$prod}, $::FORM{'component'}) >= 0; my $cok = lsearch($::components{$prod}, $::FORM{'component'}) >= 0;
if (!$vok || !$cok) { if (!$vok || !$cok) {
...@@ -79,10 +98,36 @@ if ($::FORM{'product'} ne $::dontchange) { ...@@ -79,10 +98,36 @@ if ($::FORM{'product'} ne $::dontchange) {
my @idlist; my @idlist;
if (defined $::FORM{'id'}) { if (defined $::FORM{'id'}) {
# since this means that we were called from show_bug.cgi, now is a good
# time to do a whole bunch of error checking that can't easily happen when
# we've been called from buglist.cgi, because buglist.cgi only tweaks
# values that have been changed instead of submitting all the new values.
# (XXX those error checks need to happen too, but implementing them
# is more work in the current architecture of this script...)
#
if ( Param('strictvaluechecks') ) {
CheckFormField(\%::FORM, 'rep_platform', \@::legal_platform);
CheckFormField(\%::FORM, 'priority', \@::legal_priority);
CheckFormField(\%::FORM, 'bug_severity', \@::legal_severity);
CheckFormField(\%::FORM, 'component',
\@{$::components{$::FORM{'product'}}});
CheckFormFieldDefined(\%::FORM, 'bug_file_loc');
CheckFormFieldDefined(\%::FORM, 'short_desc');
CheckFormField(\%::FORM, 'product', \@::legal_product);
CheckFormField(\%::FORM, 'version',
\@{$::versions{$::FORM{'product'}}});
CheckFormField(\%::FORM, 'op_sys', \@::legal_opsys);
CheckFormFieldDefined(\%::FORM, 'longdesclength');
CheckPosInt($::FORM{'id'});
}
push @idlist, $::FORM{'id'}; push @idlist, $::FORM{'id'};
} else { } else {
foreach my $i (keys %::FORM) { foreach my $i (keys %::FORM) {
if ($i =~ /^id_/) { if ($i =~ /^id_/) {
if ( Param('strictvaluechecks') ) {
CheckPosInt(substr($i, 3));
}
push @idlist, substr($i, 3); push @idlist, substr($i, 3);
} }
} }
...@@ -92,6 +137,8 @@ if (!defined $::FORM{'who'}) { ...@@ -92,6 +137,8 @@ if (!defined $::FORM{'who'}) {
$::FORM{'who'} = $::COOKIE{'Bugzilla_login'}; $::FORM{'who'} = $::COOKIE{'Bugzilla_login'};
} }
# the common updates to all bugs in @idlist start here
#
print "<TITLE>Update Bug " . join(" ", @idlist) . "</TITLE>\n"; print "<TITLE>Update Bug " . join(" ", @idlist) . "</TITLE>\n";
if (defined $::FORM{'id'}) { if (defined $::FORM{'id'}) {
navigation_header(); navigation_header();
...@@ -138,10 +185,9 @@ foreach my $b (grep(/^bit-\d*$/, keys %::FORM)) { ...@@ -138,10 +185,9 @@ foreach my $b (grep(/^bit-\d*$/, keys %::FORM)) {
} }
} }
foreach my $field ("rep_platform", "priority", "bug_severity",
foreach my $field ("rep_platform", "priority", "bug_severity", "url",
"summary", "component", "bug_file_loc", "short_desc", "summary", "component", "bug_file_loc", "short_desc",
"product", "version", "component", "op_sys", "product", "version", "op_sys",
"target_milestone", "status_whiteboard") { "target_milestone", "status_whiteboard") {
if (defined $::FORM{$field}) { if (defined $::FORM{$field}) {
if ($::FORM{$field} ne $::dontchange) { if ($::FORM{$field} ne $::dontchange) {
...@@ -167,6 +213,9 @@ if (defined $::FORM{'qa_contact'}) { ...@@ -167,6 +213,9 @@ if (defined $::FORM{'qa_contact'}) {
ConnectToDatabase(); ConnectToDatabase();
if ( Param('strictvaluechecks') ) {
CheckFormFieldDefined(\%::FORM, 'knob');
}
SWITCH: for ($::FORM{'knob'}) { SWITCH: for ($::FORM{'knob'}) {
/^none$/ && do { /^none$/ && do {
last SWITCH; last SWITCH;
...@@ -187,6 +236,14 @@ SWITCH: for ($::FORM{'knob'}) { ...@@ -187,6 +236,14 @@ SWITCH: for ($::FORM{'knob'}) {
/^reassign$/ && do { /^reassign$/ && do {
ChangeStatus('NEW'); ChangeStatus('NEW');
DoComma(); DoComma();
if ( Param("strictvaluechecks") ) {
if ( !defined$::FORM{'assigned_to'} ||
trim($::FORM{'assigned_to'}) eq "") {
print "You cannot reassign to a bug to noone. Unless you intentionally cleared out the \"Reassign bug to\" field, ";
print Param("browserbugmessage");
exit 0;
}
}
my $newid = DBNameToIdAndCheck($::FORM{'assigned_to'}); my $newid = DBNameToIdAndCheck($::FORM{'assigned_to'});
$::query .= "assigned_to = $newid"; $::query .= "assigned_to = $newid";
last SWITCH; last SWITCH;
...@@ -222,18 +279,24 @@ SWITCH: for ($::FORM{'knob'}) { ...@@ -222,18 +279,24 @@ SWITCH: for ($::FORM{'knob'}) {
/^duplicate$/ && do { /^duplicate$/ && do {
ChangeStatus('RESOLVED'); ChangeStatus('RESOLVED');
ChangeResolution('DUPLICATE'); ChangeResolution('DUPLICATE');
if ( Param('strictvaluechecks') ) {
CheckFormFieldDefined(\%::FORM,'dup_id');
}
my $num = trim($::FORM{'dup_id'}); my $num = trim($::FORM{'dup_id'});
if ($num !~ /^[0-9]*$/) { if ($num !~ /^[0-9]*$/) {
print "You must specify a bug number of which this bug is a\n"; print "You must specify a bug number of which this bug is a\n";
print "duplicate. The bug has not been changed.\n"; print "duplicate. The bug has not been changed.\n";
exit; exit;
} }
if ($::FORM{'dup_id'} == $::FORM{'id'}) { if (defined($::FORM{'id'}) && $::FORM{'dup_id'} == $::FORM{'id'}) {
print "Nice try, $::FORM{'who'}. But it doesn't really make sense to mark a\n"; print "Nice try, $::FORM{'who'}. But it doesn't really make sense to mark a\n";
print "bug as a duplicate of itself, does it?\n"; print "bug as a duplicate of itself, does it?\n";
exit; exit;
} }
AppendComment($::FORM{'dup_id'}, $::FORM{'who'}, "*** Bug $::FORM{'id'} has been marked as a duplicate of this bug. ***"); AppendComment($::FORM{'dup_id'}, $::FORM{'who'}, "*** Bug $::FORM{'id'} has been marked as a duplicate of this bug. ***");
if ( Param('strictvaluechecks') ) {
CheckFormFieldDefined(\%::FORM,'comment');
}
$::FORM{'comment'} .= "\n\n*** This bug has been marked as a duplicate of $::FORM{'dup_id'} ***"; $::FORM{'comment'} .= "\n\n*** This bug has been marked as a duplicate of $::FORM{'dup_id'} ***";
print "<TABLE BORDER=1><TD><H2>Notation added to bug $::FORM{'dup_id'}</H2>\n"; print "<TABLE BORDER=1><TD><H2>Notation added to bug $::FORM{'dup_id'}</H2>\n";
...@@ -301,7 +364,10 @@ sub LogDependencyActivity { ...@@ -301,7 +364,10 @@ sub LogDependencyActivity {
return 0; return 0;
} }
# this loop iterates once for each bug to be processed (eg when this script
# is called by with multiple bugs selected from buglist.cgi instead of
# show_bug.cgi).
#
foreach my $id (@idlist) { foreach my $id (@idlist) {
my %dependencychanged; my %dependencychanged;
SendSQL("lock tables bugs write, bugs_activity write, cc write, profiles write, dependencies write, votes write"); SendSQL("lock tables bugs write, bugs_activity write, cc write, profiles write, dependencies write, votes write");
...@@ -317,6 +383,7 @@ The changes made were: ...@@ -317,6 +383,7 @@ The changes made were:
DumpBugActivity($id, $delta_ts); DumpBugActivity($id, $delta_ts);
my $longdesc = GetLongDescription($id); my $longdesc = GetLongDescription($id);
my $longchanged = 0; my $longchanged = 0;
if (length($longdesc) > $::FORM{'longdesclength'}) { if (length($longdesc) > $::FORM{'longdesclength'}) {
$longchanged = 1; $longchanged = 1;
print "<P>Added text to the long description:<blockquote><pre>"; print "<P>Added text to the long description:<blockquote><pre>";
...@@ -476,6 +543,10 @@ The changes made were: ...@@ -476,6 +543,10 @@ The changes made were:
} }
# get a snapshot of the newly set values out of the database,
# and then generate any necessary bug activity entries by seeing
# what has changed since before we wrote out the new values.
#
my @newvalues = SnapShotBug($id); my @newvalues = SnapShotBug($id);
foreach my $col (@::log_columns) { foreach my $col (@::log_columns) {
my $old = shift @oldvalues; my $old = shift @oldvalues;
......
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