Raphaël Hertzog 16 rokov pred
rodič
commit
9ba415de26

+ 7 - 0
debian/changelog

@@ -11,6 +11,13 @@ dpkg (1.15.9) UNRELEASED; urgency=low
 
  -- Guillem Jover <guillem@debian.org>  Thu, 29 Jul 2010 11:00:22 +0200
 
+dpkg (1.15.8.1) unstable; urgency=low
+
+  * Fix off-by-one error in update-alternatives that lead to an infinite loop
+    while writing the administrative file. Closes: #590854
+
+ -- Raphaël Hertzog <hertzog@debian.org>  Thu, 29 Jul 2010 21:18:16 +0200
+
 dpkg (1.15.8) unstable; urgency=low
 
   [ Raphaël Hertzog ]

+ 52 - 2
utils/t/100_update_alternatives.t

@@ -45,11 +45,21 @@ my @choices = (
 		name => "slave2",
 		path => "/bin/cat",
 	    },
+	    {
+		"link" => "$bindir/slave3",
+		name => "slave3",
+		path => "/bin/cat",
+	    },
 	    {
 		"link" => "$bindir/slave1",
 		name => "slave1",
 		path => "/usr/bin/yes",
 	    },
+	    {
+		"link" => "$bindir/slave4",
+		name => "slave4",
+		path => "/bin/cat",
+	    },
 	],
     },
     {
@@ -69,9 +79,9 @@ my @choices = (
         slaves => [],
     },
 );
-my $nb_slaves = 2;
+my $nb_slaves = 4;
 plan tests => (4 * ($nb_slaves + 1) + 2) * 24 # number of check_choices
-		+ 64;			      # rest
+		+ 65;			      # rest
 
 sub cleanup {
     system("rm -rf $tmpdir && mkdir -p $admindir && mkdir -p $altdir");
@@ -220,6 +230,46 @@ check_choice(1, "auto", "initial install 2");
 install_choice(0); # 0 is higher priority
 check_choice(0, "auto", "initial install 3");
 
+# verify that the administrative file is sorted properly
+{
+    local $/ = undef;
+    open(FILE, "<", "$admindir/generic-test") or die $!;
+    my $content = <FILE>;
+    close(FILE);
+    is($content,
+"auto
+$bindir/generic-test
+slave1
+$bindir/slave1
+slave2
+$bindir/slave2
+slave3
+$bindir/slave3
+slave4
+$bindir/slave4
+
+/bin/false
+10
+/bin/date
+
+
+
+/bin/sleep
+5
+
+
+
+
+/bin/true
+20
+/usr/bin/yes
+/bin/cat
+/bin/cat
+/bin/cat
+
+", "administrative file is as expected");
+}
+
 # manual change with --set-selections
 my $input = "doesntexist auto /bin/date\ngeneric-test manual /bin/false\n";
 my $output = "";

+ 2 - 4
utils/update-alternatives.c

@@ -772,10 +772,8 @@ alternative_sort_choices(struct alternative *a)
 	/* Rewrite the linked list from the sorted table */
 	a->choices = fs = table[0];
 	table[count - 1]->next = NULL;
-	for (i = 1; i < count - 1; i++) {
+	for (i = 1; i < count; fs = fs->next, i++)
 		fs->next = table[i];
-		fs = fs->next;
-	}
 	free(table);
 }
 
@@ -800,7 +798,7 @@ alternative_sort_slaves(struct alternative *a)
 	/* Rewrite the linked list from the sorted table */
 	a->slaves = sl = table[0];
 	table[count - 1]->next = NULL;
-	for (i = 1; i < count - 1; sl = sl->next, i++)
+	for (i = 1; i < count; sl = sl->next, i++)
 		sl->next = table[i];
 	free(table);
 }