diff options
Diffstat (limited to 'Bugzilla/Attachment/PatchReader.pm')
-rw-r--r-- | Bugzilla/Attachment/PatchReader.pm | 82 |
1 files changed, 54 insertions, 28 deletions
diff --git a/Bugzilla/Attachment/PatchReader.pm b/Bugzilla/Attachment/PatchReader.pm index cfc7610f4..1ab14f386 100644 --- a/Bugzilla/Attachment/PatchReader.pm +++ b/Bugzilla/Attachment/PatchReader.pm @@ -19,6 +19,9 @@ use strict; package Bugzilla::Attachment::PatchReader; +use IPC::Open3; +use Symbol 'gensym'; + use Bugzilla::Error; use Bugzilla::Attachment; use Bugzilla::Util; @@ -33,8 +36,8 @@ sub process_diff { 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()); + require Bugzilla::PatchReader::DiffPrinter::raw; + $last_reader->sends_data_to(new Bugzilla::PatchReader::DiffPrinter::raw()); # Actually print out the patch. print $cgi->header(-type => 'text/plain', -expires => '+3M'); @@ -46,7 +49,7 @@ sub process_diff { if ($lc->{interdiffbin} && $lc->{diffpath}) { # Get the list of attachments that the user can view in this bug. my @attachments = - @{Bugzilla::Attachment->get_attachments_by_bug($attachment->bug_id)}; + @{Bugzilla::Attachment->get_attachments_by_bug($attachment->bug)}; # Extract patches only. @attachments = grep {$_->ispatch == 1} @attachments; # We want them sorted from newer to older. @@ -109,13 +112,37 @@ sub process_interdiff { # Send through interdiff, send output directly to template. # Must hack path so that interdiff will work. $ENV{'PATH'} = $lc->{diffpath}; - open my $interdiff_fh, "$lc->{interdiffbin} $old_filename $new_filename|"; - binmode $interdiff_fh; + + my ($pid, $interdiff_stdout, $interdiff_stderr); + if ($ENV{MOD_PERL}) { + require Apache2::RequestUtil; + require Apache2::SubProcess; + my $request = Apache2::RequestUtil->request; + (undef, $interdiff_stdout, $interdiff_stderr) = $request->spawn_proc_prog( + $lc->{interdiffbin}, [$old_filename, $new_filename] + ); + } else { + $interdiff_stderr = gensym; + my $pid = open3(gensym, $interdiff_stdout, $interdiff_stderr, + $lc->{interdiffbin}, $old_filename, $new_filename); + } + binmode $interdiff_stdout; + + # Check for errors + { + local $/ = undef; + my $error = <$interdiff_stderr>; + if ($error) { + warn($error); + $warning = 'interdiff3'; + } + } + 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()); + require Bugzilla::PatchReader::DiffPrinter::raw; + $last_reader->sends_data_to(new Bugzilla::PatchReader::DiffPrinter::raw()); # Actually print out the patch. print $cgi->header(-type => 'text/plain', -expires => '+3M'); @@ -123,7 +150,7 @@ sub process_interdiff { } else { # In case the HTML page is displayed with the UTF-8 encoding. - binmode $interdiff_fh, ':utf8' if Bugzilla->params->{'utf8'}; + binmode $interdiff_stdout, ':utf8' if Bugzilla->params->{'utf8'}; $vars->{'warning'} = $warning if $warning; $vars->{'bugid'} = $new_attachment->bug_id; @@ -134,9 +161,9 @@ sub process_interdiff { setup_template_patch_reader($last_reader, $format, $context, $vars); } - $reader->iterate_fh($interdiff_fh, 'interdiff #' . $old_attachment->id . + $reader->iterate_fh($interdiff_stdout, 'interdiff #' . $old_attachment->id . ' #' . $new_attachment->id); - close $interdiff_fh; + waitpid($pid, 0) if $pid; $ENV{'PATH'} = ''; # Delete temporary files. @@ -152,29 +179,29 @@ sub get_unified_diff { my ($attachment, $format) = @_; # Bring in the modules we need. - require PatchReader::Raw; - require PatchReader::FixPatchRoot; - require PatchReader::DiffPrinter::raw; - require PatchReader::PatchInfoGrabber; + require Bugzilla::PatchReader::Raw; + require Bugzilla::PatchReader::FixPatchRoot; + require Bugzilla::PatchReader::DiffPrinter::raw; + require Bugzilla::PatchReader::PatchInfoGrabber; require File::Temp; $attachment->ispatch || ThrowCodeError('must_be_patch', { 'attach_id' => $attachment->id }); # Reads in the patch, converting to unified diff in a temp file. - my $reader = new PatchReader::Raw; + my $reader = new Bugzilla::PatchReader::Raw; my $last_reader = $reader; # Fixes patch root (makes canonical if possible). if (Bugzilla->params->{'cvsroot'}) { my $fix_patch_root = - new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'}); + new Bugzilla::PatchReader::FixPatchRoot(Bugzilla->params->{'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(); + my $patch_info_grabber = new Bugzilla::PatchReader::PatchInfoGrabber(); $last_reader->sends_data_to($patch_info_grabber); $last_reader = $patch_info_grabber; @@ -184,7 +211,7 @@ sub get_unified_diff { # The HTML page will be displayed with the UTF-8 encoding. binmode $fh, ':utf8'; } - my $raw_printer = new PatchReader::DiffPrinter::raw($fh); + my $raw_printer = new Bugzilla::PatchReader::DiffPrinter::raw($fh); $last_reader->sends_data_to($raw_printer); $last_reader = $raw_printer; @@ -228,13 +255,13 @@ sub setup_patch_readers { # Define the patch readers. # The reader that reads the patch in (whatever its format). - require PatchReader::Raw; - my $reader = new PatchReader::Raw; + require Bugzilla::PatchReader::Raw; + my $reader = new Bugzilla::PatchReader::Raw; my $last_reader = $reader; # Fix the patch root if we have a cvs root. if (Bugzilla->params->{'cvsroot'}) { - require PatchReader::FixPatchRoot; - $last_reader->sends_data_to(new PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'})); + require Bugzilla::PatchReader::FixPatchRoot; + $last_reader->sends_data_to(new Bugzilla::PatchReader::FixPatchRoot(Bugzilla->params->{'cvsroot'})); $last_reader->sends_data_to->diff_root($diff_root) if defined($diff_root); $last_reader = $last_reader->sends_data_to; } @@ -243,12 +270,12 @@ sub setup_patch_readers { if ($context ne 'patch' && Bugzilla->localconfig->{cvsbin} && Bugzilla->params->{'cvsroot_get'}) { - require PatchReader::AddCVSContext; + require Bugzilla::PatchReader::AddCVSContext; # We need to set $cvsbin as global, because PatchReader::CVSClient # needs it in order to find 'cvs'. $main::cvsbin = Bugzilla->localconfig->{cvsbin}; $last_reader->sends_data_to( - new PatchReader::AddCVSContext($context, Bugzilla->params->{'cvsroot_get'})); + new Bugzilla::PatchReader::AddCVSContext($context, Bugzilla->params->{'cvsroot_get'})); $last_reader = $last_reader->sends_data_to; } @@ -260,7 +287,7 @@ sub setup_template_patch_reader { my $cgi = Bugzilla->cgi; my $template = Bugzilla->template; - require PatchReader::DiffPrinter::template; + require Bugzilla::PatchReader::DiffPrinter::template; # Define the vars for templates. if (defined $cgi->param('headers')) { @@ -276,10 +303,9 @@ sub setup_template_patch_reader { && Bugzilla->params->{'cvsroot_get'} && !$vars->{'newid'}; # Print everything out. - print $cgi->header(-type => 'text/html', - -expires => '+3M'); + print $cgi->header(-type => 'text/html'); - $last_reader->sends_data_to(new PatchReader::DiffPrinter::template($template, + $last_reader->sends_data_to(new Bugzilla::PatchReader::DiffPrinter::template($template, "attachment/diff-header.$format.tmpl", "attachment/diff-file.$format.tmpl", "attachment/diff-footer.$format.tmpl", |