Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package nix for openSUSE:Factory checked in 
at 2026-08-14 22:07:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nix (Old)
 and      /work/SRC/openSUSE:Factory/.nix.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nix"

Fri Aug 14 22:07:04 2026 rev:22 rq:1371043 version:2.35.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/nix/nix.changes  2026-07-18 22:26:09.404443084 
+0200
+++ /work/SRC/openSUSE:Factory/.nix.new.1258/nix.changes        2026-08-14 
22:07:27.519048271 +0200
@@ -1,0 +2,19 @@
+Wed Aug 12 22:36:49 UTC 2026 - Marcus Rueckert <[email protected]>
+
+- Update to version 2.35.2:
+  - ae5195225 Revert "Drop old hacks for unachhored vtables and
+    exception handling"
+  - 40c627396 libstore: Actually check that hash part is followed
+    by a dash in StorePath
+  - b15a3d003 libutil-tests: Disable
+    sourceToSink.forcedUnwindUcaughtExceptions under ASan
+  - f8d28f3b8 Add boost.context patch for
+    std::uncaught_exceptions() misreporting 0 while abandoning the
+    coroutine
+  - 95cfc5da5 libutil-tests: Add test for sourceToSink
+    boost.context bug
+  - fba3f6e49 libstore: Fix lost waiting for slot goal wakeups
+  - fbd4c3f7e daemon: unlink worker's temproots file on exit
+  - 822e07028 libutil: Use O_PATH when opening parent dirFds
+
+-------------------------------------------------------------------

Old:
----
  nix-2.35.1.tar.gz

New:
----
  nix-2.35.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nix.spec ++++++
--- /var/tmp/diff_new_pack.4kEKTE/_old  2026-08-14 22:07:28.553085919 +0200
+++ /var/tmp/diff_new_pack.4kEKTE/_new  2026-08-14 22:07:28.554085955 +0200
@@ -26,7 +26,7 @@
 %bcond_with docs
 
 Name:           nix
-Version:        2.35.1
+Version:        2.35.2
 Release:        0
 Summary:        The purely functional package manager
 License:        LGPL-2.1-only

++++++ nix-2.35.1.tar.gz -> nix-2.35.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/.version new/nix-2.35.2/.version
--- old/nix-2.35.1/.version     2026-07-14 01:07:05.000000000 +0200
+++ new/nix-2.35.2/.version     2026-08-12 23:09:18.000000000 +0200
@@ -1 +1 @@
-2.35.1
+2.35.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/packaging/components.nix 
new/nix-2.35.2/packaging/components.nix
--- old/nix-2.35.1/packaging/components.nix     2026-07-14 01:07:05.000000000 
+0200
+++ new/nix-2.35.2/packaging/components.nix     2026-08-12 23:09:18.000000000 
+0200
@@ -139,6 +139,8 @@
             !(stdenv.hostPlatform.isWindows || stdenv.hostPlatform.isCygwin)
             # build failure
             && !stdenv.hostPlatform.isStatic
+            # LTO breaks exception handling on x86-64-darwin.
+            && stdenv.system != "x86_64-darwin"
           )
           ''
             case "$mesonBuildType" in
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/packaging/dependencies.nix 
new/nix-2.35.2/packaging/dependencies.nix
--- old/nix-2.35.1/packaging/dependencies.nix   2026-07-14 01:07:05.000000000 
+0200
+++ new/nix-2.35.2/packaging/dependencies.nix   2026-08-12 23:09:18.000000000 
+0200
@@ -98,6 +98,9 @@
         "--with-iostreams"
         "--with-url"
       ];
+      patches = [
+        
./patches/0001-Fix-uncaught_exceptions-not-accounting-for-forced_un.patch
+      ];
       enableIcu = false;
     }).overrideAttrs
       (old: {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.35.1/packaging/patches/0001-Fix-uncaught_exceptions-not-accounting-for-forced_un.patch
 
new/nix-2.35.2/packaging/patches/0001-Fix-uncaught_exceptions-not-accounting-for-forced_un.patch
--- 
old/nix-2.35.1/packaging/patches/0001-Fix-uncaught_exceptions-not-accounting-for-forced_un.patch
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/nix-2.35.2/packaging/patches/0001-Fix-uncaught_exceptions-not-accounting-for-forced_un.patch
    2026-08-12 23:09:18.000000000 +0200
@@ -0,0 +1,102 @@
+From 5883212311535a0046031d74d1568ae173c1e35b Mon Sep 17 00:00:00 2001
+From: Sergei Zimmerman <[email protected]>
+Date: Tue, 21 Jul 2026 21:15:51 +0000
+Subject: [PATCH] Fix uncaught_exceptions() not accounting for forced_unwind
+
+Unwound fibers would see std::uncaught_exceptions() == 0, while a
+forced_unwind exception is in "flight". This goes against the contract
+of std::uncaught_exceptions() that scope guards rely upon. Failing
+to report the correct number of uncaught exceptions (especially
+misreporting zero) will lead to scope guards to misbehave badly and skip
+running cleanup code which branches on whether the destructor is called
+during stack unwinding or not.
+
+This is because the "throw" would happen before the destructor is run on
+the fiber stack being switched to, but the increment would be clobbered
+by the destructor of manage_exception_state.
+
+I'm not sure what the contract of run ontop_fcontext is wrt to whether
+the the caller provided function can throw or not, but in my best
+understanding the forced_unwind mechanism is mostly internal and so is
+throwing from ontop_fcontext in the switched-to fiber. Thus, I've kept
+the catch block scoped to detail::forced_unwind.
+---
+ include/boost/context/fiber_fcontext.hpp | 37 +++++++++++++++++-------
+ test/test_fiber.cpp                      | 24 +++++++++++++++
+ 2 files changed, 51 insertions(+), 10 deletions(-)
+
+diff --git a/include/boost/context/fiber_fcontext.hpp 
b/include/boost/context/fiber_fcontext.hpp
+index 543ba6c..38476c9 100644
+--- a/boost/context/fiber_fcontext.hpp
++++ b/boost/context/fiber_fcontext.hpp
+@@ -70,7 +70,9 @@ namespace context {
+ namespace detail {
+ 
+ // manage_exception_state is a dummy struct unless we have specific support
+-struct manage_exception_state {};
++struct manage_exception_state {
++    void from_forced_unwind() noexcept {}
++};
+ 
+ } // namespace detail
+ } // namespace context
+@@ -90,6 +92,11 @@ public:
+     manage_exception_state() {
+         exception_state_ = *__cxa_get_globals();
+     }
++    // Hack to account for the forced_unwind exception thrown in fiber_unwind
++    // that's run ontop before the destructor.
++    void from_forced_unwind() noexcept {
++        exception_state_.uncaughtExceptions += 1;
++    }
+     ~manage_exception_state() {
+         *__cxa_get_globals() = exception_state_;
+     }
+@@ -376,13 +383,18 @@ public:
+         BOOST_ASSERT( nullptr != fctx_);
+         detail::manage_exception_state exstate;
+         boost::ignore_unused(exstate);
+-        return { detail::jump_fcontext(
++        try {
++            return { detail::jump_fcontext(
+ #if defined(BOOST_NO_CXX14_STD_EXCHANGE)
+-                    detail::exchange( fctx_, nullptr),
++                        detail::exchange( fctx_, nullptr),
+ #else
+-                    std::exchange( fctx_, nullptr),
++                        std::exchange( fctx_, nullptr),
+ #endif
+-                    nullptr).fctx };
++                        nullptr).fctx };
++        } catch ( detail::forced_unwind const& ) {
++            exstate.from_forced_unwind();
++            throw;
++        }
+     }
+ 
+     template< typename Fn >
+@@ -391,14 +403,19 @@ public:
+         detail::manage_exception_state exstate;
+         boost::ignore_unused(exstate);
+         auto p = std::forward< Fn >( fn);
+-        return { detail::ontop_fcontext(
++        try {
++            return { detail::ontop_fcontext(
+ #if defined(BOOST_NO_CXX14_STD_EXCHANGE)
+-                    detail::exchange( fctx_, nullptr),
++                        detail::exchange( fctx_, nullptr),
+ #else
+-                    std::exchange( fctx_, nullptr),
++                        std::exchange( fctx_, nullptr),
+ #endif
+-                    & p,
+-                    detail::fiber_ontop< fiber, decltype(p) >).fctx };
++                        & p,
++                        detail::fiber_ontop< fiber, decltype(p) >).fctx };
++        } catch ( detail::forced_unwind const& ) {
++            exstate.from_forced_unwind();
++            throw;
++        }
+     }
+ 
+     explicit operator bool() const noexcept {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/src/libstore/build/worker.cc 
new/nix-2.35.2/src/libstore/build/worker.cc
--- old/nix-2.35.1/src/libstore/build/worker.cc 2026-07-14 01:07:05.000000000 
+0200
+++ new/nix-2.35.2/src/libstore/build/worker.cc 2026-08-12 23:09:18.000000000 
+0200
@@ -249,19 +249,6 @@
     }
 
     children.erase(i);
-    auto & waiting = jobCategory == JobCategory::Substitution ? 
wantingToSubstitute : wantingToBuild;
-
-    /* Wake up goals waiting for a build slot. Wake at most one waiter to avoid
-       starting unnecessary work (that is accompanied by coroutine frame 
allocation). */
-    auto it = waiting.begin();
-    while (it != waiting.end()) {
-        if (auto goal = it->lock()) {
-            waiting.erase(it);
-            wakeUp(goal);
-            break;
-        }
-        it = waiting.erase(it);
-    }
 }
 
 void Worker::waitForBuildSlot(GoalPtr goal)
@@ -337,6 +324,22 @@
                 if (topGoals.empty())
                     break; // stuff may have been cancelled
             }
+
+            auto wakeSlotWaiters = [this](WeakGoals & waiting, size_t running, 
size_t limit) {
+                auto it = waiting.begin();
+                while (it != waiting.end() && running < limit) {
+                    auto goal = it->lock();
+                    it = waiting.erase(it);
+                    if (!goal)
+                        continue;
+                    wakeUp(goal);
+                    ++running;
+                }
+            };
+
+            wakeSlotWaiters(
+                wantingToSubstitute, getNrSubstitutions(), 
std::max<std::size_t>(1, settings.maxSubstitutionJobs));
+            wakeSlotWaiters(wantingToBuild, getNrLocalBuilds(), 
settings.maxBuildJobs);
         }
 
         if (topGoals.empty())
@@ -365,6 +368,7 @@
        --keep-going *is* set, then they must all be finished now. */
     assert(!settings.keepGoing || awake.empty());
     assert(!settings.keepGoing || wantingToBuild.empty());
+    assert(!settings.keepGoing || wantingToSubstitute.empty());
     assert(!settings.keepGoing || children.empty());
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nix-2.35.1/src/libstore/include/nix/store/build/worker.hh 
new/nix-2.35.2/src/libstore/include/nix/store/build/worker.hh
--- old/nix-2.35.1/src/libstore/include/nix/store/build/worker.hh       
2026-07-14 01:07:05.000000000 +0200
+++ new/nix-2.35.2/src/libstore/include/nix/store/build/worker.hh       
2026-08-12 23:09:18.000000000 +0200
@@ -326,8 +326,7 @@
         bool respectTimeouts);
 
     /**
-     * Unregisters a running child process. Wakes at most a single goal that is
-     * awaiting on the corresponding build slot type (building or 
substitution).
+     * Unregisters a running child process.
      *
      * This overload requires `goal` to point to a fully constructed,
      * valid goal object, as it calls `goal->jobCategory()`.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/src/libstore/path.cc 
new/nix-2.35.2/src/libstore/path.cc
--- old/nix-2.35.1/src/libstore/path.cc 2026-07-14 01:07:05.000000000 +0200
+++ new/nix-2.35.2/src/libstore/path.cc 2026-08-12 23:09:18.000000000 +0200
@@ -51,6 +51,8 @@
 {
     if (baseName.size() < HashLen + 1)
         throw BadStorePath("'%s' is too short to be a valid store path", 
baseName);
+    if (baseName[HashLen] != '-')
+        throw BadStorePath("'%s' can't name a store path because the hash part 
is not followed by a '-'", baseName);
     for (auto c : hashPart())
         if (c == 'e' || c == 'o' || c == 'u' || c == 't' || !((c >= '0' && c 
<= '9') || (c >= 'a' && c <= 'z')))
             throw BadStorePath("store path '%s' contains illegal base-32 
character '%s'", baseName, c);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/src/libstore-tests/path.cc 
new/nix-2.35.2/src/libstore-tests/path.cc
--- old/nix-2.35.1/src/libstore-tests/path.cc   2026-07-14 01:07:05.000000000 
+0200
+++ new/nix-2.35.2/src/libstore-tests/path.cc   2026-08-12 23:09:18.000000000 
+0200
@@ -139,6 +139,15 @@
     RC_ASSERT(parsed == std::regex_match(std::string{name}, nameRegex));
 }
 
+TEST_F(StorePathTest, mustBeDashAfterHashPart)
+{
+    std::string hashPart = "575s52sh487i0ylmbs9pvi606ljdszr0";
+    for (char c : {'_', '\0'}) {
+        EXPECT_THROW(StorePath(hashPart + c + "name"), BadStorePath);
+    }
+    EXPECT_NO_THROW(StorePath(hashPart + "-" + "name"));
+}
+
 /* ----------------------------------------------------------------------------
  * JSON
  * --------------------------------------------------------------------------*/
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/src/libutil/meson.build 
new/nix-2.35.2/src/libutil/meson.build
--- old/nix-2.35.1/src/libutil/meson.build      2026-07-14 01:07:05.000000000 
+0200
+++ new/nix-2.35.2/src/libutil/meson.build      2026-08-12 23:09:18.000000000 
+0200
@@ -44,6 +44,12 @@
   description : 'Whether nix has been built with UBSan enabled',
 )
 
+configdata_pub.set(
+  'NIX_ASAN_ENABLED',
+  ('address' in get_option('b_sanitize')).to_int(),
+  description : 'Whether nix has been built with ASan enabled',
+)
+
 subdir('nix-meson-build-support/libatomic')
 
 if host_machine.system() == 'windows'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/src/libutil/posix-source-accessor.cc 
new/nix-2.35.2/src/libutil/posix-source-accessor.cc
--- old/nix-2.35.1/src/libutil/posix-source-accessor.cc 2026-07-14 
01:07:05.000000000 +0200
+++ new/nix-2.35.2/src/libutil/posix-source-accessor.cc 2026-08-12 
23:09:18.000000000 +0200
@@ -383,8 +383,20 @@
     }
 
     try {
-        AutoCloseFD parentFdOwning =
-            openFileEnsureBeneathNoSymlinks(startFd, relPath, O_DIRECTORY | 
O_RDONLY | O_CLOEXEC, 0, std::move(cb));
+        AutoCloseFD parentFdOwning = openFileEnsureBeneathNoSymlinks(
+            startFd,
+            relPath,
+#  ifdef O_PATH
+            /* As to not require read permissions on the directory. */
+            O_PATH |
+#  else
+            /* Sadly this will require read permissison for path resolution,
+               but without O_PATH that's unavoidable. */
+            O_RDONLY |
+#  endif
+                O_DIRECTORY | O_CLOEXEC,
+            0,
+            std::move(cb));
         return {parentFdOwning.get(), 
make_ref<AutoCloseFD>(std::move(parentFdOwning))};
     } catch (SymlinkNotAllowed & e) {
         /* Need to fixup the error message to include the actual path relative 
to the (possibly) cached fd. */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/src/libutil-tests/serialise.cc 
new/nix-2.35.2/src/libutil-tests/serialise.cc
--- old/nix-2.35.1/src/libutil-tests/serialise.cc       2026-07-14 
01:07:05.000000000 +0200
+++ new/nix-2.35.2/src/libutil-tests/serialise.cc       2026-08-12 
23:09:18.000000000 +0200
@@ -1,5 +1,7 @@
 #include "nix/util/serialise.hh"
+#include "nix/util/config.hh"
 
+#include <boost/context/detail/exception.hpp>
 #include <gtest/gtest.h>
 
 namespace nix {
@@ -37,4 +39,43 @@
     }
 }
 
+// The following test catches the bug only under fcontext backend,
+// but Boost.Coroutine2 stack switching when abandoning confuses the
+// hell out of ASan. The workaround to getting ASan working isn't
+// immediately useful because it works only with ucontext implementation.
+// 
https://www.boost.org/doc/libs/1_89_0/libs/coroutine2/doc/html/coroutine2/stack/sanitizers.html
+#if !NIX_ASAN_ENABLED
+
+TEST(sourceToSink, forcedUnwindUcaughtExceptions)
+{
+    int uncaughtExceptions = 42;
+    bool caught = false;
+
+    auto sink = sourceToSink([&](Source & source) {
+        auto recordUncaughtExceptions = Finally([&]() { uncaughtExceptions = 
std::uncaught_exceptions(); });
+        try {
+            StringSink s;
+            source.drainInto(s, 8);
+            source.drainInto(s, 8);
+        } catch (const boost::context::detail::forced_unwind &) {
+            caught = true;
+            throw;
+        }
+    });
+
+    *sink << 42;
+
+    // Abandon the coroutine. This will trigger it to unwind with 
boost::context::detail::forced_unwind.
+    sink.reset();
+
+    ASSERT_TRUE(caught);
+    // This is a test for boost.context regression fixed by 
https://github.com/boostorg/context/pull/337.
+    // Without the fix std::uncaught_exceptions() *misreports* 0 while there's 
stack unwinding in progress.
+    // The issue only surfaces with libstdc++ and fcontext when boost.context
+    // uses fiber-specific exception states and messes with 
__cxa_get_globals().
+    ASSERT_EQ(uncaughtExceptions, 1);
+}
+
+#endif
+
 } // namespace nix
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/src/nix/unix/daemon.cc 
new/nix-2.35.2/src/nix/unix/daemon.cc
--- old/nix-2.35.1/src/nix/unix/daemon.cc       2026-07-14 01:07:05.000000000 
+0200
+++ new/nix-2.35.2/src/nix/unix/daemon.cc       2026-08-12 23:09:18.000000000 
+0200
@@ -375,7 +375,12 @@
                         // Handle the connection.
                         auto store = storeConfig->openStore();
                         store->init();
-                        processConnection(store, FdSource(remote.get()), 
FdSink(remote.get()), trusted, NotRecursive);
+                        processConnection(
+                            std::move(store),
+                            FdSource(remote.get()),
+                            FdSink(remote.get()),
+                            trusted,
+                            RecursiveFlag::NotRecursive);
 
                         exit(0);
                     },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nix-2.35.1/tests/nixos/functional/symlinked-home.nix 
new/nix-2.35.2/tests/nixos/functional/symlinked-home.nix
--- old/nix-2.35.1/tests/nixos/functional/symlinked-home.nix    2026-07-14 
01:07:05.000000000 +0200
+++ new/nix-2.35.2/tests/nixos/functional/symlinked-home.nix    2026-08-12 
23:09:18.000000000 +0200
@@ -1,9 +1,11 @@
 /**
   This test runs the functional tests on a NixOS system where the home 
directory
-  is symlinked to another location.
+  is symlinked to another location that also happens to reside in parent 
directory
+  that we don't have read permissions for (only execute).
 
   The purpose of this test is to find cases where Nix uses low-level operations
-  that don't support symlinks on paths that include them.
+  that don't support symlinks on paths that include them or requires excessive
+  permissions for path resolution.
 
   It is not a substitute for more intricate, use case-specific tests, but helps
   catch common issues.
@@ -27,8 +29,12 @@
       machine.succeed("""
         (
           set -x
-          mv /home/alice /home/alice.real
-          ln -s alice.real /home/alice
+          mkdir -p /home/alice.parent
+          chown alice:users /home/alice.parent
+          # Make the parent unreadable for good measure
+          chmod 0110 /home/alice.parent
+          mv /home/alice /home/alice.parent/alice.real
+          ln -s alice.parent/alice.real /home/alice
         ) 1>&2
       """)
     machine.succeed("""

Reply via email to