Package: jetring
Version: 0.09
Severity: important
Tags: patch

It seems that jetring-diff doesn't take account of the fact that each
signature packet is associated with a specific other PGP packet; as a
result displaying a diff results in all the new sigs being shown at the
end rather than displaying which uid/subkey etc they are for. This
strikes me as fairly important - when diffing keys you care about
whether a self sig is just another one on the uid or actually updating a
subkey binding, which currently it's hard to tell.

I think the attached patch solves the problem, though there's probably a
cleaner way to do it.

-- System Information:
Debian Release: lenny/sid
  APT prefers testing
  APT policy: (750, 'testing')
Architecture: i386 (i686)

Kernel: Linux 2.6.23-toshacpi (PREEMPT)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages jetring depends on:
ii  gnupg                         1.4.6-2    GNU privacy guard - a free PGP rep

jetring recommends no packages.

-- no debconf information
--- jetring-diff        2007-11-24 09:22:45.000000000 +0000
+++ jetring-diff.new    2007-11-24 09:25:54.000000000 +0000
@@ -27,23 +27,30 @@
        else {
                my $diff=0;
                my @out;
-               my %lseen=map { comparable($_) => 1 } @{$l->{$id}};
-               my %rseen=map { comparable($_) => 1 } @{$r->{$id}};
-               foreach my $record (@{$l->{$id}}) {
-                       if ($rseen{comparable($record)}) {
-                               push @out, " ".outformat($record) if 
$record->[0] ne 'sig';
-                       }
-                       else {
-                               push @out, "-".outformat($record);
-                               $diff=1;
+
+               my %rpackets = map { comparable($_->{'details'}) => $_ }
+                               @{$r->{$id}};
+               my %lpackets = map { comparable($_->{'details'}) => 1 }
+                               @{$l->{$id}};
+
+               foreach my $packet (@{$l->{$id}}) {
+                       if 
(defined($rpackets{comparable($packet->{'details'})})) {
+                               push @out, " ".outformat($packet->{'details'});
+                               push @out, comparesigs(\$diff, 
$packet->{'sigs'},
+                                               
$rpackets{comparable($packet->{'details'})}->{'sigs'});
+                       } else {
+                               push @out, "-".outformat($packet->{'details'});
+                               $diff = 1;
                        }
                }
-               foreach my $record (@{$r->{$id}}) {
-                       if (! $lseen{comparable($record)}) {
-                               push @out, "+".outformat($record);
-                               $diff=1;
+
+               foreach my $packet (@{$r->{$id}}) {
+                       if (! $lpackets{comparable($packet->{'details'})}) {
+                               push @out, "+".outformat($packet->{'details'});
+                               $diff = 1;
                        }
                }
+
                print @out if $diff;
        }
 }
@@ -72,12 +79,13 @@
                open(DUMP, "gpg --options /dev/null --no-default-keyring 
--no-auto-check-trustdb --keyring $k --list-sigs --fixed-list-mode 
--with-colons |") 
                        or die "couldn't dump keyring $k: $!";
                if (! open(CACHE, ">$cache")) {
-                       print STDERR "watning: cannot write cache $cache\n";
+                       print STDERR "warning: cannot write cache $cache\n";
                        $cache=undef;
                }
        }
        my %keys;
        my $id;
+       my $packet;
        while (<DUMP>) {
                if (! $cached && defined $cache) {
                        print CACHE $_;
@@ -90,12 +98,21 @@
                if ($fields[0] eq 'pub') {
                        $id=$fields[4];
                }
-               if (! defined $id) {
-                       die "parse error: $_";
-                       next;
+               if ($fields[0] ne 'sig' && $fields[0] ne 'rev') {
+                       if (defined($packet)) {
+                               push @{$keys{$id}}, $packet;
+                               undef $packet;
+                       }
+                       $packet->{'details'} = [EMAIL PROTECTED];
+               } else {
+                       if (! defined $id or !defined($packet)) {
+                               die "parse error: $_";
+                               next;
+                       }
+                       push @{$packet->{'sigs'}}, [EMAIL PROTECTED];
                }
-               push @{$keys{$id}}, [EMAIL PROTECTED];
        }
+       push @{$keys{$id}}, $packet;
        close DUMP;
 
        if (defined $cache) {
@@ -130,3 +147,27 @@
        }
        return join(":", @record);
 }
+
+sub comparesigs {
+       my $diff = shift;
+       my $l = shift;
+       my $r = shift;
+       my %lseen = map { comparable($_) => 1 } @{$l};
+       my %rseen = map { comparable($_) => 1 } @{$r};
+       my @out;
+
+       foreach my $record (@{$l}) {
+               if (! $rseen{comparable($record)}) {
+                       push @out, "-".outformat($record);
+                       ${$diff} = 1;
+               }
+       }
+       foreach my $record (@{$r}) {
+               if (! $lseen{comparable($record)}) {
+                       push @out, "+".outformat($record);
+                       ${$diff} = 1;
+               }
+       }
+
+       return @out;
+}

Reply via email to