Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package libxmlb for openSUSE:Factory checked 
in at 2026-08-01 18:27:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libxmlb (Old)
 and      /work/SRC/openSUSE:Factory/.libxmlb.new.16738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libxmlb"

Sat Aug  1 18:27:24 2026 rev:23 rq:1368367 version:0.3.29

Changes:
--------
--- /work/SRC/openSUSE:Factory/libxmlb/libxmlb.changes  2026-05-24 
19:34:14.683818215 +0200
+++ /work/SRC/openSUSE:Factory/.libxmlb.new.16738/libxmlb.changes       
2026-08-01 18:27:47.296644785 +0200
@@ -1,0 +2,22 @@
+Tue Jul 28 08:15:35 UTC 2026 - Bjørn Lie <[email protected]>
+
+- Update to version 0.3.29:
+  + Bugfixes:
+    - Avoid stale query indexes when reloading the silo
+    - Clear the query cache when reloading the silo
+    - Correctly mark the silo as invalid when re-loading malformed
+      data
+    - Fix building the silo when shared-mime-info is installed
+- Changes from version 0.3.28:
+  + New Features:
+    - Automatically add system locales when using native-langs
+    - Lower the Meson and GLib deps for RHEL-8
+  + Bugfixes:
+    - Lazy clear opcode tokens for a ~2% speedup
+    - Speed up negative queries by 11% by defer creating the
+      results objects
+    - Speed up predicates with no bindings by 9%
+    - Speed up the no-results query by 2.5% by using a constant
+      error
+
+-------------------------------------------------------------------

Old:
----
  libxmlb-0.3.27.tar.gz

New:
----
  libxmlb-0.3.29.tar.gz

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

Other differences:
------------------
++++++ libxmlb.spec ++++++
--- /var/tmp/diff_new_pack.sHm6jy/_old  2026-08-01 18:27:48.152673827 +0200
+++ /var/tmp/diff_new_pack.sHm6jy/_new  2026-08-01 18:27:48.160674098 +0200
@@ -19,7 +19,7 @@
 
 %define sover 2
 Name:           libxmlb
-Version:        0.3.27
+Version:        0.3.29
 Release:        0
 Summary:        Library for querying compressed XML metadata
 License:        LGPL-2.1-or-later

++++++ libxmlb-0.3.27.tar.gz -> libxmlb-0.3.29.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/.github/workflows/main.yml 
new/libxmlb-0.3.29/.github/workflows/main.yml
--- old/libxmlb-0.3.27/.github/workflows/main.yml       2026-05-18 
17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/.github/workflows/main.yml       2026-07-27 
17:01:51.000000000 +0200
@@ -20,6 +20,6 @@
           - debian
       fail-fast: false
     steps:
-      - uses: actions/[email protected]
+      - uses: actions/[email protected]
       - run: docker build -t libxmlb-${{ matrix.distro }} -f 
contrib/ci/Dockerfile-${{ matrix.distro }} .
       - run: docker run -t -v `pwd`:/build libxmlb-${{ matrix.distro }} 
./contrib/ci/build-${{ matrix.distro }}.sh
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/.github/workflows/scorecard.yml 
new/libxmlb-0.3.29/.github/workflows/scorecard.yml
--- old/libxmlb-0.3.27/.github/workflows/scorecard.yml  2026-05-18 
17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/.github/workflows/scorecard.yml  2026-07-27 
17:01:51.000000000 +0200
@@ -32,12 +32,12 @@
 
     steps:
       - name: "Checkout code"
-        uses: actions/checkout@0c366fd6a839edf440554fa01a7085ccba70ac98 # 
v4.1.1
+        uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # 
v4.1.1
         with:
           persist-credentials: false
 
       - name: "Run analysis"
-        uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # 
v2.4.3
+        uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # 
v2.4.4
         with:
           results_file: results.sarif
           results_format: sarif
@@ -68,6 +68,6 @@
       # Upload the results to GitHub's code scanning dashboard (optional).
       # Commenting out will disable upload of results to your repo's Code 
Scanning dashboard
       - name: "Upload to code-scanning"
-        uses: 
github/codeql-action/upload-sarif@68bde559dea0fdcac2102bfdf6230c5f70eb485e # 
v3.29.5
+        uses: 
github/codeql-action/upload-sarif@e4fba868fa4b1b91e1fdab776edc8cfbe6e9fb81 # 
v3.29.5
         with:
           sarif_file: results.sarif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/NEWS new/libxmlb-0.3.29/NEWS
--- old/libxmlb-0.3.27/NEWS     2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/NEWS     2026-07-27 17:01:51.000000000 +0200
@@ -1,3 +1,28 @@
+Version 0.3.29
+~~~~~~~~~~~~~~
+Released: 2026-07-27
+
+New Features:
+Bugfixes:
+ - Avoid stale query indexes when reloading the silo (Richard Hughes)
+ - Clear the query cache when reloading the silo (Richard Hughes)
+ - Correctly mark the silo as invalid when re-loading malformed data (Richard 
Hughes)
+ - Fix building the silo when shared-mime-info is installed (Richard Hughes)
+
+Version 0.3.28
+~~~~~~~~~~~~~~
+Released: 2026-06-30
+
+New Features:
+ - Automatically add system locales when using native-langs (Richard Hughes)
+ - Lower the Meson and GLib deps for RHEL-8 (Richard Hughes)
+
+Bugfixes:
+ - Lazy clear opcode tokens for a ~2% speedup (Richard Hughes)
+ - Speed up negative queries by 11% by defer creating the results objects 
(Richard Hughes)
+ - Speed up predicates with no bindings by 9% (Richard Hughes)
+ - Speed up the no-results query by 2.5% by using a constant error (Richard 
Hughes)
+
 Version 0.3.27
 ~~~~~~~~~~~~~~
 Released: 2026-05-18
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/RELEASE new/libxmlb-0.3.29/RELEASE
--- old/libxmlb-0.3.27/RELEASE  2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/RELEASE  2026-07-27 17:01:51.000000000 +0200
@@ -2,9 +2,9 @@
 
 1. Write NEWS entries for libxmlb in the same format as usual.
 
-git shortlog 0.3.26.. | grep -i -v trivial | grep -v Merge > NEWS.new
+git shortlog 0.3.28.. | grep -i -v trivial | grep -v Merge > NEWS.new
 
-Version 0.3.27
+Version 0.3.29
 ~~~~~~~~~~~~~~
 Released: 2026-xx-xx
 
@@ -15,7 +15,7 @@
 Commit changes to git:
 
 # MAKE SURE THESE ARE CORRECT
-export release_ver="0.3.27"
+export release_ver="0.3.29"
 
 git commit -a -m "Release libxmlb ${release_ver}" --no-verify
 git tag -s -f -m "Release libxmlb ${release_ver}" "${release_ver}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/SECURITY.md 
new/libxmlb-0.3.29/SECURITY.md
--- old/libxmlb-0.3.27/SECURITY.md      2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/SECURITY.md      2026-07-27 17:01:51.000000000 +0200
@@ -10,4 +10,35 @@
 
 ## Reporting a Vulnerability
 
-We have enabled private reporting in GitHub, so please [follow these 
steps](https://github.com/hughsie/libxmlb/security) to report vulnerabilities.
+If you find a vulnerability in libxmlb you should let us know using a
+[private vulnerability 
disclosure](https://github.com/hughsie/libxmlb/security/advisories/new) on
+GitHub, with a description of the issue, the steps you took to create the 
issue, affected
+versions, and, if known, mitigations for the issue.
+
+Failing that, please report the issue against the `libxmlb` component in Red 
Hat bugzilla, with the
+security checkbox set. You should get a response within 3 days. We have no bug 
bounty program, but
+we're happy to credit you in updates if this is what you would like us to do.
+
+Security bugs found or assisted by AI tools must also include two additional 
things:
+
+* A reproducer that clearly shows the vulnerability on an unmodified `xb-tool` 
binary that is
+  running with all the usual OS level protections.
+
+* A pull requests that fixes the security vulnerability and adds unit tests; 
the logic being that
+  if you're using an autonomous system to find a theoretical issue you should 
also have the common
+  courtesy to submit a PR that fixes the vulnerability.
+
+Any security issue with the premise of “an attacker can supply a crafted xmlb 
file” will be closed.
+The `.xmlb` binary file is an internal-ABI **trusted** memory-mapped blob -- 
it is not a loadable
+file format and cannot be used like that. No libxmlb user is shipping 
pre-compiled `.xmlb` blobs to
+end users, and due to the implementation of the silo GUID it would be 
impossible to do so.
+
+Additionally, we will not issue CVEs or GHSA IDs for AI-discovered security 
issues lower than
+moderate -- doing so offers nothing to the libxmlb community (anyone can use 
similar tools to find
+the same issue) and adds a huge burden on the existing maintenance team.
+
+The CVSS scoring of reported bugs is often wildly inflated by AI tools (for 
various reasons), and
+the actual CVSS scoring may be modified at the libxmlb maintainers discretion.
+
+So-called "low severity" security bugs or "hardening enhancements" will be 
treated as normal issues
+and will be fixed as part of the next tarball release with no coordinated 
disclosure process.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/contrib/libxmlb.spec.in 
new/libxmlb-0.3.29/contrib/libxmlb.spec.in
--- old/libxmlb-0.3.27/contrib/libxmlb.spec.in  2026-05-18 17:44:22.000000000 
+0200
+++ new/libxmlb-0.3.29/contrib/libxmlb.spec.in  2026-07-27 17:01:51.000000000 
+0200
@@ -1,6 +1,4 @@
-%bcond stemmer %{defined fedora}
-
-%global glib2_version 2.45.8
+%global glib2_version 2.56.0
 
 %define alphatag                #ALPHATAG#
 
@@ -14,7 +12,7 @@
 
 BuildRequires: glib2-devel >= %{glib2_version}
 BuildRequires: gtk-doc
-%if %{with stemmer}
+%if 0%{?fedora}
 BuildRequires: libstemmer-devel
 %endif
 BuildRequires: meson
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/meson.build 
new/libxmlb-0.3.29/meson.build
--- old/libxmlb-0.3.27/meson.build      2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/meson.build      2026-07-27 17:01:51.000000000 +0200
@@ -1,7 +1,7 @@
 project('libxmlb', 'c',
-  version : '0.3.27',
+  version : '0.3.29',
   license : 'LGPL-2.1-or-later',
-  meson_version : '>=0.60.0',
+  meson_version : '>=0.58.2',
   default_options : ['warning_level=2', 'c_std=c99'],
 )
 
@@ -129,7 +129,7 @@
 endif
 mandir = join_paths(prefix, get_option('mandir'))
 
-gio = dependency('gio-2.0', version : '>= 2.68.0')
+gio = dependency('gio-2.0', version : '>= 2.56.0')
 giounix = dependency('gio-unix-2.0', required: false)
 lzma = dependency('liblzma', required: get_option('lzma'))
 if lzma.found()
@@ -143,12 +143,6 @@
   conf.set('HAVE_GIO_UNIX', '1')
 endif
 
-# Limit our use of GLib API to our minimum version requirement, and what’s
-# available in RHEL 9. Use of more modern API has to be optional and
-# protected by GLIB_CHECK_VERSION.
-add_project_arguments('-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_46', 
language: 'c')
-add_project_arguments('-DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_68', 
language: 'c')
-
 libxmlb_deps = [
   gio,
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/meson_options.txt 
new/libxmlb-0.3.29/meson_options.txt
--- old/libxmlb-0.3.27/meson_options.txt        2026-05-18 17:44:22.000000000 
+0200
+++ new/libxmlb-0.3.29/meson_options.txt        2026-07-27 17:01:51.000000000 
+0200
@@ -10,8 +10,4 @@
 option('zstd',
   type: 'feature',
   description: 'enable zstd support',
-  deprecated: {
-    'true': 'enabled',
-    'false': 'disabled',
-  },
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/meson.build 
new/libxmlb-0.3.29/src/meson.build
--- old/libxmlb-0.3.27/src/meson.build  2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/meson.build  2026-07-27 17:01:51.000000000 +0200
@@ -6,7 +6,7 @@
 
 install_headers(
   'xmlb.h',
-  subdir : 'libxmlb-2',
+  subdir : 'libxmlb-@0@'.format(lt_current),
 )
 
 xb_headers = files(
@@ -16,6 +16,7 @@
   'xb-builder-source.h',
   'xb-builder-source-ctx.h',
   'xb-compile.h',
+  'xb-compile-glib-2-62.h',
   'xb-machine.h',
   'xb-node.h',
   'xb-node-query.h',
@@ -33,7 +34,7 @@
 
 install_headers(
   xb_headers,
-  subdir : 'libxmlb-2/libxmlb',
+  subdir : 'libxmlb-@0@/libxmlb'.format(lt_current),
 )
 
 subdir('libxmlb')
@@ -138,7 +139,7 @@
 pkgg = import('pkgconfig')
 pkgg.generate(libxmlb,
   requires : [ 'gio-2.0' ],
-  subdirs : 'libxmlb-2',
+  subdirs : 'libxmlb-@0@'.format(lt_current),
   version : meson.project_version(),
   name : 'libxmlb',
   filebase : 'xmlb',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-builder-source-ctx.c 
new/libxmlb-0.3.29/src/xb-builder-source-ctx.c
--- old/libxmlb-0.3.27/src/xb-builder-source-ctx.c      2026-05-18 
17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/xb-builder-source-ctx.c      2026-07-27 
17:01:51.000000000 +0200
@@ -70,9 +70,9 @@
                        g_set_error(error,
                                    G_IO_ERROR,
                                    G_IO_ERROR_FAILED,
-                                   "cannot read from fd: 0x%x > 0x%x",
+                                   "cannot read from fd: 0x%x > 0x%zx",
                                    buf->len,
-                                   (guint)count);
+                                   count);
                        return NULL;
                }
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-builder-source.c 
new/libxmlb-0.3.29/src/xb-builder-source.c
--- old/libxmlb-0.3.27/src/xb-builder-source.c  2026-05-18 17:44:22.000000000 
+0200
+++ new/libxmlb-0.3.29/src/xb-builder-source.c  2026-07-27 17:01:51.000000000 
+0200
@@ -469,7 +469,7 @@
                g_debug("detected content type of %s to be %s", basename, 
content_type);
                if (content_type == NULL)
                        return NULL;
-               if (g_strcmp0(content_type, "application/xml") == 0)
+               if (g_content_type_is_a(content_type, "application/xml"))
                        break;
                /* Also accept the text/xml alias, just in case the user’s 
content-type database is
                 * slightly broken (application/xml should normally be what’s 
used): */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-builder.c 
new/libxmlb-0.3.29/src/xb-builder.c
--- old/libxmlb-0.3.27/src/xb-builder.c 2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/xb-builder.c 2026-07-27 17:01:51.000000000 +0200
@@ -869,11 +869,9 @@
 
        /* the builder needs to know the locales */
        if (priv->locales->len == 0 && (flags & 
XB_BUILDER_COMPILE_FLAG_NATIVE_LANGS)) {
-               g_set_error_literal(error,
-                                   G_IO_ERROR,
-                                   G_IO_ERROR_INVALID_DATA,
-                                   "No locales set and using NATIVE_LANGS");
-               return NULL;
+               const gchar *const *locales = g_get_language_names();
+               for (guint i = 0; locales[i] != NULL; i++)
+                       xb_builder_add_locale(self, locales[i]);
        }
 
        /* create helper used for compiling */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-compile-glib-2-62.h 
new/libxmlb-0.3.29/src/xb-compile-glib-2-62.h
--- old/libxmlb-0.3.27/src/xb-compile-glib-2-62.h       1970-01-01 
01:00:00.000000000 +0100
+++ new/libxmlb-0.3.29/src/xb-compile-glib-2-62.h       2026-07-27 
17:01:51.000000000 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2026 Richard Hughes <[email protected]>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#pragma once
+
+#include <glib.h>
+
+typedef void GRWLockReaderLocker;
+
+static inline GRWLockReaderLocker *
+g_rw_lock_reader_locker_new(GRWLock *rw_lock)
+{
+       g_rw_lock_reader_lock(rw_lock);
+       return (GRWLockReaderLocker *)rw_lock;
+}
+
+static inline void
+g_rw_lock_reader_locker_free(GRWLockReaderLocker *locker)
+{
+       g_rw_lock_reader_unlock((GRWLock *)locker);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GRWLockReaderLocker, 
g_rw_lock_reader_locker_free)
+
+typedef void GRWLockWriterLocker;
+
+static inline GRWLockWriterLocker *
+g_rw_lock_writer_locker_new(GRWLock *rw_lock)
+{
+       g_rw_lock_writer_lock(rw_lock);
+       return (GRWLockWriterLocker *)rw_lock;
+}
+
+static inline void
+g_rw_lock_writer_locker_free(GRWLockWriterLocker *locker)
+{
+       g_rw_lock_writer_unlock((GRWLock *)locker);
+}
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GRWLockWriterLocker, 
g_rw_lock_writer_locker_free)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-compile.h 
new/libxmlb-0.3.29/src/xb-compile.h
--- old/libxmlb-0.3.27/src/xb-compile.h 2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/xb-compile.h 2026-07-27 17:01:51.000000000 +0200
@@ -16,3 +16,7 @@
 #define G_GNUC_NON_NULL(params...)
 #endif
 #endif
+
+#if !GLIB_CHECK_VERSION(2, 62, 0)
+#include "xb-compile-glib-2-62.h"
+#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-machine.c 
new/libxmlb-0.3.29/src/xb-machine.c
--- old/libxmlb-0.3.27/src/xb-machine.c 2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/xb-machine.c 2026-07-27 17:01:51.000000000 +0200
@@ -1011,7 +1011,7 @@
                                         kind == 
XB_OPCODE_KIND_BOUND_INDEXED_TEXT ||
                                         kind == XB_OPCODE_KIND_BOUND_INTEGER)) 
{
                        XbOpcode *machine_opcode;
-                       if (!xb_machine_stack_push(self, stack, 
&machine_opcode, error))
+                       if (!xb_stack_push(stack, &machine_opcode, error))
                                return FALSE;
                        if (!xb_value_bindings_lookup_opcode(bindings,
                                                             bound_opcode_idx++,
@@ -1061,7 +1061,7 @@
                                          kind == 
XB_OPCODE_KIND_BOUND_INDEXED_TEXT ||
                                          kind == 
XB_OPCODE_KIND_BOUND_INTEGER))) {
                        XbOpcode *machine_opcode;
-                       if (!xb_machine_stack_push(self, stack, 
&machine_opcode, error))
+                       if (!xb_stack_push(stack, &machine_opcode, error))
                                return FALSE;
                        *machine_opcode = *opcode;
                        machine_opcode->destroy_func = NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-opcode.c 
new/libxmlb-0.3.29/src/xb-opcode.c
--- old/libxmlb-0.3.27/src/xb-opcode.c  2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/xb-opcode.c  2026-07-27 17:01:51.000000000 +0200
@@ -357,7 +357,7 @@
        self->val = val;
        self->tokens_len = 0;
        self->destroy_func = destroy_func;
-       memset(self->tokens, 0, sizeof(self->tokens));
+       self->tokens[0] = NULL;
 }
 
 /**
@@ -466,6 +466,7 @@
        if (self->tokens_len >= XB_OPCODE_TOKEN_MAX)
                return FALSE;
        self->tokens[self->tokens_len++] = val;
+       self->tokens[self->tokens_len] = NULL;
        self->kind |= XB_OPCODE_FLAG_TOKENIZED;
        return TRUE;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-self-test.c 
new/libxmlb-0.3.29/src/xb-self-test.c
--- old/libxmlb-0.3.27/src/xb-self-test.c       2026-05-18 17:44:22.000000000 
+0200
+++ new/libxmlb-0.3.29/src/xb-self-test.c       2026-07-27 17:01:51.000000000 
+0200
@@ -2065,22 +2065,18 @@
 static void
 xb_builder_strtab_ntags_limit_func(void)
 {
-       gboolean ret;
        g_autoptr(GError) error = NULL;
-       g_autoptr(GString) xml = g_string_new("<root>");
        g_autoptr(XbBuilder) builder = xb_builder_new();
-       g_autoptr(XbBuilderSource) source = xb_builder_source_new();
+       g_autoptr(XbBuilderNode) root = xb_builder_node_new("root");
        g_autoptr(XbSilo) silo = NULL;
 
-       /* generate XML with more than 65535 unique element names */
-       for (guint i = 0; i <= G_MAXUINT16; i++)
-               g_string_append_printf(xml, "<e%u/>", i);
-       g_string_append(xml, "</root>");
+       /* build a node tree with more than 65535 unique element names */
+       for (guint i = 0; i <= G_MAXUINT16; i++) {
+               g_autofree gchar *name = g_strdup_printf("e%u", i);
+               xb_builder_node_insert_text(root, name, NULL, NULL);
+       }
 
-       ret = xb_builder_source_load_xml(source, xml->str, 
XB_BUILDER_SOURCE_FLAG_NONE, &error);
-       g_assert_no_error(error);
-       g_assert_true(ret);
-       xb_builder_import_source(builder, source);
+       xb_builder_import_node(builder, root);
        silo = xb_builder_compile(builder, XB_BUILDER_COMPILE_FLAG_NONE, NULL, 
&error);
        g_assert_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
        g_assert_null(silo);
@@ -2345,23 +2341,6 @@
 }
 
 static void
-xb_builder_native_lang_no_locales_func(void)
-{
-       gboolean ret;
-       g_autoptr(GError) error = NULL;
-       g_autoptr(XbBuilder) builder = xb_builder_new();
-       g_autoptr(XbSilo) silo = NULL;
-
-       /* import from XML */
-       ret = xb_test_import_xml(builder, "<id>gimp.desktop</id>", &error);
-       g_assert_no_error(error);
-       g_assert_true(ret);
-       silo = xb_builder_compile(builder, XB_BUILDER_COMPILE_FLAG_SINGLE_LANG, 
NULL, &error);
-       g_assert_error(error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
-       g_assert_null(silo);
-}
-
-static void
 xb_xpath_parent_func(void)
 {
        XbNode *n;
@@ -3301,6 +3280,52 @@
        g_print("query[x%u]: %.3fms\n", n_components, g_timer_elapsed(timer, 
NULL) * 1000);
 }
 
+static void
+xb_speed_precompiled_func(void)
+{
+       guint n_components = 5000;
+       g_autoptr(GError) error = NULL;
+       g_autoptr(GString) xml = g_string_new(NULL);
+       g_autoptr(GTimer) timer = g_timer_new();
+       g_autoptr(XbSilo) silo = NULL;
+       g_autoptr(XbQuery) query = NULL;
+
+#ifdef __s390x__
+       g_test_skip("s390 too slow, skipping");
+       return;
+#endif
+
+       /* create a huge document */
+       g_string_append(xml, "<components>");
+       for (guint i = 0; i < n_components; i++) {
+               g_string_append(xml, "<component type=\"firmware\">");
+               g_string_append_printf(xml, "  <id>%06u.firmware</id>", i);
+               g_string_append(xml, "  <name>ColorHug2</name>");
+               g_string_append(xml, "  <summary>Firmware</summary>");
+               g_string_append(xml, "</component>");
+       }
+       g_string_append(xml, "</components>");
+
+       silo = xb_silo_new_from_xml(xml->str, &error);
+       g_assert_no_error(error);
+       g_assert_nonnull(silo);
+
+       query = xb_query_new(silo, "components/component[@type='firmware']", 
&error);
+       g_assert_no_error(error);
+       g_assert_nonnull(query);
+
+       g_timer_reset(timer);
+       for (guint i = 0; i < n_components; i += 20) {
+               g_autoptr(GPtrArray) results = NULL;
+               results = xb_silo_query_full(silo, query, &error);
+               g_assert_no_error(error);
+               g_assert_nonnull(results);
+               if (i == 0)
+                       g_assert_cmpint(results->len, ==, n_components);
+       }
+       g_print("query_full[x%u]: %.3fms\n", n_components, 
g_timer_elapsed(timer, NULL) * 1000);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -3332,8 +3357,6 @@
        g_test_add_func("/libxmlb/builder{cdata}", xb_builder_cdata_func);
        g_test_add_func("/libxmlb/builder{native-lang}", 
xb_builder_native_lang_func);
        g_test_add_func("/libxmlb/builder{native-lang-nested}", 
xb_builder_native_lang2_func);
-       g_test_add_func("/libxmlb/builder{native-lang-locale}",
-                       xb_builder_native_lang_no_locales_func);
        g_test_add_func("/libxmlb/builder{empty}", xb_builder_empty_func);
        g_test_add_func("/libxmlb/builder{ensure}", xb_builder_ensure_func);
        g_test_add_func("/libxmlb/builder{ensure-watch-source}",
@@ -3382,6 +3405,7 @@
        if (g_test_perf()) {
                g_test_add_func("/libxmlb/threading", xb_threading_func);
                g_test_add_func("/libxmlb/speed", xb_speed_func);
+               g_test_add_func("/libxmlb/speed-precompiled", 
xb_speed_precompiled_func);
        }
        return g_test_run();
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-silo-node.c 
new/libxmlb-0.3.29/src/xb-silo-node.c
--- old/libxmlb-0.3.27/src/xb-silo-node.c       2026-05-18 17:44:22.000000000 
+0200
+++ new/libxmlb-0.3.29/src/xb-silo-node.c       2026-07-27 17:01:51.000000000 
+0200
@@ -11,8 +11,8 @@
 xb_silo_node_to_string(const XbSiloNode *self)
 {
        GString *str = g_string_new("XbSiloNode:\n");
-       g_string_append_printf(str, "  flags: 0x%x\n", self->flags);
-       g_string_append_printf(str, "  attr_count: %u\n", self->attr_count);
+       g_string_append_printf(str, "  flags: 0x%x\n", (guint)self->flags);
+       g_string_append_printf(str, "  attr_count: %u\n", 
(guint)self->attr_count);
        if (self->flags & XB_SILO_NODE_FLAG_IS_ELEMENT) {
                if (self->element_name != XB_SILO_UNSET)
                        g_string_append_printf(str, "  element_name: %u\n", 
self->element_name);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-silo-query.c 
new/libxmlb-0.3.29/src/xb-silo-query.c
--- old/libxmlb-0.3.27/src/xb-silo-query.c      2026-05-18 17:44:22.000000000 
+0200
+++ new/libxmlb-0.3.29/src/xb-silo-query.c      2026-07-27 17:01:51.000000000 
+0200
@@ -22,6 +22,50 @@
 
 #define XB_QUERY_OR_BRANCH_MAX 64
 
+static inline gboolean
+xb_silo_query_node_matches_predicate_with_bindings(XbSilo *self,
+                                                  XbStack *opcodes,
+                                                  XbSiloQueryData *query_data,
+                                                  XbValueBindings *bindings,
+                                                  guint *bindings_offset,
+                                                  gboolean *result,
+                                                  GError **error)
+{
+       XbMachine *machine = xb_silo_get_machine(self);
+       g_auto(XbValueBindings) predicate_bindings = XB_VALUE_BINDINGS_INIT();
+       guint predicate_bindings_idx = 0;
+       XbValueBindings *predicate_bindings_ptr = &predicate_bindings;
+
+       /* set up the bindings for this predicate */
+       for (guint k = 0; k < xb_stack_get_size(opcodes); k++) {
+               XbOpcode *op = xb_stack_peek(opcodes, k);
+               if (xb_opcode_is_binding(op)) {
+                       /* ignore errors as they’ll be caught by 
xb_machine_run() */
+                       xb_value_bindings_copy_binding(bindings,
+                                                      *bindings_offset + 
predicate_bindings_idx,
+                                                      &predicate_bindings,
+                                                      predicate_bindings_idx);
+                       predicate_bindings_idx++;
+               }
+       }
+
+       /* run the predicate; pass NULL for the bindings iff
+        * (bindings == NULL), as that means we’ve been called
+        * with pre-0.3.0-style pre-bound values */
+       if (!xb_machine_run_with_bindings(machine,
+                                         opcodes,
+                                         predicate_bindings_ptr,
+                                         result,
+                                         query_data,
+                                         error))
+               return FALSE;
+
+       *bindings_offset += predicate_bindings_idx;
+
+       /* success */
+       return TRUE;
+}
+
 static gboolean
 xb_silo_query_node_matches(XbSilo *self,
                           XbMachine *machine,
@@ -48,39 +92,26 @@
        if (section->predicates != NULL) {
                for (guint i = 0; i < section->predicates->len; i++) {
                        XbStack *opcodes = 
g_ptr_array_index(section->predicates, i);
-                       g_auto(XbValueBindings) predicate_bindings = 
XB_VALUE_BINDINGS_INIT();
-                       guint predicate_bindings_idx = 0;
-                       XbValueBindings *predicate_bindings_ptr = NULL;
-
-                       if (bindings != NULL)
-                               predicate_bindings_ptr = &predicate_bindings;
-
-                       /* set up the bindings for this predicate */
-                       for (guint k = 0; bindings != NULL && k < 
xb_stack_get_size(opcodes); k++) {
-                               XbOpcode *op = xb_stack_peek(opcodes, k);
-                               if (xb_opcode_is_binding(op)) {
-                                       /* ignore errors as they’ll be caught 
by xb_machine_run() */
-                                       xb_value_bindings_copy_binding(bindings,
-                                                                      
bindings_offset +
-                                                                          
predicate_bindings_idx,
-                                                                      
&predicate_bindings,
-                                                                      
predicate_bindings_idx);
-                                       predicate_bindings_idx++;
-                               }
+                       if (bindings != NULL) {
+                               if 
(!xb_silo_query_node_matches_predicate_with_bindings(
+                                       self,
+                                       opcodes,
+                                       query_data,
+                                       bindings,
+                                       &bindings_offset,
+                                       result,
+                                       error))
+                                       return FALSE;
+                       } else {
+                               /* we’ve been called with pre-0.3.0-style 
pre-bound values */
+                               if (!xb_machine_run_with_bindings(machine,
+                                                                 opcodes,
+                                                                 NULL,
+                                                                 result,
+                                                                 query_data,
+                                                                 error))
+                                       return FALSE;
                        }
-
-                       /* run the predicate; pass NULL for the bindings iff
-                        * (bindings == NULL), as that means we’ve been called
-                        * with pre-0.3.0-style pre-bound values */
-                       if (!xb_machine_run_with_bindings(machine,
-                                                         opcodes,
-                                                         
predicate_bindings_ptr,
-                                                         result,
-                                                         query_data,
-                                                         error))
-                               return FALSE;
-
-                       bindings_offset += predicate_bindings_idx;
                }
        }
 
@@ -106,32 +137,56 @@
        XB_SILO_QUERY_HELPER_NONE = 0,
        XB_SILO_QUERY_HELPER_USE_SN = 1 << 0,
        XB_SILO_QUERY_HELPER_FORCE_NODE_CACHE = 1 << 1,
+       XB_SILO_QUERY_HELPER_USE_HASH = 1 << 2,
 } XbSiloQueryHelperFlags;
 
 typedef struct {
-       GPtrArray *sections; /* of XbQuerySection */
-       GPtrArray *results;  /* of XbNode or XbSiloNode (see @flags) */
+       GPtrArray *sections;    /* of XbQuerySection */
+       GPtrArray *nodes;       /* of XbNode or XbSiloNode (see @flags) */
+       GHashTable *nodes_hash; /* of sn:1 */
        XbValueBindings *bindings;
-       GHashTable *results_hash; /* of sn:1 */
        guint limit;
        XbSiloQueryHelperFlags flags;
        XbSiloQueryData *query_data;
 } XbSiloQueryHelper;
 
+static void
+xb_silo_query_helper_free(XbSiloQueryHelper *helper)
+{
+       if (helper->nodes != NULL)
+               g_ptr_array_unref(helper->nodes);
+       if (helper->nodes_hash != NULL)
+               g_hash_table_unref(helper->nodes_hash);
+}
+
+G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(XbSiloQueryHelper, xb_silo_query_helper_free)
+
 static gboolean
-xb_silo_query_section_add_result(XbSilo *self, XbSiloQueryHelper *helper, 
XbSiloNode *sn)
+xb_silo_query_section_add_node(XbSilo *self, XbSiloQueryHelper *helper, 
XbSiloNode *sn)
 {
-       if (g_hash_table_lookup(helper->results_hash, sn) != NULL)
-               return FALSE;
+       if (helper->flags & XB_SILO_QUERY_HELPER_USE_HASH) {
+               if (helper->nodes_hash == NULL) {
+                       helper->nodes_hash = g_hash_table_new(g_direct_hash, 
g_direct_equal);
+               } else {
+                       if (g_hash_table_lookup(helper->nodes_hash, sn) != NULL)
+                               return FALSE;
+               }
+               g_hash_table_add(helper->nodes_hash, sn);
+       }
        if (helper->flags & XB_SILO_QUERY_HELPER_USE_SN) {
-               g_ptr_array_add(helper->results, sn);
+               if (helper->nodes == NULL)
+                       helper->nodes = g_ptr_array_new();
+               g_ptr_array_add(helper->nodes, sn);
        } else {
                gboolean force_node_cache =
                    (helper->flags & XB_SILO_QUERY_HELPER_FORCE_NODE_CACHE) > 0;
-               g_ptr_array_add(helper->results, xb_silo_create_node(self, sn, 
force_node_cache));
+               if (helper->nodes == NULL) {
+                       helper->nodes =
+                           
g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
+               }
+               g_ptr_array_add(helper->nodes, xb_silo_create_node(self, sn, 
force_node_cache));
        }
-       g_hash_table_add(helper->results_hash, sn);
-       return helper->results->len == helper->limit;
+       return helper->limit > 0 && helper->nodes->len >= helper->limit;
 }
 
 /*
@@ -163,7 +218,7 @@
                if (parent == NULL)
                        return FALSE;
                if (i == helper->sections->len - 1) {
-                       xb_silo_query_section_add_result(self, helper, parent);
+                       xb_silo_query_section_add_node(self, helper, parent);
                        return TRUE;
                }
                return xb_silo_query_section_root(self,
@@ -212,7 +267,7 @@
                        return FALSE;
                if (result) {
                        if (i == helper->sections->len - 1) {
-                               if (xb_silo_query_section_add_result(self, 
helper, sn))
+                               if (xb_silo_query_section_add_node(self, 
helper, sn))
                                        break;
                        } else {
                                if (!xb_silo_query_section_root(self,
@@ -222,8 +277,7 @@
                                                                helper,
                                                                error))
                                        return FALSE;
-                               if (helper->results->len > 0 &&
-                                   helper->results->len == helper->limit)
+                               if (helper->nodes != NULL && helper->nodes->len 
== helper->limit)
                                        break;
                        }
                }
@@ -249,35 +303,28 @@
 static gboolean
 xb_silo_query_part(XbSilo *self,
                   XbSiloNode *sroot,
-                  GPtrArray *results,
-                  GHashTable *results_hash,
+                  XbSiloQueryHelper *helper,
                   XbQuery *query,
                   XbQueryContext *context,
                   gboolean first_result_only,
-                  XbSiloQueryData *query_data,
-                  XbSiloQueryHelperFlags flags,
                   GError **error)
 {
-       G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-       XbSiloQueryHelper helper = {
-           .results = results,
-           .bindings = (context != NULL) ? 
xb_query_context_get_bindings(context) : NULL,
-           .limit = first_result_only   ? 1
-                    : (context != NULL) ? xb_query_context_get_limit(context)
-                                        : xb_query_get_limit(query),
-           .flags = flags,
-           .results_hash = results_hash,
-           .query_data = query_data,
-       };
-       XbQueryFlags query_flags = (context != NULL) ? 
xb_query_context_get_flags(context)
-                                                    : 
xb_query_get_flags(query);
-       G_GNUC_END_IGNORE_DEPRECATIONS
+       if (context != NULL) {
+               if (xb_query_context_get_flags(context) & 
XB_QUERY_FLAG_FORCE_NODE_CACHE)
+                       helper->flags |= XB_SILO_QUERY_HELPER_FORCE_NODE_CACHE;
+               helper->bindings = xb_query_context_get_bindings(context);
+               helper->limit = first_result_only ? 1 : 
xb_query_context_get_limit(context);
+       } else {
+               G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+               if (xb_query_get_flags(query) & XB_QUERY_FLAG_FORCE_NODE_CACHE)
+                       helper->flags |= XB_SILO_QUERY_HELPER_FORCE_NODE_CACHE;
+               helper->limit = first_result_only ? 1 : 
xb_query_get_limit(query);
+               G_GNUC_END_IGNORE_DEPRECATIONS
+       }
 
        /* find each section */
-       helper.sections = xb_query_get_sections(query);
-       if (query_flags & XB_QUERY_FLAG_FORCE_NODE_CACHE)
-               helper.flags |= XB_SILO_QUERY_HELPER_FORCE_NODE_CACHE;
-       return xb_silo_query_section_root(self, sroot, 0, 0, &helper, error);
+       helper->sections = xb_query_get_sections(query);
+       return xb_silo_query_section_root(self, sroot, 0, 0, helper, error);
 }
 
 /* Returns an array with (element-type XbSiloNode) if
@@ -292,13 +339,12 @@
 {
        XbSiloNode *sn = NULL;
        g_auto(GStrv) split = NULL;
-       g_autoptr(GHashTable) results_hash = g_hash_table_new(g_direct_hash, 
g_direct_equal);
-       g_autoptr(GPtrArray) results = NULL;
        g_autoptr(GTimer) timer = xb_silo_start_profile(self);
        XbSiloQueryData query_data = {
            .sn = NULL,
            .position = 0,
        };
+       g_auto(XbSiloQueryHelper) helper = {.flags = flags, .query_data = 
&query_data};
 
        g_return_val_if_fail(XB_IS_SILO(self), NULL);
        g_return_val_if_fail(xpath != NULL, NULL);
@@ -310,11 +356,6 @@
                return NULL;
        }
 
-       if (flags & XB_SILO_QUERY_HELPER_USE_SN)
-               results = g_ptr_array_new_with_free_func(NULL);
-       else
-               results = 
g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
-
        /* subtree query */
        if (n != NULL) {
                sn = xb_node_get_sn(n);
@@ -347,7 +388,7 @@
 
                if (query == NULL) {
                        if (g_error_matches(error_local, G_IO_ERROR, 
G_IO_ERROR_INVALID_ARGUMENT) &&
-                           (split[i + 1] != NULL || results->len > 0)) {
+                           (split[i + 1] != NULL || helper.nodes != NULL)) {
                                if (xb_silo_get_profile_flags(self) & 
XB_SILO_PROFILE_FLAG_DEBUG) {
                                        g_debug("ignoring for OR statement: %s",
                                                error_local->message);
@@ -362,18 +403,8 @@
                }
 
                xb_query_context_set_limit(&context, limit);
-               if (!xb_silo_query_part(self,
-                                       sn,
-                                       results,
-                                       results_hash,
-                                       query,
-                                       &context,
-                                       FALSE,
-                                       &query_data,
-                                       flags,
-                                       error)) {
+               if (!xb_silo_query_part(self, sn, &helper, query, &context, 
FALSE, error))
                        return NULL;
-               }
        }
 
        /* profile */
@@ -384,11 +415,11 @@
                                    n != NULL ? xb_node_get_element(n) : "/",
                                    xpath,
                                    limit,
-                                   results->len);
+                                   helper.nodes != NULL ? helper.nodes->len : 
0);
        }
 
        /* nothing found */
-       if (results->len == 0) {
+       if (helper.nodes == NULL) {
                g_set_error(error,
                            G_IO_ERROR,
                            G_IO_ERROR_NOT_FOUND,
@@ -396,7 +427,7 @@
                            xpath);
                return NULL;
        }
-       return g_steal_pointer(&results);
+       return g_steal_pointer(&helper.nodes);
 }
 
 /**
@@ -489,14 +520,15 @@
                             GError **error)
 {
        XbSiloNode *sn = NULL;
-       g_autoptr(GHashTable) results_hash = g_hash_table_new(g_direct_hash, 
g_direct_equal);
-       g_autoptr(GPtrArray) results =
-           g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref);
        g_autoptr(GTimer) timer = xb_silo_start_profile(self);
        XbSiloQueryData query_data = {
            .sn = NULL,
            .position = 0,
        };
+       g_auto(XbSiloQueryHelper) helper = {
+           .flags = first_result_only ? XB_SILO_QUERY_HELPER_NONE : 
XB_SILO_QUERY_HELPER_USE_HASH,
+           .query_data = &query_data,
+       };
        G_GNUC_BEGIN_IGNORE_DEPRECATIONS
        XbQueryFlags query_flags = (context != NULL) ? 
xb_query_context_get_flags(context)
                                                     : 
xb_query_get_flags(query);
@@ -519,17 +551,9 @@
        if (n != NULL)
                sn = xb_node_get_sn(n);
 
-       /* only one query allowed */
-       if (!xb_silo_query_part(self,
-                               sn,
-                               results,
-                               results_hash,
-                               query,
-                               context,
-                               first_result_only,
-                               &query_data,
-                               XB_SILO_QUERY_HELPER_NONE,
-                               error))
+       /* only one query, so dedup is only needed for multi-result queries
+        * where parent traversal could fan in to the same node */
+       if (!xb_silo_query_part(self, sn, &helper, query, context, 
first_result_only, error))
                return NULL;
 
        /* profile */
@@ -554,27 +578,21 @@
                                    tmp,
                                    bindings_str != NULL ? bindings_str : "",
                                    limit,
-                                   results->len);
+                                   helper.nodes != NULL ? helper.nodes->len : 
0);
        }
 
        /* nothing found */
-       if (results->len == 0) {
-               if (error != NULL) {
-                       g_autofree gchar *tmp = xb_query_to_string(query);
-                       g_set_error(error,
-                                   G_IO_ERROR,
-                                   G_IO_ERROR_NOT_FOUND,
-                                   "no results for XPath query '%s'",
-                                   tmp);
-               }
+       if (helper.nodes == NULL) {
+               if (error != NULL)
+                       g_set_error_literal(error, G_IO_ERROR, 
G_IO_ERROR_NOT_FOUND, "no results");
                return NULL;
        }
 
        /* reverse order */
        if (query_flags & XB_QUERY_FLAG_REVERSE)
-               _g_ptr_array_reverse(results);
+               _g_ptr_array_reverse(helper.nodes);
 
-       return g_steal_pointer(&results);
+       return g_steal_pointer(&helper.nodes);
 }
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-silo.c 
new/libxmlb-0.3.29/src/xb-silo.c
--- old/libxmlb-0.3.27/src/xb-silo.c    2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/xb-silo.c    2026-07-27 17:01:51.000000000 +0200
@@ -53,6 +53,7 @@
        guint32 strtab;
        GHashTable *strtab_tags;
        GHashTable *strindex;
+       GRWLock strindex_mutex;
        gboolean enable_node_cache;
        GHashTable *nodes; /* (mutex nodes_mutex) */
        GMutex nodes_mutex;
@@ -199,11 +200,13 @@
 {
        XbSiloPrivate *priv = GET_PRIVATE(self);
        const gchar *tmp;
+       g_autoptr(GRWLockWriterLocker) locker_rw = NULL;
 
        /* get the string version */
        tmp = xb_silo_from_strtab(self, offset, error);
        if (tmp == NULL)
                return FALSE;
+       locker_rw = g_rw_lock_writer_locker_new(&priv->strindex_mutex);
        if (g_hash_table_lookup(priv->strindex, tmp) != NULL)
                return TRUE;
        g_hash_table_insert(priv->strindex, (gpointer)tmp, 
GUINT_TO_POINTER(offset));
@@ -216,6 +219,9 @@
 {
        XbSiloPrivate *priv = GET_PRIVATE(self);
        gpointer val = NULL;
+       g_autoptr(GRWLockReaderLocker) locker_ro = NULL;
+
+       locker_ro = g_rw_lock_reader_locker_new(&priv->strindex_mutex);
        if (!g_hash_table_lookup_extended(priv->strindex, str, NULL, &val))
                return XB_SILO_UNSET;
        return GPOINTER_TO_INT(val);
@@ -266,8 +272,8 @@
                g_set_error(error,
                            G_IO_ERROR,
                            G_IO_ERROR_INVALID_DATA,
-                           "blob too small: 0x%x",
-                           (guint)g_bytes_get_size(priv->blob));
+                           "blob too small: 0x%zx",
+                           g_bytes_get_size(priv->blob));
                return NULL;
        }
        if (G_UNLIKELY(g_bytes_get_size(priv->blob) == sizeof(XbSiloHeader))) {
@@ -726,7 +732,6 @@
 xb_silo_get_machine(XbSilo *self)
 {
        XbSiloPrivate *priv = GET_PRIVATE(self);
-       g_return_val_if_fail(XB_IS_SILO(self), NULL);
        return priv->machine;
 }
 
@@ -759,6 +764,7 @@
        g_return_val_if_fail(error == NULL || *error == NULL, FALSE);
 
        /* no longer valid */
+       xb_silo_invalidate(self);
        if (priv->enable_node_cache) {
                locker = g_mutex_locker_new(&priv->nodes_mutex);
                if (priv->nodes != NULL)
@@ -766,8 +772,17 @@
        }
 
        g_hash_table_remove_all(priv->strtab_tags);
+
+       g_rw_lock_writer_lock(&priv->strindex_mutex);
+       g_hash_table_remove_all(priv->strindex);
+       g_rw_lock_writer_unlock(&priv->strindex_mutex);
+
        g_clear_pointer(&priv->guid, g_free);
 
+       g_rw_lock_writer_lock(&priv->query_cache_mutex);
+       g_hash_table_remove_all(priv->query_cache);
+       g_rw_lock_writer_unlock(&priv->query_cache_mutex);
+
        /* refcount internally */
        if (priv->blob != NULL)
                g_bytes_unref(priv->blob);
@@ -848,7 +863,7 @@
        xb_silo_add_profile(self, timer, "parse blob");
 
        /* success */
-       priv->valid = TRUE;
+       xb_silo_uninvalidate(self);
        return TRUE;
 }
 
@@ -1753,6 +1768,7 @@
 
        priv->strtab_tags = g_hash_table_new(g_str_hash, g_str_equal);
        priv->strindex = g_hash_table_new(g_str_hash, g_str_equal);
+       g_rw_lock_init(&priv->strindex_mutex);
        priv->profile_str = g_string_new(NULL);
        priv->query_cache = g_hash_table_new_full(g_str_hash, g_str_equal, 
g_free, g_object_unref);
        g_rw_lock_init(&priv->query_cache_mutex);
@@ -1827,6 +1843,7 @@
        g_rw_lock_clear(&priv->query_cache_mutex);
        g_object_unref(priv->machine);
        g_hash_table_unref(priv->strindex);
+       g_rw_lock_clear(&priv->strindex_mutex);
        g_hash_table_unref(priv->file_monitors);
        g_mutex_clear(&priv->file_monitors_mutex);
        g_hash_table_unref(priv->strtab_tags);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-string.h 
new/libxmlb-0.3.29/src/xb-string.h
--- old/libxmlb-0.3.27/src/xb-string.h  2026-05-18 17:44:22.000000000 +0200
+++ new/libxmlb-0.3.29/src/xb-string.h  2026-07-27 17:01:51.000000000 +0200
@@ -13,8 +13,6 @@
 void
 xb_string_append_union(GString *xpath, const gchar *fmt, ...) G_GNUC_PRINTF(2, 
3)
     G_GNUC_NON_NULL(1);
-
-GLIB_DEPRECATED_FOR(xb_value_bindings_bind_str)
 gchar *
 xb_string_escape(const gchar *str) G_GNUC_NON_NULL(1);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/libxmlb-0.3.27/src/xb-value-bindings.c 
new/libxmlb-0.3.29/src/xb-value-bindings.c
--- old/libxmlb-0.3.27/src/xb-value-bindings.c  2026-05-18 17:44:22.000000000 
+0200
+++ new/libxmlb-0.3.29/src/xb-value-bindings.c  2026-07-27 17:01:51.000000000 
+0200
@@ -70,13 +70,11 @@
 {
        RealValueBindings *_self = (RealValueBindings *)self;
 
-       g_return_if_fail(idx < G_N_ELEMENTS(_self->values));
-
-       if (_self->values[idx].ptr != NULL && _self->values[idx].destroy_func)
+       if (_self->values[idx].ptr != NULL && _self->values[idx].destroy_func) {
                _self->values[idx].destroy_func(_self->values[idx].ptr);
-       _self->values[idx].kind = XB_BOUND_VALUE_KIND_NONE;
-       _self->values[idx].ptr = NULL;
-       _self->values[idx].destroy_func = NULL;
+               _self->values[idx].ptr = NULL;
+               _self->values[idx].destroy_func = NULL;
+       }
 }
 
 /**

Reply via email to