#!/usr/bin/perl -wT
# -*- Mode: perl; indent-tabs-mode: nil -*-
#
# The contents of this file are subject to the Mozilla Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is the Bugzilla Bug Tracking System.
#
# The Initial Developer of the Original Code is Netscape Communications
# Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s): Terry Weissman <terry@mozilla.org>
#                 Myk Melez <myk@mozilla.org>
#                 Daniel Raichle <draichle@gmx.net>
#                 Dave Miller <justdave@syndicomm.com>
#                 Alexander J. Vincent <ajvincent@juno.com>
#                 Max Kanat-Alexander <mkanat@bugzilla.org>

################################################################################
# Script Initialization
################################################################################

# Make it harder for us to do dangerous things in Perl.
use strict;

use lib qw(.);

use vars qw(
  $template
  $vars
);

# Include the Bugzilla CGI and general utility library.
require "CGI.pl";
use Bugzilla::Config qw(:locations);

# Use these modules to handle flags.
use Bugzilla::Constants;
use Bugzilla::Flag; 
use Bugzilla::FlagType; 
use Bugzilla::User;
use Bugzilla::Util;
use Bugzilla::Bug;

use IPC::Open2;

Bugzilla->login();

my $cgi = Bugzilla->cgi;

################################################################################
# Main Body Execution
################################################################################

# All calls to this script should contain an "action" variable whose
# value determines what the user wants to do.  The code below checks
# the value of that variable and runs the appropriate code. If none is
# supplied, we default to 'view'.

# Determine whether to use the action specified by the user or the default.
my $action = $cgi->param('action') || 'view';

if ($action eq "view")  
{
    view();
}
elsif ($action eq "interdiff")
{
    interdiff();
}
elsif ($action eq "diff")
{
    diff();
}
elsif ($action eq "viewall") 
{ 
    viewall(); 
}
elsif ($action eq "enter") 
{ 
    Bugzilla->login(LOGIN_REQUIRED);
    enter(); 
}
elsif ($action eq "insert")
{
    Bugzilla->login(LOGIN_REQUIRED);
    insert();
}
elsif ($action eq "edit") 
{ 
    edit(); 
}
elsif ($action eq "update") 
{ 
    Bugzilla->login(LOGIN_REQUIRED);
    update();
}
elsif ($action eq "prettypatch")
{
    prettyPatch();
}
else 
{ 
  ThrowCodeError("unknown_action", { action => $action });
}

exit;

################################################################################
# Data Validation / Security Authorization
################################################################################

# Validates an attachment ID. Optionally takes a parameter of a form
# variable name that contains the ID to be validated. If not specified,
# uses 'id'.
# 
# Will throw an error if 1) attachment ID is not a valid number,
# 2) attachment does not exist, or 3) user isn't allowed to access the
# attachment.
#
# Returns a list, where the first item is the validated, detainted
# attachment id, and the 2nd item is the bug id corresponding to the
# attachment.
# 
sub validateID
{
    my $param = @_ ? $_[0] : 'id';

    # 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.
    # Happens when calling plain attachment.cgi from the urlbar directly
    if ($param eq 'id' && !$cgi->param('id')) {

        print Bugzilla->cgi->header();
        $template->process("attachment/choose.html.tmpl", $vars) ||
            ThrowTemplateError($template->error());
        exit;
    }
    
    my $attach_id = $cgi->param($param);

    # Validate the specified attachment id. detaint kills $attach_id if
    # non-natural, so use the original value from $cgi in our exception
    # message here.
    detaint_natural($attach_id)
     || ThrowUserError("invalid_attach_id", { attach_id => $cgi->param($param) });
  
    # Make sure the attachment exists in the database.
    SendSQL("SELECT bug_id, isprivate FROM attachments WHERE attach_id = $attach_id");
    MoreSQLData()
      || ThrowUserError("invalid_attach_id", { attach_id => $attach_id });

    # Make sure the user is authorized to access this attachment's bug.
    (my $bugid, my $isprivate) = FetchSQLData();

    ValidateBugID($bugid);
    if ($isprivate && Param("insidergroup")) {
        UserInGroup(Param("insidergroup"))
          || ThrowUserError("auth_failure", {action => "access",
                                             object => "attachment"});
    }

    return ($attach_id,$bugid);
}

# Validates format of a diff/interdiff. Takes a list as an parameter, which
# defines the valid format values. Will throw an error if the format is not
# in the list. Returns either the user selected or default format.
sub validateFormat
{
  # receives a list of legal formats; first item is a default
  my $format = $cgi->param('format') || $_[0];
  if ( lsearch(\@_, $format) == -1)
  {
     ThrowUserError("invalid_format", { format  => $format, formats => \@_ });
  }

  return $format;
}

# Validates context of a diff/interdiff. Will throw an error if the context
# is not number, "file" or "patch". Returns the validated, detainted context.
sub validateContext
{
  my $context = $cgi->param('context') || "patch";
  if ($context ne "file" && $context ne "patch") {
    detaint_natural($context)
      || ThrowUserError("invalid_context", { context => $cgi->param('context') });
  }

  return $context;
}

sub validateCanEdit
{
    my ($attach_id) = (@_);

    # People in editbugs can edit all attachments
    return if UserInGroup("editbugs");

    # Bug 97729 - the submitter can edit their attachments
    SendSQL("SELECT attach_id FROM attachments WHERE " .
            "attach_id = $attach_id AND submitter_id = " . Bugzilla->user->id);

    FetchSQLData()
      || ThrowUserError("illegal_attachment_edit",
                        { attach_id => $attach_id });
}

sub validateCanChangeAttachment 
{
    my ($attachid) = @_;
    SendSQL("SELECT product_id
             FROM attachments
             INNER JOIN bugs
             ON bugs.bug_id = attachments.bug_id
             WHERE attach_id = $attachid");
    my $productid = FetchOneColumn();
    CanEditProductId($productid)
      || ThrowUserError("illegal_attachment_edit",
                        { attach_id => $attachid });
}

sub validateCanChangeBug
{
    my ($bugid) = @_;
    SendSQL("SELECT product_id
             FROM bugs 
             WHERE bug_id = $bugid");
    my $productid = FetchOneColumn();
    CanEditProductId($productid)
      || ThrowUserError("illegal_attachment_edit_bug",
                        { bug_id => $bugid });
}

sub validateDescription
{
    $cgi->param('description')
      || ThrowUserError("missing_attachment_description");
}

sub validateIsPatch
{
    # Set the ispatch flag to zero if it is undefined, since the UI uses
    # an HTML checkbox to represent this flag, and unchecked HTML checkboxes
    # do not get sent in HTML requests.
    $cgi->param('ispatch', $cgi->param('ispatch') ? 1 : 0);

    # Set the content type to text/plain if the attachment is a patch.
    $cgi->param('contenttype', 'text/plain') if $cgi->param('ispatch');
}

sub validateContentType
{
  if (!defined $cgi->param('contenttypemethod'))
  {
    ThrowUserError("missing_content_type_method");
  }
  elsif ($cgi->param('contenttypemethod') eq 'autodetect')
  {
    my $contenttype = $cgi->uploadInfo($cgi->param('data'))->{'Content-Type'};
    # The user asked us to auto-detect the content type, so use the type
    # specified in the HTTP request headers.
    if ( !$contenttype )
    {
      ThrowUserError("missing_content_type");
    }
    $cgi->param('contenttype', $contenttype);
  }
  elsif ($cgi->param('contenttypemethod') eq 'list')
  {
    # The user selected a content type from the list, so use their selection.
    $cgi->param('contenttype', $cgi->param('contenttypeselection'));
  }
  elsif ($cgi->param('contenttypemethod') eq 'manual')
  {
    # The user entered a content type manually, so use their entry.
    $cgi->param('contenttype', $cgi->param('contenttypeentry'));
  }
  else
  {
    ThrowCodeError("illegal_content_type_method",
                   { contenttypemethod => $cgi->param('contenttypemethod') });
  }

  if ( $cgi->param('contenttype') !~
         /^(application|audio|image|message|model|multipart|text|video)\/.+$/ )
  {
    ThrowUserError("invalid_content_type",
                   { contenttype => $cgi->param('contenttype') });
  }
}

sub validateIsObsolete
{
    # Set the isobsolete flag to zero if it is undefined, since the UI uses
    # an HTML checkbox to represent this flag, and unchecked HTML checkboxes
    # do not get sent in HTML requests.
    $cgi->param('isobsolete', $cgi->param('isobsolete') ? 1 : 0);
}

sub validatePrivate
{
    # Set the isprivate flag to zero if it is undefined, since the UI uses
    # an HTML checkbox to represent this flag, and unchecked HTML checkboxes
    # do not get sent in HTML requests.
    $cgi->param('isprivate', $cgi->param('isprivate') ? 1 : 0);
}

sub validateData
{
  my $maxsize = $cgi->param('ispatch') ? Param('maxpatchsize') : Param('maxattachmentsize');
  $maxsize *= 1024; # Convert from K
  my $fh;
  # Skip uploading into a local variable if the user wants to upload huge
  # attachments into local files.
  if (!$cgi->param('bigfile'))
  {
    $fh = $cgi->upload('data');
  }
  my $data;

  # We could get away with reading only as much as required, except that then
  # we wouldn't have a size to print to the error handler below.
  if (!$cgi->param('bigfile'))
  {
      # enable 'slurp' mode
      local $/;
      $data = <$fh>;
  }

  $data
    || ($cgi->param('bigfile'))
    || ThrowUserError("zero_length_file");

  # Make sure the attachment does not exceed the maximum permitted size
  my $len = $data ? length($data) : 0;
  if ($maxsize && $len > $maxsize) {
      my $vars = { filesize => sprintf("%.0f", $len/1024) };
      if ($cgi->param('ispatch')) {
          ThrowUserError("patch_too_large", $vars);
      } else {
          ThrowUserError("file_too_large", $vars);
      }
  }

  return $data || '';
}

sub validateFilename
{
  defined $cgi->upload('data')
    || ThrowUserError("file_not_specified");

  my $filename = $cgi->upload('data');
  
  # Remove path info (if any) from the file name.  The browser should do this
  # for us, but some are buggy.  This may not work on Mac file names and could
  # mess up file names with slashes in them, but them's the breaks.  We only
  # use this as a hint to users downloading attachments anyway, so it's not 
  # a big deal if it munges incorrectly occasionally.
  $filename =~ s/^.*[\/\\]//;

  # Truncate the filename to 100 characters, counting from the end of the string
  # to make sure we keep the filename extension.
  $filename = substr($filename, -100, 100);

  return $filename;
}

sub validateObsolete
{
  my @obsolete_ids = ();

  # Make sure the attachment id is valid and the user has permissions to view
  # the bug to which it is attached.
  foreach my $attachid ($cgi->param('obsolete')) {
    my $vars = {};
    $vars->{'attach_id'} = $attachid;
    
    detaint_natural($attachid)
      || ThrowCodeError("invalid_attach_id_to_obsolete", $vars);
  
    SendSQL("SELECT bug_id, isobsolete, description 
             FROM attachments WHERE attach_id = $attachid");

    # Make sure the attachment exists in the database.
    MoreSQLData()
      || ThrowUserError("invalid_attach_id", $vars);

    my ($bugid, $isobsolete, $description) = FetchSQLData();

    $vars->{'description'} = $description;
    
    if ($bugid != $cgi->param('bugid'))
    {
      $vars->{'my_bug_id'} = $cgi->param('bugid');
      $vars->{'attach_bug_id'} = $bugid;
      ThrowCodeError("mismatched_bug_ids_on_obsolete", $vars);
    }

    if ( $isobsolete )
    {
      ThrowCodeError("attachment_already_obsolete", $vars);
    }

    # Check that the user can modify this attachment
    validateCanEdit($attachid);
    push(@obsolete_ids, $attachid);
  }

  return @obsolete_ids;
}

# Returns 1 if the parameter is a content-type viewable in this browser
# Note that we don't use $cgi->Accept()'s ability to check if a content-type
# matches, because this will return a value even if it's matched by the generic
# */* which most browsers add to the end of their Accept: headers.
sub isViewable
{
  my $contenttype = trim(shift);
    
  # We assume we can view all text and image types  
  if ($contenttype =~ /^(text|image)\//) {
    return 1;
  }
  
  # Mozilla can view XUL. Note the trailing slash on the Gecko detection to
  # avoid sending XUL to Safari.
  if (($contenttype =~ /^application\/vnd\.mozilla\./) &&
      ($cgi->user_agent() =~ /Gecko\//))
  {
    return 1;
  }

  # If it's not one of the above types, we check the Accept: header for any 
  # types mentioned explicitly.
  my $accept = join(",", $cgi->Accept());
  
  if ($accept =~ /^(.*,)?\Q$contenttype\E(,.*)?$/) {
    return 1;
  }
  
  return 0;
}

################################################################################
# Functions
################################################################################

# Display an attachment.
sub view
{
    # Retrieve and validate parameters
    my ($attach_id) = validateID();

    # Retrieve the attachment content and its content type from the database.
    SendSQL("SELECT mimetype, filename, thedata FROM attachments " .
            "WHERE attach_id = $attach_id");
    my ($contenttype, $filename, $thedata) = FetchSQLData();
   
    # Bug 111522: allow overriding content-type manually in the posted form
    # params.
    if (defined $cgi->param('content_type'))
    {
        $cgi->param('contenttypemethod', 'manual');
        $cgi->param('contenttypeentry', $cgi->param('content_type'));
        validateContentType();
        $contenttype = $cgi->param('content_type');
    }

    # Return the appropriate HTTP response headers.
    $filename =~ s/^.*[\/\\]//;
    my $filesize = length($thedata);
    # A zero length attachment in the database means the attachment is 
    # stored in a local file
    if ($filesize == 0)
    {
        my $hash = ($attach_id % 100) + 100;
        $hash =~ s/.*(\d\d)$/group.$1/;
        if (open(AH, "$attachdir/$hash/attachment.$attach_id")) {
            binmode AH;
            $filesize = (stat(AH))[7];
        }
    }
    if ($filesize == 0)
    {
        ThrowUserError("attachment_removed");
    }


    # escape quotes and backslashes in the filename, per RFCs 2045/822
    $filename =~ s/\\/\\\\/g; # escape backslashes
    $filename =~ s/"/\\"/g; # escape quotes

    print Bugzilla->cgi->header(-type=>"$contenttype; name=\"$filename\"",
                                -content_disposition=> "inline; filename=\"$filename\"",
                                -content_length => $filesize);

    if ($thedata) {
        print $thedata;
    } else {
        while (<AH>) {
            print $_;
        }
        close(AH);
    }

}

sub interdiff
{
  # Retrieve and validate parameters
  my ($old_id) = validateID('oldid');
  my ($new_id) = validateID('newid');
  my $format = validateFormat('html', 'raw');
  my $context = validateContext();

  # Get old patch data
  my ($old_bugid, $old_description, $old_filename, $old_file_list) =
      get_unified_diff($old_id);

  # Get new patch data
  my ($new_bugid, $new_description, $new_filename, $new_file_list) =
      get_unified_diff($new_id);

  my $warning = warn_if_interdiff_might_fail($old_file_list, $new_file_list);

  #
  # send through interdiff, send output directly to template
  #
  # Must hack path so that interdiff will work.
  #
  $ENV{'PATH'} = $::diffpath;
  open my $interdiff_fh, "$::interdiffbin $old_filename $new_filename|";
  binmode $interdiff_fh;
    my ($reader, $last_reader) = setup_patch_readers("", $context);
    if ($format eq 'raw')
  {
    require PatchReader::DiffPrinter::raw;
    $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw());
    # Actually print out the patch
    print $cgi->header(-type => 'text/plain',
                       -expires => '+3M');
  }
  else
  {
    $vars->{warning} = $warning if $warning;
    $vars->{bugid} = $new_bugid;
    $vars->{oldid} = $old_id;
    $vars->{old_desc} = $old_description;
    $vars->{newid} = $new_id;
    $vars->{new_desc} = $new_description;
    delete $vars->{attachid};
    delete $vars->{do_context};
    delete $vars->{context};
    setup_template_patch_reader($last_reader, $format, $context);
  }
  $reader->iterate_fh($interdiff_fh, "interdiff #$old_id #$new_id");
  close $interdiff_fh;
  $ENV{'PATH'} = '';

  #
  # Delete temporary files
  #
  unlink($old_filename) or warn "Could not unlink $old_filename: $!";
  unlink($new_filename) or warn "Could not unlink $new_filename: $!";
}

sub get_unified_diff
{
  my ($id) = @_;

  # Bring in the modules we need
  require PatchReader::Raw;
  require PatchReader::FixPatchRoot;
  require PatchReader::DiffPrinter::raw;
  require PatchReader::PatchInfoGrabber;
  require File::Temp;

  # Get the patch
  SendSQL("SELECT bug_id, description, ispatch, thedata FROM attachments WHERE attach_id = $id");
  my ($bugid, $description, $ispatch, $thedata) = FetchSQLData();
  if (!$ispatch) {
    $vars->{'attach_id'} = $id;
    ThrowUserError("must_be_patch");
  }

  # Reads in the patch, converting to unified diff in a temp file
  my $reader = new PatchReader::Raw;
  my $last_reader = $reader;

  # fixes patch root (makes canonical if possible)
  if (Param('cvsroot')) {
    my $fix_patch_root = new PatchReader::FixPatchRoot(Param('cvsroot'));
    $last_reader->sends_data_to($fix_patch_root);
    $last_reader = $fix_patch_root;
  }

  # Grabs the patch file info
  my $patch_info_grabber = new PatchReader::PatchInfoGrabber();
  $last_reader->sends_data_to($patch_info_grabber);
  $last_reader = $patch_info_grabber;

  # Prints out to temporary file
  my ($fh, $filename) = File::Temp::tempfile();
  my $raw_printer = new PatchReader::DiffPrinter::raw($fh);
  $last_reader->sends_data_to($raw_printer);
  $last_reader = $raw_printer;

  # Iterate!
  $reader->iterate_string($id, $thedata);

  return ($bugid, $description, $filename, $patch_info_grabber->patch_info()->{files});
}

sub warn_if_interdiff_might_fail {
  my ($old_file_list, $new_file_list) = @_;
  # Verify that the list of files diffed is the same
  my @old_files = sort keys %{$old_file_list};
  my @new_files = sort keys %{$new_file_list};
  if (@old_files != @new_files ||
      join(' ', @old_files) ne join(' ', @new_files)) {
    return "interdiff1";
  }

  # Verify that the revisions in the files are the same
  foreach my $file (keys %{$old_file_list}) {
    if ($old_file_list->{$file}{old_revision} ne
        $new_file_list->{$file}{old_revision}) {
      return "interdiff2";
    }
  }

  return undef;
}

sub setup_patch_readers {
  my ($diff_root, $context) = @_;

  #
  # Parameters:
  # format=raw|html
  # context=patch|file|0-n
  # collapsed=0|1
  # headers=0|1
  #

  # Define the patch readers
  # The reader that reads the patch in (whatever its format)
  require PatchReader::Raw;
  my $reader = new PatchReader::Raw;
  my $last_reader = $reader;
  # Fix the patch root if we have a cvs root
  if (Param('cvsroot'))
  {
    require PatchReader::FixPatchRoot;
    $last_reader->sends_data_to(new PatchReader::FixPatchRoot(Param('cvsroot')));
    $last_reader->sends_data_to->diff_root($diff_root) if defined($diff_root);
    $last_reader = $last_reader->sends_data_to;
  }
  # Add in cvs context if we have the necessary info to do it
  if ($context ne "patch" && $::cvsbin && Param('cvsroot_get'))
  {
    require PatchReader::AddCVSContext;
    $last_reader->sends_data_to(
          new PatchReader::AddCVSContext($context,
                                         Param('cvsroot_get')));
    $last_reader = $last_reader->sends_data_to;
  }
  return ($reader, $last_reader);
}

sub setup_template_patch_reader
{
  my ($last_reader, $format, $context) = @_;

  require PatchReader::DiffPrinter::template;

  # Define the vars for templates
  if (defined $cgi->param('headers')) {
    $vars->{headers} = $cgi->param('headers');
  } else {
    $vars->{headers} = 1 if !defined $cgi->param('headers');
  }
  $vars->{collapsed} = $cgi->param('collapsed');
  $vars->{context} = $context;
  $vars->{do_context} = $::cvsbin && Param('cvsroot_get') && !$vars->{'newid'};

  # Print everything out
  print $cgi->header(-type => 'text/html',
                     -expires => '+3M');
  $last_reader->sends_data_to(new PatchReader::DiffPrinter::template($template,
                             "attachment/diff-header.$format.tmpl",
                             "attachment/diff-file.$format.tmpl",
                             "attachment/diff-footer.$format.tmpl",
                             { %{$vars},
                               bonsai_url => Param('bonsai_url'),
                               lxr_url => Param('lxr_url'),
                               lxr_root => Param('lxr_root'),
                             }));
}

sub prettyPatch
{
  # Retrieve and validate parameters
  my ($attach_id) = validateID();
  my $format = validateFormat('html', 'raw');
  my $context = validateContext();

  # Get patch data
  SendSQL("SELECT bug_id, description, ispatch, thedata FROM attachments " .
          "WHERE attach_id = $attach_id");
  my ($bugid, $description, $ispatch, $thedata) = FetchSQLData();

  # If it is not a patch, view normally
  if (!$ispatch)
  {
    view();
    return;
  }

  use vars qw($cgi);
  print $cgi->header(-type => 'text/html',
                     -expires => '+3M');

  open2(\*OUT, \*IN, "/usr/bin/ruby", "-I", "PrettyPatch", "PrettyPatch/prettify.rb");
  print IN $thedata . "\n";
  close(IN);
  while (<OUT>) {
      print;
  }
  close(OUT);
}

sub diff
{
  # Retrieve and validate parameters
  my ($attach_id) = validateID();
  my $format = validateFormat('html', 'raw');
  my $context = validateContext();

  # Get patch data
  SendSQL("SELECT bug_id, description, ispatch, thedata FROM attachments " .
          "WHERE attach_id = $attach_id");
  my ($bugid, $description, $ispatch, $thedata) = FetchSQLData();

  # If it is not a patch, view normally
  if (!$ispatch)
  {
    view();
    return;
  }

  my ($reader, $last_reader) = setup_patch_readers(undef,$context);

  if ($format eq 'raw')
  {
    require PatchReader::DiffPrinter::raw;
    $last_reader->sends_data_to(new PatchReader::DiffPrinter::raw());
    # Actually print out the patch
    use vars qw($cgi);
    print $cgi->header(-type => 'text/plain',
                       -expires => '+3M');
    $reader->iterate_string("Attachment $attach_id", $thedata);
  }
  else
  {
    $vars->{other_patches} = [];
    if ($::interdiffbin && $::diffpath) {
      # Get list of attachments on this bug.
      # Ignore the current patch, but select the one right before it
      # chronologically.
      SendSQL("SELECT attach_id, description FROM attachments WHERE bug_id = $bugid AND ispatch = 1 ORDER BY creation_ts DESC");
      my $select_next_patch = 0;
      while (my ($other_id, $other_desc) = FetchSQLData()) {
        if ($other_id eq $attach_id) {
          $select_next_patch = 1;
        } else {
          push @{$vars->{other_patches}}, { id => $other_id, desc => $other_desc, selected => $select_next_patch };
          if ($select_next_patch) {
            $select_next_patch = 0;
          }
        }
      }
    }

    $vars->{bugid} = $bugid;
    $vars->{attachid} = $attach_id;
    $vars->{description} = $description;
    setup_template_patch_reader($last_reader, $format, $context);
    # Actually print out the patch
    $reader->iterate_string("Attachment $attach_id", $thedata);
  }
}

# Display all attachments for a given bug in a series of IFRAMEs within one
# HTML page.
sub viewall
{
    # Retrieve and validate parameters
    my $bugid = $cgi->param('bugid');
    ValidateBugID($bugid);

    # Retrieve the attachments from the database and write them into an array
    # of hashes where each hash represents one attachment.
    my $privacy = "";
    my $dbh = Bugzilla->dbh;

    if (Param("insidergroup") && !(UserInGroup(Param("insidergroup")))) {
        $privacy = "AND isprivate < 1 ";
    }
    SendSQL("SELECT attach_id, " .
            $dbh->sql_date_format('creation_ts', '%Y.%m.%d %H:%i') . ",
            mimetype, description, ispatch, isobsolete, isprivate, 
            LENGTH(thedata)
            FROM attachments WHERE bug_id = $bugid $privacy 
            ORDER BY attach_id");
  my @attachments; # the attachments array
  while (MoreSQLData())
  {
    my %a; # the attachment hash
    ($a{'attachid'}, $a{'date'}, $a{'contenttype'},
     $a{'description'}, $a{'ispatch'}, $a{'isobsolete'}, $a{'isprivate'},
     $a{'datasize'}) = FetchSQLData();
    $a{'isviewable'} = isViewable($a{'contenttype'});
    $a{'flags'} = Bugzilla::Flag::match({ 'attach_id' => $a{'attachid'},
                                          '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.
  SendSQL("SELECT short_desc, assigned_to FROM bugs " .
          "WHERE bug_id = $bugid");
  my ($bugsummary, $assignee_id) = FetchSQLData();

  # Define the variables and functions that will be passed to the UI template.
  $vars->{'bugid'} = $bugid;
  $vars->{'attachments'} = \@attachments;
  $vars->{'bugassignee_id'} = $assignee_id;
  $vars->{'bugsummary'} = $bugsummary;
  $vars->{'GetBugLink'} = \&GetBugLink;

  print Bugzilla->cgi->header();

  # Generate and return the UI (HTML page) from the appropriate template.
  $template->process("attachment/show-multiple.html.tmpl", $vars)
    || ThrowTemplateError($template->error());
}

# Display a form for entering a new attachment.
sub enter
{
  # Retrieve and validate parameters
  my $bugid = $cgi->param('bugid');
  ValidateBugID($bugid);
  validateCanChangeBug($bugid);

  # Retrieve the attachments the user can edit from the database and write
  # them into an array of hashes where each hash represents one attachment.
  my $canEdit = "";
  if (!UserInGroup("editbugs")) {
      $canEdit = "AND submitter_id = " . Bugzilla->user->id;
  }
  SendSQL("SELECT attach_id, description, isprivate
           FROM attachments
           WHERE bug_id = $bugid 
           AND isobsolete = 0 $canEdit
           ORDER BY attach_id");
  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.
  SendSQL("SELECT short_desc, assigned_to FROM bugs 
           WHERE bug_id = $bugid");
  my ($bugsummary, $assignee_id) = FetchSQLData();

  # Define the variables and functions that will be passed to the UI template.
  $vars->{'bugid'} = $bugid;
  $vars->{'attachments'} = \@attachments;
  $vars->{'bugassignee_id'} = $assignee_id;
  $vars->{'bugsummary'} = $bugsummary;
  $vars->{'GetBugLink'} = \&GetBugLink;

  SendSQL("SELECT product_id, component_id FROM bugs
           WHERE bug_id = $bugid");
  my ($product_id, $component_id) = FetchSQLData();
  my $flag_types = Bugzilla::FlagType::match({'target_type'  => 'attachment',
                                              'product_id'   => $product_id,
                                              'component_id' => $component_id});
  $vars->{'flag_types'} = $flag_types;
  $vars->{'any_flags_requesteeble'} = grep($_->{'is_requesteeble'},
                                           @$flag_types);
  $vars->{'bug'} = new Bugzilla::Bug($bugid, Bugzilla->user);

  print Bugzilla->cgi->header();

  # Generate and return the UI (HTML page) from the appropriate template.
  $template->process("attachment/create.html.tmpl", $vars)
    || ThrowTemplateError($template->error());
}

# Insert a new attachment into the database.
sub insert
{
    my $dbh = Bugzilla->dbh;
    my $userid = Bugzilla->user->id;

    # Retrieve and validate parameters
    my $bugid = $cgi->param('bugid');
    ValidateBugID($bugid);
    validateCanChangeBug($bugid);
    ValidateComment(scalar $cgi->param('comment'));
    my $filename = validateFilename();
    validateIsPatch();
    my $data = validateData();
    validateDescription();
    validateContentType() unless $cgi->param('ispatch');

    my @obsolete_ids = ();
    @obsolete_ids = validateObsolete() if $cgi->param('obsolete');

    # The order of these function calls is important, as both Flag::validate
    # and FlagType::validate assume User::match_field has ensured that the
    # values in the requestee fields are legitimate user email addresses.
    my $match_status = Bugzilla::User::match_field($cgi, {
        '^requestee(_type)?-(\d+)$' => { 'type' => 'single' },
    }, MATCH_SKIP_CONFIRM);

    $vars->{'match_field'} = 'requestee';
    if ($match_status == USER_MATCH_FAILED) {
        $vars->{'message'} = 'user_match_failed';
    }
    elsif ($match_status == USER_MATCH_MULTIPLE) {
        $vars->{'message'} = 'user_match_multiple';
    }

    # FlagType::validate() and Flag::validate() should not detect
    # any reference to existing flags when creating a new attachment.
    # Setting the third param to -1 will force this function to check this point.
    Bugzilla::Flag::validate($cgi, $bugid, -1);
    Bugzilla::FlagType::validate($cgi, $bugid, -1);

    # Escape characters in strings that will be used in SQL statements.
    my $sql_filename = SqlQuote($filename);
    my $description = SqlQuote($cgi->param('description'));
    my $contenttype = SqlQuote($cgi->param('contenttype'));
    my $isprivate = $cgi->param('isprivate') ? 1 : 0;

  # Figure out when the changes were made.
  my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()"); 
  my $sql_timestamp = SqlQuote($timestamp); 

  # Insert the attachment into the database.
  my $sth = $dbh->prepare("INSERT INTO attachments
      (thedata, bug_id, creation_ts, filename, description,
       mimetype, ispatch, isprivate, submitter_id) 
      VALUES (?, $bugid, $sql_timestamp, $sql_filename,
              $description, $contenttype, " . $cgi->param('ispatch') . ",
              $isprivate, $userid)");
  # We only use $data here in this INSERT with a placeholder,
  # so it's safe.
  trick_taint($data);
  $sth->bind_param(1, $data, $dbh->BLOB_TYPE);
  $sth->execute();

  # Retrieve the ID of the newly created attachment record.
  my $attachid = $dbh->bz_last_key('attachments', 'attach_id');

  # If the file is to be stored locally, stream the file from the webserver
  # to the local file without reading it into a local variable.
  if ($cgi->param('bigfile'))
  {
    my $fh = $cgi->upload('data');
    my $hash = ($attachid % 100) + 100;
    $hash =~ s/.*(\d\d)$/group.$1/;
    mkdir "$attachdir/$hash", 0770;
    chmod 0770, "$attachdir/$hash";
    open(AH, ">$attachdir/$hash/attachment.$attachid");
    binmode AH;
    my $sizecount = 0;
    my $limit = (Param("maxlocalattachment") * 1048576);
    while (<$fh>) {
        print AH $_;
        $sizecount += length($_);
        if ($sizecount > $limit) {
            close AH;
            close $fh;
            unlink "$attachdir/$hash/attachment.$attachid";
            ThrowUserError("local_file_too_large");
        }
    }
    close AH;
    close $fh;
  }


  # Insert a comment about the new attachment into the database.
  my $comment = "Created an attachment (id=$attachid)\n" .
                $cgi->param('description') . "\n";
  $comment .= ("\n" . $cgi->param('comment')) if defined $cgi->param('comment');

  AppendComment($bugid, $userid, $comment, $isprivate, $timestamp);

  # Make existing attachments obsolete.
  my $fieldid = GetFieldID('attachments.isobsolete');
  foreach my $obsolete_id (@obsolete_ids) {
      # If the obsolete attachment has request flags, cancel them.
      # This call must be done before updating the 'attachments' table.
      Bugzilla::Flag::CancelRequests($bugid, $obsolete_id, $sql_timestamp);

      SendSQL("UPDATE attachments SET isobsolete = 1 " . 
              "WHERE attach_id = $obsolete_id");
      SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
                                          fieldid, removed, added) 
              VALUES ($bugid, $obsolete_id, $userid, $sql_timestamp, $fieldid,
                      '0', '1')");
  }

  # Assign the bug to the user, if they are allowed to take it
  my $owner = "";
  
  if ($cgi->param('takebug') && UserInGroup("editbugs")) {
      
      my @fields = ("assigned_to", "bug_status", "resolution", "everconfirmed",
                    "login_name");
      
      # Get the old values, for the bugs_activity table
      SendSQL("SELECT " . join(", ", @fields) . " " .
              "FROM bugs " .
              "INNER JOIN profiles " .
              "ON profiles.userid = bugs.assigned_to " .
              "WHERE bugs.bug_id = $bugid");
      
      my @oldvalues = FetchSQLData();
      my @newvalues = ($userid, "ASSIGNED", "", 1, Bugzilla->user->login);
      
      # Make sure the person we are taking the bug from gets mail.
      $owner = $oldvalues[4];  
                  
      @oldvalues = map(SqlQuote($_), @oldvalues);
      @newvalues = map(SqlQuote($_), @newvalues);
               
      # Update the bug record. Note that this doesn't involve login_name.
      SendSQL("UPDATE bugs SET delta_ts = $sql_timestamp, " . 
              join(", ", map("$fields[$_] = $newvalues[$_]", (0..3))) . 
              " WHERE bug_id = $bugid");
      
      # We store email addresses in the bugs_activity table rather than IDs.
      $oldvalues[0] = $oldvalues[4];
      $newvalues[0] = $newvalues[4];
      
      # Add the changes to the bugs_activity table
      for (my $i = 0; $i < 4; $i++) {
          if ($oldvalues[$i] ne $newvalues[$i]) {
              my $fieldid = GetFieldID($fields[$i]);
              SendSQL("INSERT INTO bugs_activity " .
                      "(bug_id, who, bug_when, fieldid, removed, added) " .
                      "VALUES ($bugid, $userid, $sql_timestamp, " .
                      "$fieldid, $oldvalues[$i], $newvalues[$i])");
          }
      }      
  }   
  
  # Create flags.
  my $target = Bugzilla::Flag::GetTarget(undef, $attachid);
  Bugzilla::Flag::process($target, $timestamp, $cgi);
   
  # Define the variables and functions that will be passed to the UI template.
  $vars->{'mailrecipients'} =  { 'changer' => Bugzilla->user->login,
                                 'owner'   => $owner };
  $vars->{'bugid'} = $bugid;
  $vars->{'attachid'} = $attachid;
  $vars->{'description'} = $description;
  $vars->{'contenttypemethod'} = $cgi->param('contenttypemethod');
  $vars->{'contenttype'} = $cgi->param('contenttype');

  print Bugzilla->cgi->header();

  # Generate and return the UI (HTML page) from the appropriate template.
  $template->process("attachment/created.html.tmpl", $vars)
    || ThrowTemplateError($template->error());
}

# Displays a form for editing attachment properties.
# Any user is allowed to access this page, unless the attachment
# is private and the user does not belong to the insider group.
# Validations are done later when the user submits changes.
sub edit
{
  # Retrieve and validate parameters
  my ($attach_id) = validateID();

  # Retrieve the attachment from the database.
  SendSQL("SELECT description, mimetype, filename, bug_id, ispatch, isobsolete, isprivate, LENGTH(thedata)
           FROM attachments WHERE attach_id = $attach_id");
  my ($description, $contenttype, $filename, $bugid, $ispatch, $isobsolete, $isprivate, $datasize) = FetchSQLData();

  my $isviewable = isViewable($contenttype);

  # Retrieve a list of attachments for this bug as well as a summary of the bug
  # to use in a navigation bar across the top of the screen.
  SendSQL("SELECT attach_id FROM attachments WHERE bug_id = $bugid ORDER BY attach_id");
  my @bugattachments;
  push(@bugattachments, FetchSQLData()) while (MoreSQLData());
  SendSQL("SELECT short_desc FROM bugs WHERE bug_id = $bugid");
  my ($bugsummary) = FetchSQLData();
  
  # Get a list of flag types that can be set for this attachment.
  SendSQL("SELECT product_id, component_id FROM bugs WHERE bug_id = $bugid");
  my ($product_id, $component_id) = FetchSQLData();
  my $flag_types = Bugzilla::FlagType::match({ 'target_type'  => 'attachment' ,
                                               'product_id'   => $product_id ,
                                               'component_id' => $component_id });
  foreach my $flag_type (@$flag_types) {
    $flag_type->{'flags'} = Bugzilla::Flag::match({ 'type_id'   => $flag_type->{'id'},
                                                    'attach_id' => $attach_id,
                                                    'is_active' => 1 });
  }
  $vars->{'flag_types'} = $flag_types;
  $vars->{'any_flags_requesteeble'} = grep($_->{'is_requesteeble'}, @$flag_types);
  
  # Define the variables and functions that will be passed to the UI template.
  $vars->{'attachid'} = $attach_id; 
  $vars->{'description'} = $description; 
  $vars->{'contenttype'} = $contenttype; 
  $vars->{'filename'} = $filename;
  $vars->{'bugid'} = $bugid; 
  $vars->{'bugsummary'} = $bugsummary; 
  $vars->{'ispatch'} = $ispatch; 
  $vars->{'isobsolete'} = $isobsolete; 
  $vars->{'isprivate'} = $isprivate; 
  $vars->{'datasize'} = $datasize;
  $vars->{'isviewable'} = $isviewable; 
  $vars->{'attachments'} = \@bugattachments; 
  $vars->{'GetBugLink'} = \&GetBugLink;

  # Determine if PatchReader is installed
  eval {
    require PatchReader;
    $vars->{'patchviewerinstalled'} = 1;
  };
  print Bugzilla->cgi->header();

  # Generate and return the UI (HTML page) from the appropriate template.
  $template->process("attachment/edit.html.tmpl", $vars)
    || ThrowTemplateError($template->error());
}

# Updates an attachment record. Users with "editbugs" privileges, (or the
# original attachment's submitter) can edit the attachment's description,
# content type, ispatch and isobsolete flags, and statuses, and they can
# also submit a comment that appears in the bug.
# Users cannot edit the content of the attachment itself.
sub update
{
  my $dbh = Bugzilla->dbh;
  my $userid = Bugzilla->user->id;

    # Retrieve and validate parameters
    ValidateComment(scalar $cgi->param('comment'));
    my ($attach_id, $bugid) = validateID();
    validateCanEdit($attach_id);
    validateCanChangeAttachment($attach_id);
    validateDescription();
    validateIsPatch();
    validateContentType() unless $cgi->param('ispatch');
    validateIsObsolete();
    validatePrivate();

    # The order of these function calls is important, as both Flag::validate
    # and FlagType::validate assume User::match_field has ensured that the
    # values in the requestee fields are legitimate user email addresses.
    Bugzilla::User::match_field($cgi, {
        '^requestee(_type)?-(\d+)$' => { 'type' => 'single' }
    });
    Bugzilla::Flag::validate($cgi, $bugid, $attach_id);
    Bugzilla::FlagType::validate($cgi, $bugid, $attach_id);

  # Lock database tables in preparation for updating the attachment.
  $dbh->bz_lock_tables('attachments WRITE', 'flags WRITE' ,
          'flagtypes READ', 'fielddefs READ', 'bugs_activity WRITE',
          'flaginclusions AS i READ', 'flagexclusions AS e READ',
          # cc, bug_group_map, user_group_map, and groups are in here so we
          # can check the permissions of flag requestees and email addresses
          # on the flag type cc: lists via the CanSeeBug
          # function call in Flag::notify. group_group_map is in here in case
          # Bugzilla::User needs to rederive groups. profiles and 
          # user_group_map would be READ locks instead of WRITE locks if it
          # weren't for derive_groups, which needs to write to those tables.
          'bugs WRITE', 'profiles WRITE', 'email_setting READ',
          'cc READ', 'bug_group_map READ', 'user_group_map WRITE',
          'group_group_map READ', 'groups READ');

  # Get a copy of the attachment record before we make changes
  # 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,
      $oldisobsolete, $oldisprivate) = FetchSQLData();

  # Quote the description and content type for use in the SQL UPDATE statement.
  my $quoteddescription = SqlQuote($cgi->param('description'));
  my $quotedcontenttype = SqlQuote($cgi->param('contenttype'));
  my $quotedfilename = SqlQuote($cgi->param('filename'));

  # Figure out when the changes were made.
  SendSQL("SELECT NOW()");
  my $timestamp = FetchOneColumn();
    
  # Update flags.  We have to do this before committing changes
  # to attachments so that we can delete pending requests if the user
  # is obsoleting this attachment without deleting any requests
  # the user submits at the same time.
  my $target = Bugzilla::Flag::GetTarget(undef, $attach_id);
  Bugzilla::Flag::process($target, $timestamp, $cgi);

  # Update the attachment record in the database.
  SendSQL("UPDATE  attachments 
           SET     description = $quoteddescription ,
                   mimetype = $quotedcontenttype ,
                   filename = $quotedfilename ,
                   ispatch = " . $cgi->param('ispatch') . ",
                   isobsolete = " . $cgi->param('isobsolete') . ",
                   isprivate = " . $cgi->param('isprivate') . "
           WHERE   attach_id = $attach_id
         ");

  # Record changes in the activity table.
  my $sql_timestamp = SqlQuote($timestamp);
  if ($olddescription ne $cgi->param('description')) {
    my $quotedolddescription = SqlQuote($olddescription);
    my $fieldid = GetFieldID('attachments.description');
    SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
                                        fieldid, removed, added)
             VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid,
                     $quotedolddescription, $quoteddescription)");
  }
  if ($oldcontenttype ne $cgi->param('contenttype')) {
    my $quotedoldcontenttype = SqlQuote($oldcontenttype);
    my $fieldid = GetFieldID('attachments.mimetype');
    SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
                                        fieldid, removed, added)
             VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid,
                     $quotedoldcontenttype, $quotedcontenttype)");
  }
  if ($oldfilename ne $cgi->param('filename')) {
    my $quotedoldfilename = SqlQuote($oldfilename);
    my $fieldid = GetFieldID('attachments.filename');
    SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
                                        fieldid, removed, added)
             VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid,
                     $quotedoldfilename, $quotedfilename)");
  }
  if ($oldispatch ne $cgi->param('ispatch')) {
    my $fieldid = GetFieldID('attachments.ispatch');
    SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
                                        fieldid, removed, added)
             VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid,
                     $oldispatch, " . $cgi->param('ispatch') . ")");
  }
  if ($oldisobsolete ne $cgi->param('isobsolete')) {
    my $fieldid = GetFieldID('attachments.isobsolete');
    SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
                                        fieldid, removed, added)
             VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid,
                     $oldisobsolete, " . $cgi->param('isobsolete') . ")");
  }
  if ($oldisprivate ne $cgi->param('isprivate')) {
    my $fieldid = GetFieldID('attachments.isprivate');
    SendSQL("INSERT INTO bugs_activity (bug_id, attach_id, who, bug_when,
                                        fieldid, removed, added)
             VALUES ($bugid, $attach_id, $userid, $sql_timestamp, $fieldid,
                     $oldisprivate, " . $cgi->param('isprivate') . ")");
  }
  
  # Unlock all database tables now that we are finished updating the database.
  $dbh->bz_unlock_tables();

  # If the user submitted a comment while editing the attachment,
  # add the comment to the bug.
  if ($cgi->param('comment'))
  {
    # Prepend a string to the comment to let users know that the comment came
    # from the "edit attachment" screen.
    my $comment = qq|(From update of attachment $attach_id)\n| .
                  $cgi->param('comment');

    # Append the comment to the list of comments in the database.
    AppendComment($bugid, $userid, $comment, $cgi->param('isprivate'), $timestamp);
  }
  
  # Define the variables and functions that will be passed to the UI template.
  $vars->{'mailrecipients'} = { 'changer' => Bugzilla->user->login };
  $vars->{'attachid'} = $attach_id; 
  $vars->{'bugid'} = $bugid; 

  print Bugzilla->cgi->header();

  # Generate and return the UI (HTML page) from the appropriate template.
  $template->process("attachment/updated.html.tmpl", $vars)
    || ThrowTemplateError($template->error());
}
