Commit 8a3523f9 authored by lpsolit%gmail.com's avatar lpsolit%gmail.com

Bug 303688: Eliminate deprecated Bugzilla::DB routines from attachment.cgi -…

Bug 303688: Eliminate deprecated Bugzilla::DB routines from attachment.cgi - Patch by Greg Hendricks <ghendricks@novell.com> r=LpSolit a=justdave
parent a3cf3b1a
...@@ -53,7 +53,6 @@ use Bugzilla::Attachment; ...@@ -53,7 +53,6 @@ use Bugzilla::Attachment;
Bugzilla->login(); Bugzilla->login();
my $cgi = Bugzilla->cgi; my $cgi = Bugzilla->cgi;
my $dbh = Bugzilla->dbh;
my $template = Bugzilla->template; my $template = Bugzilla->template;
my $vars = {}; my $vars = {};
...@@ -130,7 +129,8 @@ exit; ...@@ -130,7 +129,8 @@ exit;
sub validateID sub validateID
{ {
my $param = @_ ? $_[0] : 'id'; my $param = @_ ? $_[0] : 'id';
my $dbh = Bugzilla->dbh;
# If we're not doing interdiffs, check if id wasn't specified and # If we're not doing interdiffs, check if id wasn't specified and
# prompt them with a page that allows them to choose an attachment. # prompt them with a page that allows them to choose an attachment.
# Happens when calling plain attachment.cgi from the urlbar directly # Happens when calling plain attachment.cgi from the urlbar directly
...@@ -151,12 +151,15 @@ sub validateID ...@@ -151,12 +151,15 @@ sub validateID
|| ThrowUserError("invalid_attach_id", { attach_id => $cgi->param($param) }); || ThrowUserError("invalid_attach_id", { attach_id => $cgi->param($param) });
# Make sure the attachment exists in the database. # Make sure the attachment exists in the database.
SendSQL("SELECT bug_id, isprivate FROM attachments WHERE attach_id = $attach_id"); my ($bugid, $isprivate) = $dbh->selectrow_array(
MoreSQLData() "SELECT bug_id, isprivate
|| ThrowUserError("invalid_attach_id", { attach_id => $attach_id }); FROM attachments
WHERE attach_id = ?",
undef, $attach_id);
ThrowUserError("invalid_attach_id", { attach_id => $attach_id })
unless $bugid;
# Make sure the user is authorized to access this attachment's bug. # Make sure the user is authorized to access this attachment's bug.
(my $bugid, my $isprivate) = FetchSQLData();
ValidateBugID($bugid); ValidateBugID($bugid);
if ($isprivate && Param("insidergroup")) { if ($isprivate && Param("insidergroup")) {
...@@ -199,28 +202,32 @@ sub validateContext ...@@ -199,28 +202,32 @@ sub validateContext
sub validateCanEdit sub validateCanEdit
{ {
my ($attach_id) = (@_); my ($attach_id) = (@_);
my $dbh = Bugzilla->dbh;
# People in editbugs can edit all attachments # People in editbugs can edit all attachments
return if UserInGroup("editbugs"); return if UserInGroup("editbugs");
# Bug 97729 - the submitter can edit their attachments # Bug 97729 - the submitter can edit their attachments
SendSQL("SELECT attach_id FROM attachments WHERE " . my ($ref) = $dbh->selectrow_array("SELECT attach_id FROM attachments
"attach_id = $attach_id AND submitter_id = " . Bugzilla->user->id); WHERE attach_id = ?
AND submitter_id = ?",
undef, ($attach_id, Bugzilla->user->id));
FetchSQLData()
|| ThrowUserError("illegal_attachment_edit", $ref || ThrowUserError("illegal_attachment_edit",{ attach_id => $attach_id });
{ attach_id => $attach_id });
} }
sub validateCanChangeAttachment sub validateCanChangeAttachment
{ {
my ($attachid) = @_; my ($attachid) = @_;
SendSQL("SELECT product_id my $dbh = Bugzilla->dbh;
my ($productid) = $dbh->selectrow_array(
"SELECT product_id
FROM attachments FROM attachments
INNER JOIN bugs INNER JOIN bugs
ON bugs.bug_id = attachments.bug_id ON bugs.bug_id = attachments.bug_id
WHERE attach_id = $attachid"); WHERE attach_id = ?", undef, $attachid);
my $productid = FetchOneColumn();
Bugzilla->user->can_edit_product($productid) Bugzilla->user->can_edit_product($productid)
|| ThrowUserError("illegal_attachment_edit", || ThrowUserError("illegal_attachment_edit",
{ attach_id => $attachid }); { attach_id => $attachid });
...@@ -229,10 +236,12 @@ sub validateCanChangeAttachment ...@@ -229,10 +236,12 @@ sub validateCanChangeAttachment
sub validateCanChangeBug sub validateCanChangeBug
{ {
my ($bugid) = @_; my ($bugid) = @_;
SendSQL("SELECT product_id my $dbh = Bugzilla->dbh;
my ($productid) = $dbh->selectrow_array(
"SELECT product_id
FROM bugs FROM bugs
WHERE bug_id = $bugid"); WHERE bug_id = ?", undef, $bugid);
my $productid = FetchOneColumn();
Bugzilla->user->can_edit_product($productid) Bugzilla->user->can_edit_product($productid)
|| ThrowUserError("illegal_attachment_edit_bug", || ThrowUserError("illegal_attachment_edit_bug",
{ bug_id => $bugid }); { bug_id => $bugid });
...@@ -391,7 +400,8 @@ sub validateFilename ...@@ -391,7 +400,8 @@ sub validateFilename
sub validateObsolete sub validateObsolete
{ {
my @obsolete_ids = (); my @obsolete_ids = ();
my $dbh = Bugzilla->dbh;
# Make sure the attachment id is valid and the user has permissions to view # Make sure the attachment id is valid and the user has permissions to view
# the bug to which it is attached. # the bug to which it is attached.
foreach my $attachid ($cgi->param('obsolete')) { foreach my $attachid ($cgi->param('obsolete')) {
...@@ -401,14 +411,14 @@ sub validateObsolete ...@@ -401,14 +411,14 @@ sub validateObsolete
detaint_natural($attachid) detaint_natural($attachid)
|| ThrowCodeError("invalid_attach_id_to_obsolete", $vars); || ThrowCodeError("invalid_attach_id_to_obsolete", $vars);
SendSQL("SELECT bug_id, isobsolete, description my ($bugid, $isobsolete, $description) = $dbh->selectrow_array(
FROM attachments WHERE attach_id = $attachid"); "SELECT bug_id, isobsolete, description
FROM attachments WHERE attach_id = ?", undef, $attachid);
# Make sure the attachment exists in the database. # Make sure the attachment exists in the database.
MoreSQLData() ThrowUserError("invalid_attach_id", $vars) unless $bugid;
|| ThrowUserError("invalid_attach_id", $vars);
my ($bugid, $isobsolete, $description) = FetchSQLData();
$vars->{'description'} = $description; $vars->{'description'} = $description;
...@@ -473,12 +483,13 @@ sub view ...@@ -473,12 +483,13 @@ sub view
{ {
# Retrieve and validate parameters # Retrieve and validate parameters
my ($attach_id) = validateID(); my ($attach_id) = validateID();
my $dbh = Bugzilla->dbh;
# Retrieve the attachment content and its content type from the database. # Retrieve the attachment content and its content type from the database.
SendSQL("SELECT mimetype, filename, thedata FROM attachments " . my ($contenttype, $filename, $thedata) = $dbh->selectrow_array(
"SELECT mimetype, filename, thedata FROM attachments " .
"INNER JOIN attach_data ON id = attach_id " . "INNER JOIN attach_data ON id = attach_id " .
"WHERE attach_id = $attach_id"); "WHERE attach_id = ?", undef, $attach_id);
my ($contenttype, $filename, $thedata) = FetchSQLData();
# Bug 111522: allow overriding content-type manually in the posted form # Bug 111522: allow overriding content-type manually in the posted form
# params. # params.
...@@ -591,7 +602,8 @@ sub interdiff ...@@ -591,7 +602,8 @@ sub interdiff
sub get_unified_diff sub get_unified_diff
{ {
my ($id) = @_; my ($id) = @_;
my $dbh = Bugzilla->dbh;
# Bring in the modules we need # Bring in the modules we need
require PatchReader::Raw; require PatchReader::Raw;
require PatchReader::FixPatchRoot; require PatchReader::FixPatchRoot;
...@@ -600,12 +612,12 @@ sub get_unified_diff ...@@ -600,12 +612,12 @@ sub get_unified_diff
require File::Temp; require File::Temp;
# Get the patch # Get the patch
SendSQL("SELECT bug_id, description, ispatch, thedata " . my ($bugid, $description, $ispatch, $thedata) = $dbh->selectrow_array(
"SELECT bug_id, description, ispatch, thedata " .
"FROM attachments " . "FROM attachments " .
"INNER JOIN attach_data " . "INNER JOIN attach_data " .
"ON id = attach_id " . "ON id = attach_id " .
"WHERE attach_id = $id"); "WHERE attach_id = ?", undef, $id);
my ($bugid, $description, $ispatch, $thedata) = FetchSQLData();
if (!$ispatch) { if (!$ispatch) {
$vars->{'attach_id'} = $id; $vars->{'attach_id'} = $id;
ThrowCodeError("must_be_patch"); ThrowCodeError("must_be_patch");
...@@ -732,12 +744,13 @@ sub diff ...@@ -732,12 +744,13 @@ sub diff
my ($attach_id) = validateID(); my ($attach_id) = validateID();
my $format = validateFormat('html', 'raw'); my $format = validateFormat('html', 'raw');
my $context = validateContext(); my $context = validateContext();
my $dbh = Bugzilla->dbh;
# Get patch data # Get patch data
SendSQL("SELECT bug_id, description, ispatch, thedata FROM attachments " . my ($bugid, $description, $ispatch, $thedata) = $dbh->selectrow_array(
"SELECT bug_id, description, ispatch, thedata FROM attachments " .
"INNER JOIN attach_data ON id = attach_id " . "INNER JOIN attach_data ON id = attach_id " .
"WHERE attach_id = $attach_id"); "WHERE attach_id = ?", undef, $attach_id);
my ($bugid, $description, $ispatch, $thedata) = FetchSQLData();
# If it is not a patch, view normally # If it is not a patch, view normally
if (!$ispatch) if (!$ispatch)
...@@ -764,9 +777,14 @@ sub diff ...@@ -764,9 +777,14 @@ sub diff
# Get list of attachments on this bug. # Get list of attachments on this bug.
# Ignore the current patch, but select the one right before it # Ignore the current patch, but select the one right before it
# chronologically. # chronologically.
SendSQL("SELECT attach_id, description FROM attachments WHERE bug_id = $bugid AND ispatch = 1 ORDER BY creation_ts DESC"); my $sth = $dbh->prepare("SELECT attach_id, description
FROM attachments
WHERE bug_id = ?
AND ispatch = 1
ORDER BY creation_ts DESC");
$sth->execute($bugid);
my $select_next_patch = 0; my $select_next_patch = 0;
while (my ($other_id, $other_desc) = FetchSQLData()) { while (my ($other_id, $other_desc) = $sth->fetchrow_array) {
if ($other_id eq $attach_id) { if ($other_id eq $attach_id) {
$select_next_patch = 1; $select_next_patch = 1;
} else { } else {
...@@ -803,38 +821,33 @@ sub viewall ...@@ -803,38 +821,33 @@ sub viewall
if (Param("insidergroup") && !(UserInGroup(Param("insidergroup")))) { if (Param("insidergroup") && !(UserInGroup(Param("insidergroup")))) {
$privacy = "AND isprivate < 1 "; $privacy = "AND isprivate < 1 ";
} }
SendSQL("SELECT attach_id, " . my $attachments = $dbh->selectall_arrayref(
$dbh->sql_date_format('creation_ts', '%Y.%m.%d %H:%i') . ", "SELECT attach_id AS attachid, " .
mimetype, description, ispatch, isobsolete, isprivate, $dbh->sql_date_format('creation_ts', '%Y.%m.%d %H:%i') . " AS date,
LENGTH(thedata) mimetype AS contenttype, description, ispatch, isobsolete, isprivate,
LENGTH(thedata) AS datasize
FROM attachments FROM attachments
INNER JOIN attach_data INNER JOIN attach_data
ON attach_id = id ON attach_id = id
WHERE bug_id = $bugid $privacy WHERE bug_id = ? $privacy
ORDER BY attach_id"); ORDER BY attach_id", {'Slice'=>{}}, $bugid);
my @attachments; # the attachments array
while (MoreSQLData()) foreach my $a (@{$attachments})
{ {
my %a; # the attachment hash
($a{'attachid'}, $a{'date'}, $a{'contenttype'}, $a->{'isviewable'} = isViewable($a->{'contenttype'});
$a{'description'}, $a{'ispatch'}, $a{'isobsolete'}, $a{'isprivate'}, $a->{'flags'} = Bugzilla::Flag::match({ 'attach_id' => $a->{'attachid'},
$a{'datasize'}) = FetchSQLData();
$a{'isviewable'} = isViewable($a{'contenttype'});
$a{'flags'} = Bugzilla::Flag::match({ 'attach_id' => $a{'attachid'},
'is_active' => 1 }); 'is_active' => 1 });
# Add the hash representing the attachment to the array of attachments.
push @attachments, \%a;
} }
# Retrieve the bug summary (for displaying on screen) and assignee. # Retrieve the bug summary (for displaying on screen) and assignee.
SendSQL("SELECT short_desc, assigned_to FROM bugs " . my ($bugsummary, $assignee_id) = $dbh->selectrow_array(
"WHERE bug_id = $bugid"); "SELECT short_desc, assigned_to FROM bugs " .
my ($bugsummary, $assignee_id) = FetchSQLData(); "WHERE bug_id = ?", undef, $bugid);
# Define the variables and functions that will be passed to the UI template. # Define the variables and functions that will be passed to the UI template.
$vars->{'bugid'} = $bugid; $vars->{'bugid'} = $bugid;
$vars->{'attachments'} = \@attachments; $vars->{'attachments'} = $attachments;
$vars->{'bugassignee_id'} = $assignee_id; $vars->{'bugassignee_id'} = $assignee_id;
$vars->{'bugsummary'} = $bugsummary; $vars->{'bugsummary'} = $bugsummary;
...@@ -852,41 +865,36 @@ sub enter ...@@ -852,41 +865,36 @@ sub enter
my $bugid = $cgi->param('bugid'); my $bugid = $cgi->param('bugid');
ValidateBugID($bugid); ValidateBugID($bugid);
validateCanChangeBug($bugid); validateCanChangeBug($bugid);
my $dbh = Bugzilla->dbh;
# Retrieve the attachments the user can edit from the database and write # Retrieve the attachments the user can edit from the database and write
# them into an array of hashes where each hash represents one attachment. # them into an array of hashes where each hash represents one attachment.
my $canEdit = ""; my $canEdit = "";
if (!UserInGroup("editbugs")) { if (!UserInGroup("editbugs")) {
$canEdit = "AND submitter_id = " . Bugzilla->user->id; $canEdit = "AND submitter_id = " . Bugzilla->user->id;
} }
SendSQL("SELECT attach_id, description, isprivate my $attachments = $dbh->selectall_arrayref(
"SELECT attach_id AS id, description, isprivate
FROM attachments FROM attachments
WHERE bug_id = $bugid WHERE bug_id = ?
AND isobsolete = 0 $canEdit AND isobsolete = 0 $canEdit
ORDER BY attach_id"); ORDER BY attach_id",{'Slice' =>{}}, $bugid);
my @attachments; # the attachments array
while ( MoreSQLData() ) {
my %a; # the attachment hash
($a{'id'}, $a{'description'}, $a{'isprivate'}) = FetchSQLData();
# Add the hash representing the attachment to the array of attachments.
push @attachments, \%a;
}
# Retrieve the bug summary (for displaying on screen) and assignee. # Retrieve the bug summary (for displaying on screen) and assignee.
SendSQL("SELECT short_desc, assigned_to FROM bugs my ($bugsummary, $assignee_id) = $dbh->selectrow_array(
WHERE bug_id = $bugid"); "SELECT short_desc, assigned_to FROM bugs
my ($bugsummary, $assignee_id) = FetchSQLData(); WHERE bug_id = ?", undef, $bugid);
# Define the variables and functions that will be passed to the UI template. # Define the variables and functions that will be passed to the UI template.
$vars->{'bugid'} = $bugid; $vars->{'bugid'} = $bugid;
$vars->{'attachments'} = \@attachments; $vars->{'attachments'} = $attachments;
$vars->{'bugassignee_id'} = $assignee_id; $vars->{'bugassignee_id'} = $assignee_id;
$vars->{'bugsummary'} = $bugsummary; $vars->{'bugsummary'} = $bugsummary;
SendSQL("SELECT product_id, component_id FROM bugs my ($product_id, $component_id)= $dbh->selectrow_array(
WHERE bug_id = $bugid"); "SELECT product_id, component_id FROM bugs
my ($product_id, $component_id) = FetchSQLData(); WHERE bug_id = ?", undef, $bugid);
my $flag_types = Bugzilla::FlagType::match({'target_type' => 'attachment', my $flag_types = Bugzilla::FlagType::match({'target_type' => 'attachment',
'product_id' => $product_id, 'product_id' => $product_id,
'component_id' => $component_id}); 'component_id' => $component_id});
...@@ -904,7 +912,6 @@ sub enter ...@@ -904,7 +912,6 @@ sub enter
# Insert a new attachment into the database. # Insert a new attachment into the database.
sub insert sub insert
{ {
my $dbh = Bugzilla->dbh;
my $userid = Bugzilla->user->id; my $userid = Bugzilla->user->id;
# Retrieve and validate parameters # Retrieve and validate parameters
...@@ -919,13 +926,14 @@ sub insert ...@@ -919,13 +926,14 @@ sub insert
my $isurl; my $isurl;
validateIsPatch(); validateIsPatch();
validateDescription(); validateDescription();
my $dbh = Bugzilla->dbh;
if (($attachurl =~ /^(http|https|ftp):\/\/\S+/) if (($attachurl =~ /^(http|https|ftp):\/\/\S+/)
&& !(defined $cgi->upload('data'))) { && !(defined $cgi->upload('data'))) {
$filename = ''; $filename = '';
$data = $attachurl; $data = $attachurl;
$isurl = 1; $isurl = 1;
$contenttype = SqlQuote('text/plain'); $contenttype = 'text/plain';
$cgi->param('ispatch', 0); $cgi->param('ispatch', 0);
$cgi->delete('bigfile'); $cgi->delete('bigfile');
} else { } else {
...@@ -934,7 +942,11 @@ sub insert ...@@ -934,7 +942,11 @@ sub insert
# we now check the content type for image/bmp in validateData() # we now check the content type for image/bmp in validateData()
validateContentType() unless $cgi->param('ispatch'); validateContentType() unless $cgi->param('ispatch');
$data = validateData(); $data = validateData();
$contenttype = SqlQuote($cgi->param('contenttype')); $contenttype = $cgi->param('contenttype');
# These are inserted using placeholders so no need to panic
trick_taint($filename);
trick_taint($contenttype);
$isurl = 0; $isurl = 0;
} }
...@@ -963,22 +975,21 @@ sub insert ...@@ -963,22 +975,21 @@ sub insert
Bugzilla::FlagType::validate($cgi, $bugid, -1); Bugzilla::FlagType::validate($cgi, $bugid, -1);
# Escape characters in strings that will be used in SQL statements. # Escape characters in strings that will be used in SQL statements.
my $sql_filename = SqlQuote($filename); my $description = $cgi->param('description');
my $description = SqlQuote($cgi->param('description')); trick_taint($description);
my $isprivate = $cgi->param('isprivate') ? 1 : 0; my $isprivate = $cgi->param('isprivate') ? 1 : 0;
# Figure out when the changes were made. # Figure out when the changes were made.
my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()"); my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()");
my $sql_timestamp = SqlQuote($timestamp);
# Insert the attachment into the database. # Insert the attachment into the database.
my $sth = $dbh->prepare("INSERT INTO attachments my $sth = $dbh->do(
(bug_id, creation_ts, filename, description, "INSERT INTO attachments
mimetype, ispatch, isurl, isprivate, submitter_id) (bug_id, creation_ts, filename, description,
VALUES ($bugid, $sql_timestamp, $sql_filename, mimetype, ispatch, isurl, isprivate, submitter_id)
$description, $contenttype, " . $cgi->param('ispatch') . ", VALUES (?,?,?,?,?,?,?,?,?)", undef, ($bugid, $timestamp, $filename,
$isurl, $isprivate, $userid)"); $description, $contenttype, $cgi->param('ispatch'),
$sth->execute(); $isurl, $isprivate, $userid));
# Retrieve the ID of the newly created attachment record. # Retrieve the ID of the newly created attachment record.
my $attachid = $dbh->bz_last_key('attachments', 'attach_id'); my $attachid = $dbh->bz_last_key('attachments', 'attach_id');
...@@ -1031,14 +1042,14 @@ sub insert ...@@ -1031,14 +1042,14 @@ sub insert
foreach my $obsolete_id (@obsolete_ids) { foreach my $obsolete_id (@obsolete_ids) {
# If the obsolete attachment has request flags, cancel them. # If the obsolete attachment has request flags, cancel them.
# This call must be done before updating the 'attachments' table. # This call must be done before updating the 'attachments' table.
Bugzilla::Flag::CancelRequests($bugid, $obsolete_id, $sql_timestamp); Bugzilla::Flag::CancelRequests($bugid, $obsolete_id, $dbh->quote($timestamp));
SendSQL("UPDATE attachments SET isobsolete = 1 " . $dbh->do("UPDATE attachments SET isobsolete = 1 " .
"WHERE attach_id = $obsolete_id"); "WHERE attach_id = ?", undef, $obsolete_id);
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
fieldid, removed, added) fieldid, removed, added)
VALUES ($bugid, $obsolete_id, $userid, $sql_timestamp, $fieldid, VALUES (?,?,?,?,?,?,?)", undef,
'0', '1')"); $bugid, $obsolete_id, $userid, $timestamp, $fieldid, 0, 1);
} }
# Assign the bug to the user, if they are allowed to take it # Assign the bug to the user, if they are allowed to take it
...@@ -1050,26 +1061,26 @@ sub insert ...@@ -1050,26 +1061,26 @@ sub insert
"login_name"); "login_name");
# Get the old values, for the bugs_activity table # Get the old values, for the bugs_activity table
SendSQL("SELECT " . join(", ", @fields) . " " . my @oldvalues = $dbh->selectrow_array(
"SELECT " . join(", ", @fields) . " " .
"FROM bugs " . "FROM bugs " .
"INNER JOIN profiles " . "INNER JOIN profiles " .
"ON profiles.userid = bugs.assigned_to " . "ON profiles.userid = bugs.assigned_to " .
"WHERE bugs.bug_id = $bugid"); "WHERE bugs.bug_id = ?", undef, $bugid);
my @oldvalues = FetchSQLData();
my @newvalues = ($userid, "ASSIGNED", "", 1, Bugzilla->user->login); my @newvalues = ($userid, "ASSIGNED", "", 1, Bugzilla->user->login);
# Make sure the person we are taking the bug from gets mail. # Make sure the person we are taking the bug from gets mail.
$owner = $oldvalues[4]; $owner = $oldvalues[4];
@oldvalues = map(SqlQuote($_), @oldvalues); @oldvalues = map($dbh->quote($_), @oldvalues);
@newvalues = map(SqlQuote($_), @newvalues); @newvalues = map($dbh->quote($_), @newvalues);
# Update the bug record. Note that this doesn't involve login_name. # Update the bug record. Note that this doesn't involve login_name.
SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp, " . $dbh->do("UPDATE bugs SET delta_ts = ?, " .
join(", ", map("$fields[$_] = $newvalues[$_]", (0..3))) . join(", ", map("$fields[$_] = $newvalues[$_]", (0..3))) .
" WHERE bug_id = $bugid"); " WHERE bug_id = ?", undef, ($timestamp, $bugid));
# If the bug was a dupe, we have to remove its entry from the # If the bug was a dupe, we have to remove its entry from the
# 'duplicates' table. # 'duplicates' table.
$dbh->do('DELETE FROM duplicates WHERE dupe = ?', undef, $bugid); $dbh->do('DELETE FROM duplicates WHERE dupe = ?', undef, $bugid);
...@@ -1079,13 +1090,15 @@ sub insert ...@@ -1079,13 +1090,15 @@ sub insert
$newvalues[0] = $newvalues[4]; $newvalues[0] = $newvalues[4];
# Add the changes to the bugs_activity table # Add the changes to the bugs_activity table
my $sth = $dbh->prepare("INSERT INTO bugs_activity
(bug_id, who, bug_when, fieldid, removed, added)
VALUES (?,?,?,?,?,?)");
for (my $i = 0; $i < 4; $i++) { for (my $i = 0; $i < 4; $i++) {
if ($oldvalues[$i] ne $newvalues[$i]) { if ($oldvalues[$i] ne $newvalues[$i]) {
my $fieldid = get_field_id($fields[$i]); my $fieldid = get_field_id($fields[$i]);
SendSQL("INSERT INTO bugs_activity " . $sth->execute($bugid, $userid, $timestamp,
"(bug_id, who, bug_when, fieldid, removed, added) " . $fieldid, $oldvalues[$i], $newvalues[$i]);
"VALUES ($bugid, $userid, $sql_timestamp, " .
"$fieldid, $oldvalues[$i], $newvalues[$i])");
} }
} }
} }
...@@ -1167,7 +1180,6 @@ sub edit { ...@@ -1167,7 +1180,6 @@ sub edit {
# Users cannot edit the content of the attachment itself. # Users cannot edit the content of the attachment itself.
sub update sub update
{ {
my $dbh = Bugzilla->dbh;
my $userid = Bugzilla->user->id; my $userid = Bugzilla->user->id;
# Retrieve and validate parameters # Retrieve and validate parameters
...@@ -1180,6 +1192,7 @@ sub update ...@@ -1180,6 +1192,7 @@ sub update
validateContentType() unless $cgi->param('ispatch'); validateContentType() unless $cgi->param('ispatch');
validateIsObsolete(); validateIsObsolete();
validatePrivate(); validatePrivate();
my $dbh = Bugzilla->dbh;
# The order of these function calls is important, as both Flag::validate # The order of these function calls is important, as both Flag::validate
# and FlagType::validate assume User::match_field has ensured that the # and FlagType::validate assume User::match_field has ensured that the
...@@ -1205,19 +1218,22 @@ sub update ...@@ -1205,19 +1218,22 @@ sub update
# Get a copy of the attachment record before we make changes # Get a copy of the attachment record before we make changes
# so we can record those changes in the activity table. # so we can record those changes in the activity table.
SendSQL("SELECT description, mimetype, filename, ispatch, isobsolete, isprivate
FROM attachments WHERE attach_id = $attach_id");
my ($olddescription, $oldcontenttype, $oldfilename, $oldispatch, my ($olddescription, $oldcontenttype, $oldfilename, $oldispatch,
$oldisobsolete, $oldisprivate) = FetchSQLData(); $oldisobsolete, $oldisprivate) = $dbh->selectrow_array(
"SELECT description, mimetype, filename, ispatch, isobsolete, isprivate
FROM attachments WHERE attach_id = ?", undef, $attach_id);
# Quote the description and content type for use in the SQL UPDATE statement. # Quote the description and content type for use in the SQL UPDATE statement.
my $quoteddescription = SqlQuote($cgi->param('description')); my $description = $cgi->param('description');
my $quotedcontenttype = SqlQuote($cgi->param('contenttype')); my $contenttype = $cgi->param('contenttype');
my $quotedfilename = SqlQuote($cgi->param('filename')); my $filename = $cgi->param('filename');
# we can detaint this way thanks to placeholders
trick_taint($description);
trick_taint($contenttype);
trick_taint($filename);
# Figure out when the changes were made. # Figure out when the changes were made.
SendSQL("SELECT NOW()"); my ($timestamp) = $dbh->selectrow_array("SELECT NOW()");
my $timestamp = FetchOneColumn();
# Update flags. We have to do this before committing changes # Update flags. We have to do this before committing changes
# to attachments so that we can delete pending requests if the user # to attachments so that we can delete pending requests if the user
...@@ -1226,62 +1242,66 @@ sub update ...@@ -1226,62 +1242,66 @@ sub update
Bugzilla::Flag::process($bugid, $attach_id, $timestamp, $cgi); Bugzilla::Flag::process($bugid, $attach_id, $timestamp, $cgi);
# Update the attachment record in the database. # Update the attachment record in the database.
SendSQL("UPDATE attachments $dbh->do("UPDATE attachments
SET description = $quoteddescription , SET description = ?,
mimetype = $quotedcontenttype , mimetype = ?,
filename = $quotedfilename , filename = ?,
ispatch = " . $cgi->param('ispatch') . ", ispatch = ?,
isobsolete = " . $cgi->param('isobsolete') . ", isobsolete = ?,
isprivate = " . $cgi->param('isprivate') . " isprivate = ?
WHERE attach_id = $attach_id WHERE attach_id = ?",
"); undef, ($description, $contenttype, $filename,
$cgi->param('ispatch'), $cgi->param('isobsolete'),
$cgi->param('isprivate'), $attach_id));
# Record changes in the activity table. # Record changes in the activity table.
my $sql_timestamp = SqlQuote($timestamp);
if ($olddescription ne $cgi->param('description')) { if ($olddescription ne $cgi->param('description')) {
my $quotedolddescription = SqlQuote($olddescription);
my $fieldid = get_field_id('attachments.description'); my $fieldid = get_field_id('attachments.description');
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
fieldid, removed, added) fieldid, removed, added)
VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, VALUES (?,?,?,?,?,?,?)",
$quotedolddescription, $quoteddescription)"); undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid,
$olddescription, $description));
} }
if ($oldcontenttype ne $cgi->param('contenttype')) { if ($oldcontenttype ne $cgi->param('contenttype')) {
my $quotedoldcontenttype = SqlQuote($oldcontenttype);
my $fieldid = get_field_id('attachments.mimetype'); my $fieldid = get_field_id('attachments.mimetype');
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
fieldid, removed, added) fieldid, removed, added)
VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, VALUES (?,?,?,?,?,?,?)",
$quotedoldcontenttype, $quotedcontenttype)"); undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid,
$oldcontenttype, $contenttype));
} }
if ($oldfilename ne $cgi->param('filename')) { if ($oldfilename ne $cgi->param('filename')) {
my $quotedoldfilename = SqlQuote($oldfilename);
my $fieldid = get_field_id('attachments.filename'); my $fieldid = get_field_id('attachments.filename');
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
fieldid, removed, added) fieldid, removed, added)
VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, VALUES (?,?,?,?,?,?,?)",
$quotedoldfilename, $quotedfilename)"); undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid,
$oldfilename, $filename));
} }
if ($oldispatch ne $cgi->param('ispatch')) { if ($oldispatch ne $cgi->param('ispatch')) {
my $fieldid = get_field_id('attachments.ispatch'); my $fieldid = get_field_id('attachments.ispatch');
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
fieldid, removed, added) fieldid, removed, added)
VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, VALUES (?,?,?,?,?,?,?)",
$oldispatch, " . $cgi->param('ispatch') . ")"); undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid,
$oldispatch, $cgi->param('ispatch')));
} }
if ($oldisobsolete ne $cgi->param('isobsolete')) { if ($oldisobsolete ne $cgi->param('isobsolete')) {
my $fieldid = get_field_id('attachments.isobsolete'); my $fieldid = get_field_id('attachments.isobsolete');
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
fieldid, removed, added) fieldid, removed, added)
VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, VALUES (?,?,?,?,?,?,?)",
$oldisobsolete, " . $cgi->param('isobsolete') . ")"); undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid,
$oldisobsolete, $cgi->param('isobsolete')));
} }
if ($oldisprivate ne $cgi->param('isprivate')) { if ($oldisprivate ne $cgi->param('isprivate')) {
my $fieldid = get_field_id('attachments.isprivate'); my $fieldid = get_field_id('attachments.isprivate');
SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when, $dbh->do("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
fieldid, removed, added) fieldid, removed, added)
VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid, VALUES (?,?,?,?,?,?,?)",
$oldisprivate, " . $cgi->param('isprivate') . ")"); undef, ($bugid, $attach_id, $userid, $timestamp, $fieldid,
$oldisprivate, $cgi->param('isprivate')));
} }
# Unlock all database tables now that we are finished updating the database. # Unlock all database tables now that we are finished updating the database.
......
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