Index | Thread | Search

From:
Marc Espie <marc.espie.openbsd@gmail.com>
Subject:
fix loop in pkg_add
To:
tech@openbsd.org
Date:
Wed, 24 Jun 2026 21:37:19 +0200

Download raw body.

Thread
  • Marc Espie:

    fix loop in pkg_add

It's not pretty, but at least it avoids the loop.

Suggestions for making it nicer welcome.


Index: Dependencies.pm
===================================================================
RCS file: /build/data/openbsd/cvs/src/usr.sbin/pkg_add/OpenBSD/Dependencies.pm,v
diff -u -p -r1.175 Dependencies.pm
--- Dependencies.pm	13 Jun 2023 09:07:17 -0000	1.175
+++ Dependencies.pm	24 Jun 2026 19:36:36 -0000
@@ -149,6 +149,7 @@ sub check_for_loops($self, $state)
 		}
 	}
 	if (@to_merge > 0) {
+		my $merge = 0;
 		my $merged = {};
 		my @real = ();
 		$state->say("Detected loop, merging sets #1", $state->ntogo);
@@ -156,6 +157,7 @@ sub check_for_loops($self, $state)
 		for my $set (@to_merge) {
 			my $k = $set;
 			while ($k ne $initial && !$merged->{$k}) {
+				$merge++;
 				unless ($k->{finished}) {
 					$state->say("| #1", $k->print);
 					delete $k->solver->{deplist};
@@ -168,8 +170,14 @@ sub check_for_loops($self, $state)
 		}
 		delete $initial->solver->{deplist};
 		delete $initial->solver->{to_register};
-		$initial->merge($state->tracker, @real);
+		if ($merge) {
+			$initial->merge($state->tracker, @real);
+			return 1;
+		} else {
+			return 0;
+		}
 	}
+	return 1;
 }
 
 sub find_dep_in_repositories($self, $state, $dep)
Index: PkgAdd.pm
===================================================================
RCS file: /build/data/openbsd/cvs/src/usr.sbin/pkg_add/OpenBSD/PkgAdd.pm,v
diff -u -p -r1.152 PkgAdd.pm
--- PkgAdd.pm	6 May 2025 18:36:20 -0000	1.152
+++ PkgAdd.pm	24 Jun 2026 19:17:15 -0000
@@ -953,8 +953,14 @@ sub process_set($self, $set, $state)
 	}
 	if (@deps > 0) {
 		$state->build_deptree($set, @deps);
-		$set->solver->check_for_loops($state);
-		return (@deps, $set);
+		if ($set->solver->check_for_loops($state)) {
+			return (@deps, $set);
+		} else {
+			$state->{bad}++;
+			$set->cleanup(OpenBSD::Handle::CANT_INSTALL);
+			$state->tracker->cant($set);
+			return ();
+		}
 	}
 
 	$set->figure_out_kept($state);