X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=lib%2FPublicInbox%2FSolverGit.pm;h=dd95f40043b14c3cf230393845ed812bf898d489;hb=38226be5fd4c24885658e00d4ce87ccee663063d;hp=34669dbeeaf97f6c706c7734318b48334647fbbc;hpb=95bdac7f09c69036efed537a4d03d5bdd2ae4eb6;p=public-inbox.git diff --git a/lib/PublicInbox/SolverGit.pm b/lib/PublicInbox/SolverGit.pm index 34669dbe..dd95f400 100644 --- a/lib/PublicInbox/SolverGit.pm +++ b/lib/PublicInbox/SolverGit.pm @@ -9,12 +9,11 @@ # local filesystem layouts in the process. package PublicInbox::SolverGit; use strict; -use warnings; -use 5.010_001; +use v5.10.1; use File::Temp 0.19 (); # 0.19 for ->newdir use Fcntl qw(SEEK_SET); use PublicInbox::Git qw(git_unquote git_quote); -use PublicInbox::MsgIter qw(msg_iter msg_part_text); +use PublicInbox::MsgIter qw(msg_part_text); use PublicInbox::Qspawn; use PublicInbox::Tmpfile; use URI::Escape qw(uri_escape_utf8); @@ -34,6 +33,12 @@ my $OID_MIN = 7; # work fairly. Other PSGI servers may have trouble, though. my $MAX_PATCH = 9999; +my $LF = qr!\r?\n!; +my $ANY = qr![^\r\n]+!; +my $MODE = '100644|120000|100755'; +my $FN = qr!(?:("?[^/\n]+/[^\r\n]+)|/dev/null)!; +my %BAD_COMPONENT = ('' => 1, '.' => 1, '..' => 1); + # di = diff info / a hashref with information about a diff ($di): # { # oid_a => abbreviated pre-image oid, @@ -42,7 +47,7 @@ my $MAX_PATCH = 9999; # hdr_lines => string of various header lines for mode information # mode_a => original mode of oid_a (string, not integer), # ibx => PublicInbox::Inbox object containing the diff -# smsg => PublicInbox::SearchMsg object containing diff +# smsg => PublicInbox::Smsg object containing diff # path_a => pre-image path # path_b => post-image path # n => numeric path of the patch (relative to worktree) @@ -110,10 +115,6 @@ sub extract_diff ($$) { $s =~ s/\r\n/\n/sg; } - state $LF = qr!\r?\n!; - state $ANY = qr![^\r\n]+!; - state $MODE = '100644|120000|100755'; - state $FN = qr!(?:("?[^/\n]+/[^\r\n]+)|/dev/null)!; $s =~ m!( # $1 start header lines we save for debugging: @@ -174,8 +175,7 @@ sub extract_diff ($$) { # get rid of path-traversal attempts and junk patches: # it's junk at best, an attack attempt at worse: - state $bad_component = { map { $_ => 1 } ('', '.', '..') }; - foreach (@a, @b) { return if $bad_component->{$_} } + foreach (@a, @b) { return if $BAD_COMPONENT{$_} } $di->{path_a} = join('/', @a) if @a; $di->{path_b} = join('/', @b); @@ -228,12 +228,11 @@ sub find_extract_diffs ($$$) { } } - my $msgs = $srch->query($q, { relevance => 1 }); - + my $mset = $srch->mset($q, { relevance => 1 }); my $diffs = []; - foreach my $smsg (@$msgs) { - $ibx->smsg_mime($smsg) or next; - msg_iter(delete $smsg->{mime}, \&extract_diff, + for my $smsg (@{$srch->mset_to_smsg($ibx, $mset)}) { + my $eml = $ibx->smsg_eml($smsg) or next; + $eml->each_part(\&extract_diff, [$self, $diffs, $pre, $post, $ibx, $smsg], 1); } @$diffs ? $diffs : undef; @@ -270,7 +269,7 @@ sub prepare_index ($) { my $in = tmpfile("update-index.$oid_full") or die "tmpfile: $!"; print $in "$mode_a $oid_full\t$path_a\0" or die "print: $!"; $in->flush or die "flush: $!"; - sysseek($in, 0, 0) or die "seek: $!"; + sysseek($in, 0, SEEK_SET) or die "seek: $!"; dbg($self, 'preparing index'); my $rdr = { 0 => $in }; @@ -593,7 +592,7 @@ sub new { } # recreate $oid_want using $hints -# hints keys: path_a, path_b, oid_a +# hints keys: path_a, path_b, oid_a (note: `oid_b' is NOT a hint) # Calls {user_cb} with: [ ::Git object, oid_full, type, size, di (diff_info) ] # with found object, or undef if nothing was found # Calls {user_cb} with a string error on fatal errors