Ver código fonte

Dpkg::Deps: Fix implications evaluation to use arch qualifiers

When evaluating implications, it's important to take into account the
arch qualifier otherwise the dependency simplification code might strip
dependencies that cannot be stripped without altering the meaning
of the dependency.

Sponsored-by: Linaro Limited
Raphaël Hertzog 15 anos atrás
pai
commit
16fb27a839
2 arquivos alterados com 37 adições e 1 exclusões
  1. 28 0
      scripts/Dpkg/Deps.pm
  2. 9 1
      scripts/t/400_Dpkg_Deps.t

+ 28 - 0
scripts/Dpkg/Deps.pm

@@ -125,6 +125,29 @@ sub _arch_is_superset {
     return 1;
     return 1;
 }
 }
 
 
+# Dpkg::Deps::_arch_qualifier_allows_implication($p, $q)
+#
+# Returns true if the arch qualifier $p and $q are compatible with the
+# implication $p -> $q, false otherwise. $p/$q can be
+# undef/"any"/"native" or an architecture string.
+
+sub _arch_qualifier_allows_implication {
+    my ($p, $q) = @_;
+    if (defined $p and $p eq "any") {
+	return 1 if defined $q and $q eq "any";
+	return 0;
+    } elsif (defined $p and $p eq "native") {
+	return 1 if defined $q and ($q eq "any" or $q eq "native");
+	return 0;
+    } elsif (defined $p) {
+	return 1 if defined $q and ($p eq $q or $q eq "any");
+	return 0;
+    } else {
+	return 0 if defined $q and $q ne "any" and $q ne "native";
+	return 1;
+    }
+}
+
 =item deps_eval_implication($rel_p, $v_p, $rel_q, $v_q)
 =item deps_eval_implication($rel_p, $v_p, $rel_q, $v_q)
 
 
 ($rel_p, $v_p) and ($rel_q, $v_q) express two dependencies as (relation,
 ($rel_p, $v_p) and ($rel_q, $v_q) express two dependencies as (relation,
@@ -598,6 +621,11 @@ sub implies {
 	# o, otherwise we can't conclude anything.
 	# o, otherwise we can't conclude anything.
 	return undef unless Dpkg::Deps::_arch_is_superset($self->{arches}, $o->{arches});
 	return undef unless Dpkg::Deps::_arch_is_superset($self->{arches}, $o->{arches});
 
 
+	# The arch qualifier must not forbid an implication
+	return undef unless
+	    Dpkg::Deps::_arch_qualifier_allows_implication($self->{archqual},
+	                                                   $o->{archqual});
+
 	# If o has no version clause, then our dependency is stronger
 	# If o has no version clause, then our dependency is stronger
 	return 1 if not defined $o->{relation};
 	return 1 if not defined $o->{relation};
 	# If o has a version clause, we must also have one, otherwise there
 	# If o has a version clause, we must also have one, otherwise there

+ 9 - 1
scripts/t/400_Dpkg_Deps.t

@@ -13,7 +13,7 @@
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
-use Test::More tests => 18;
+use Test::More tests => 20;
 
 
 use strict;
 use strict;
 use warnings;
 use warnings;
@@ -41,6 +41,14 @@ my $dep_or2 = deps_parse("x|y|a|b|c (<= 0.5)|c (>=1.5)|d|e");
 is($dep_or1->implies($dep_or2), 1, "Implication between OR 1/2");
 is($dep_or1->implies($dep_or2), 1, "Implication between OR 1/2");
 is($dep_or2->implies($dep_or1), undef, "Implication between OR 2/2");
 is($dep_or2->implies($dep_or1), undef, "Implication between OR 2/2");
 
 
+my $dep_ma_any = deps_parse("libcairo2:any");
+my $dep_ma_native = deps_parse("libcairo2");
+#my $dep_ma_native2 = deps_parse("libcairo2:native");
+is($dep_ma_native->implies($dep_ma_any), 1, "foo -> foo:any");
+#is($dep_ma_native2->implies($dep_ma_any), 1, "foo:native -> foo:any");
+is($dep_ma_any->implies($dep_ma_native), undef, "foo:any !-> foo");
+#is($dep_ma_any->implies($dep_ma_native2), undef, "foo:any !-> foo:native");
+
 my $field_arch = "libc6 (>= 2.5) [!alpha !hurd-i386], libc6.1 [alpha], libc0.1 [hurd-i386]";
 my $field_arch = "libc6 (>= 2.5) [!alpha !hurd-i386], libc6.1 [alpha], libc0.1 [hurd-i386]";
 my $dep_i386 = deps_parse($field_arch, reduce_arch => 1, host_arch => 'i386');
 my $dep_i386 = deps_parse($field_arch, reduce_arch => 1, host_arch => 'i386');
 my $dep_alpha = deps_parse($field_arch, reduce_arch => 1, host_arch => 'alpha');
 my $dep_alpha = deps_parse($field_arch, reduce_arch => 1, host_arch => 'alpha');