pkgng/pkgng 2678d2b.github/workflows build.yaml

ci: exclude the macOS ubsan+tsan matrix
DeltaFile
+4-0.github/workflows/build.yaml
+4-01 files

pkgng/pkgng 037f655. NEWS configure.def, external/sqlite sqlite3.c shell.c

2.7.99.3

Bump version to 2.7.99.3 and add the NEWS section covering changes
since the 2.7.99.2 release (ee453993f): DB schema/WAL overhaul,
OSVf 1.7.5, plist @for loops, security fixes including the "snap"
version parsing OOB (#2691) and pkg_printf format parsing, and an
update of the vendored SQLite amalgamation to 3.53.2.
DeltaFile
+697-181external/sqlite/sqlite3.c
+27-0NEWS
+15-8external/sqlite/shell.c
+17-5external/sqlite/sqlite3.h
+1-1configure.def
+757-1955 files

pkgng/pkgng 0742ba8tests/fuzz fuzz_plist.c

tests/fuzz: fix plist harness

Store the fmemopen FILE* in a FILE* (not int, which truncated the
pointer) and parse through the exported plist_parse_line() instead
of the static plist_parse(), so the harness actually builds and runs.
DeltaFile
+15-7tests/fuzz/fuzz_plist.c
+15-71 files

pkgng/pkgng 4ffc94blibpkg pkg_printf.c fetch_file.c, src event.c

fix: OOB and hangs in version/printf parsing

- pkg_version: fix the "snap" stage entry, whose namelen was 6 for a
  4-char name, causing a heap OOB read and dangling pointer in
  get_component on versions ending in "snap". Set namelen to 4 and
  value to "s"-"a"+ABASE so snap sorts after alpha as intended (#2691)
- pkg_printf: stop format_code from reading f[1] past end of string,
  and emit a lone "%" literally instead of looping forever when no
  valid format code follows
- event: cast nbdigits to int for the %* field width
- fetch_file: print the offending URL in the "hostname too long"
  error message
DeltaFile
+13-1libpkg/pkg_printf.c
+1-1libpkg/fetch_file.c
+1-1libpkg/pkg_version.c
+1-1src/event.c
+16-44 files

pkgng/pkgng 70dd603libpkg pkg_printf.c pkg_event.c, src query.c event.c

xstring: rename xprintf/xputs/xputc/xwrite/xflush to xstring_*

Rename the convenience macros to use the xstring_ prefix for
consistency with xstring_new/xstring_reset/xstring_renew.
DeltaFile
+78-78libpkg/pkg_printf.c
+74-74src/query.c
+32-32libpkg/pkg_event.c
+26-26libpkg/pkg_ports.c
+21-21src/event.c
+20-20libpkg/utils.c
+251-25135 files not shown
+399-39941 files

pkgng/pkgng bb99830tests/lib pkg_osvf.c

tests: Update OSVf test

Update OSVf test for osv_type and type change
DeltaFile
+8-4tests/lib/pkg_osvf.c
+8-41 files

pkgng/pkgng a45f6c7libpkg pkg_osvf.c, libpkg/pkg audit.h

pkg_osvf: Add osv_type for VuXML compatibility

As VuXML audit currently uses pkg_audit_version type
field different than pkg_osvf make sure that OSVf implementation
tries to mimic VuXML version checking code.

For keeping OSVf version compatibility in order introduce
osv_type which now contains OSVf events information
DeltaFile
+38-19libpkg/pkg_osvf.c
+1-0libpkg/pkg/audit.h
+39-192 files

pkgng/pkgng c1ffb83libpkg fetch_file.c, tests Makefile.in

fix: prevent buffer overflow in file_open() URL parsing

Replace strncat() with snprintf() and add length validation when
extracting hostname from file:// URLs. Reject hostnames > 255 chars.

Security: Fixes potential stack buffer overflow
Tests: Add 4 ATF tests (all passing)

Closes(#2705)
DeltaFile
+161-0tests/lib/fetch_file.c
+16-3libpkg/fetch_file.c
+5-2tests/Makefile.in
+182-53 files

pkgng/pkgng 31aa72esrc main.c

main: Don't set debug level twice

Now that pkg_ini() no longer clears the debug level, it is enough to set
it once, immediately after the getopt_long() loop.
DeltaFile
+0-3src/main.c
+0-31 files

pkgng/pkgng 226c4c7libpkg pkg_config.c

libpkg: Fix early debug

* Initialize ctx.debug_flags to all-bits-one so pkg_dbg() can be used
  before pkg_ini() read the configuration.

* In pkg_ini(), only set ctx.debug_level if the new value (from the
  configuration or environment) is greater than the current value.
DeltaFile
+13-1libpkg/pkg_config.c
+13-11 files

pkgng/pkgng cdf7f9fsrc install.c

install: Support -X for --register-only

This was documented but not actually implemented.

Fixes:          cb296b1d164f ("pkg_install: Add --register-only")
DeltaFile
+1-1src/install.c
+1-11 files

pkgng/pkgng 55d2ea0libpkg pkg_jobs.c

Fix: use-after-free since 1d3a0e5fb
DeltaFile
+2-1libpkg/pkg_jobs.c
+2-11 files

pkgng/pkgng 6a7dc3alibpkg pkgdb.c, libpkg/private db_upgrades.h

fix: move PRAGMA journal_mode/synchronous out of upgrade SQL

PRAGMA journal_mode and synchronous cannot be changed inside a
transaction.  The v40 upgrade SQL bundled DROP INDEX statements
(which implicitly start a transaction) together with PRAGMAs,
causing a "Safety level may not be changed inside a transaction"
error.

Fix: remove PRAGMAs from db_upgrades.h v40 and set synchronous=NORMAL
in pkgdb_open right after journal_mode=WAL, where no transaction
is active.
DeltaFile
+0-2libpkg/private/db_upgrades.h
+1-0libpkg/pkgdb.c
+1-22 files

pkgng/pkgng 59b3b4clibpkg pkgdb.c

run_prstmt: skip expensive sqlite3_expanded_sql when debug is off

sqlite3_expanded_sql formats the entire SQL with all bound values
substituted.  This was called unconditionally on every prepared
statement execution, even in production (debug_level=0), wasting
CPU cycles on memory allocation and string formatting.

Guard the call with ctx.debug_level >= 4, matching the pattern
already used by pkgdb_debug().
DeltaFile
+5-3libpkg/pkgdb.c
+5-31 files

pkgng/pkgng 6ea2a39libpkg pkgdb.c, libpkg/private db_upgrades.h

shlibs: add missing indexes on shlib_id for faster library lookups

pkgdb_query_shlib_require/provide join through shlib_id but no index
existed on that column.  Without an index, SQLite does a full table scan
of pkg_shlibs_required/provided to find matching rows for a given shlib.

Added indexes (4 for local DB, 2 for binary repo):
  pkg_shlibs_required_shlib_id(shlib_id)
  pkg_shlibs_required_ignore_shlib_id(shlib_id)
  pkg_shlibs_provided_shlib_id(shlib_id)
  pkg_shlibs_provided_ignore_shlib_id(shlib_id)

Local DB: schema bumped to v42 with upgrade path for existing databases.
Binary repo: added to binary_repo_initsql.
DeltaFile
+5-1libpkg/pkgdb.c
+5-0libpkg/private/db_upgrades.h
+2-0libpkg/repo/binary/binary_private.h
+12-13 files

pkgng/pkgng fc8f666libpkg pkgdb_query.c pkgdb.c

pkgdb: convert remaining implicit SQL-89 JOINs to explicit syntax

- pkgdb_query.c: 4 queries in pkgdb_query_shlib_require/provide,
  pkgdb_query_require/provide (comma-separated FROM)
- pkgdb.c: pkgdb_is_dir_used (comma-separated FROM)
DeltaFile
+16-16libpkg/pkgdb_query.c
+3-2libpkg/pkgdb.c
+19-182 files

pkgng/pkgng c480698libpkg pkgdb_query.c pkgdb.c, libpkg/private db_upgrades.h

flavors: replace duplicated CTE with persistent view in both databases

The WITH flavors AS (...) CTE was duplicated across 5 queries in
pkgdb_query.c and repo/binary/query.c.  Replace it with a persistent
VIEW created in both the local and binary repo schemas.

Changes:
- binary_private.h: add CREATE VIEW to binary_repo_initsql
- pkgdb.c: add CREATE VIEW to pkgdb_init() for fresh databases
- db_upgrades.h: add upgrade v41 to create the view on existing DBs
- pkgdb_query.c: remove the 2 duplicated CTE definitions
- repo/binary/query.c: remove the 2 duplicated CTE definitions
- pkgdb.c: bump DB_SCHEMA_MINOR 40 -> 41
DeltaFile
+0-11libpkg/repo/binary/query.c
+0-10libpkg/pkgdb_query.c
+7-1libpkg/pkgdb.c
+6-0libpkg/private/db_upgrades.h
+5-0libpkg/repo/binary/binary_private.h
+18-225 files

pkgng/pkgng 2c3aef9libpkg/repo/binary update.c

binary repo: use 16K pages and synchronous=OFF during bulk update

- page_size: switch from getpagesize() (typically 4K) to 16384 for
  better B-tree cache efficiency with millions of rows
- synchronous: set to OFF during bulk INSERT phase; the database is
  re-opened with synchronous=FULL on subsequent access via
  pkg_repo_binary_init, so durability is maintained for read queries
DeltaFile
+3-3libpkg/repo/binary/update.c
+3-31 files

pkgng/pkgng 3f6748flibpkg pkgdb.c, libpkg/private db_upgrades.h

local db: remove 15 redundant indexes, switch to WAL+NORMAL, bump schema v40

Each *_{package_id} index is redundant: all junction tables use
PRIMARY KEY(package_id, other_id) or UNIQUE(package_id, other_id),
which implicitly creates an index with package_id as leading column.
The explicit single-column index adds storage and INSERT overhead
with zero query-plan benefit.

Dropped indexes (15 total):
  pkg_script_package_id, pkg_directories_package_id,
  pkg_categories_package_id, pkg_licenses_package_id,
  pkg_users_package_id, pkg_groups_package_id,
  pkg_shlibs_required_package_id, pkg_shlibs_required_ignore_package_id,
  pkg_shlibs_provided_package_id, pkg_shlibs_provided_ignore_package_id,
  pkg_annotation_package_id, pkg_conflicts_pid,
  pkg_provides_id, pkg_requires_package_id, pkg_lua_script_package_id

PRAGMA changes:
- journal_mode: TRUNCATE -> WAL (better concurrent read performance)

    [4 lines not shown]
DeltaFile
+4-17libpkg/pkgdb.c
+19-1libpkg/private/db_upgrades.h
+23-182 files

pkgng/pkgng 1ef32fdlibpkg pkgdb_iterator.c

pkgdb_iterator: convert implicit SQL-89 JOINs to explicit JOIN syntax

Replaced 11 comma-separated implicit JOIN queries with explicit
JOIN ... ON syntax for clarity and maintainability:

- pkg_directories, directories
- pkg_licenses, licenses AS l
- pkg_categories, categories AS c
- pkg_users, users
- pkg_groups, groups
- pkg_shlibs_required(/ignore/provided/ignore), shlibs AS s
- pkg_provides, provides AS s
- pkg_requires, requires AS s
DeltaFile
+23-23libpkg/pkgdb_iterator.c
+23-231 files

pkgng/pkgng 626fc74libpkg pkgdb_query.c

pkgdb_query: optimized SQL queries and removed BUFSIZ limit

- Removed GROUP BY p.id from exact-match which query (path TEXT PRIMARY KEY
  guarantees uniqueness per file across all packages; GROUP BY retained for
  GLOB mode)
- Changed LEFT JOIN to INNER JOIN in which query (WHERE f.path = ? filters
  NULLs, making LEFT JOIN misleading)
- Replaced fixed BUFSIZ buffers with xasprintf() for safe dynamic allocation
  in pkgdb_query_cond, pkgdb_query_which, and pkgdb_file_exists
- Simplified pkgdb_file_exists to a const string instead of snprintf
DeltaFile
+19-15libpkg/pkgdb_query.c
+19-151 files

pkgng/pkgng 14503d7libpkg/repo/binary update.c

rwhich: remove redundant pkg_files indexes

The pkg_files table has a UNIQUE(package_id, dir_id, name) constraint
which implicitly creates an index with package_id as the leading column.
This serves any WHERE package_id=? query just as efficiently as a
dedicated index, making pkg_files_package_id redundant.

The pkg_files_name index is unused: no query in the binary repo filters
by name alone - file_which either matches (dir_id, name) via the
composite index, or uses a GLOB on a concatenated expression which
cannot use any index.

Only pkg_files_dir_name(dir_id, name) is retained, as it is used by the
exact-match path in pkg_repo_binary_file_which.
DeltaFile
+0-2libpkg/repo/binary/update.c
+0-21 files

pkgng/pkgng 1f91a25libpkg/repo/binary update.c common.c

rwhich: replace SQL subquery with hashmap for dir_id lookups

The FILEDIR2 prepared statement previously used a subquery:
  (SELECT id FROM file_dirs WHERE path = ?2)
for every file inserted (6M+ rows on a full FreeBSD repo update).

Replace this with an in-memory pkghash built from a single SELECT after
Phase 1 directory insertion.  Phase 2 looks up dir_id from the hashmap
in O(1) average instead of O(log N) per file via SQL.

Also change FILEDIR2 to accept dir_id as a direct integer parameter,
eliminating the subquery entirely.

Net improvement: ~6M subquery executions → 1 bulk SELECT + ~6M hash
lookups (all in-process, no SQL round-trips).
DeltaFile
+21-1libpkg/repo/binary/update.c
+1-1libpkg/repo/binary/common.c
+22-22 files

pkgng/pkgng 8a5619blibpkg/repo/binary query.c

rwhich: remove unnecessary GROUP BY in exact-match query

The UNIQUE(package_id, dir_id, name) constraint guarantees at most
one row per package per file.  No grouping is needed for the exact
match query path.  The GROUP BY is retained in the glob variant,
where a single GLOB can match multiple distinct files from the same
package.
DeltaFile
+1-2libpkg/repo/binary/query.c
+1-21 files

pkgng/pkgng 7119e50libpkg pkg_jobs_conflicts.c

jobs/conflicts: fix data corruption in conflict_items_insert

conflict_items_insert called vec_push first, then memmove to shift
elements right at the insertion position. This overwrote the just-pushed
element at the end of the vector, duplicating the last existing element
instead.

Fix by growing capacity manually, shifting elements first, then
inserting at the correct position.
DeltaFile
+13-5libpkg/pkg_jobs_conflicts.c
+13-51 files

pkgng/pkgng 84a5c49libpkg pkghash.c pkghash.h

pkghash: fix deletion in open-addressing hash table

Use tombstone markers instead of NULLing keys on deletion.
In open-addressing with linear probing, setting key to NULL creates
a hole that breaks probe chains for subsequent lookups.

Track tombstones and trigger rehash when tombstone density exceeds 25%
to guarantee bounded probe sequences.
DeltaFile
+31-14libpkg/pkghash.c
+1-0libpkg/pkghash.h
+32-142 files

pkgng/pkgng ebbfe3dlibpkg clean_cache.c triggers.c

fdopendir UB: use dirfd() instead of raw fd

POSIX states that after fdopendir(), the file descriptor is under
the control of the system and must not be used directly. Use dirfd()
to retrieve the fd from the DIR stream for subsequent openat()
and fstatat() calls.

Rename dirfd variable in clean_cache.c to avoid collision with
the POSIX dirfd() function.
DeltaFile
+9-9libpkg/clean_cache.c
+3-3libpkg/triggers.c
+2-2libpkg/pkg_repo_create.c
+14-143 files

pkgng/pkgng d4f6eb8libpkg pkg.c

pkg: simplify pkg_is_valid with table-driven NULL checks

Replace the chain of 9 identical if/return checks with a loop over
a table of (offsetof, name) pairs. This reduces ~50 lines to ~25,
makes the required-fields list explicit, and simplifies adding or
removing required fields in the future.
DeltaFile
+24-38libpkg/pkg.c
+24-381 files

pkgng/pkgng a81e5f5libpkg pkg_manifest.c

manifest: replace sscanf in url_decode with manual hex conversion

The sscanf("%2x") call in url_decode is expensive and pulls in
the full scanf machinery. Replace it with a simple inline hex
conversion using the (c | 32) trick to normalize letter case.
DeltaFile
+13-3libpkg/pkg_manifest.c
+13-31 files

pkgng/pkgng ba08a6dlibpkg pkg_manifest.c

manifest: replace script-type if-chains with table-driven lookups

Replace the manual if/STREQ chains in script_type_str() and
lua_script_type_str() with loops over static const lookup tables.
This makes the valid types explicit and simplifies adding new script
types in the future.
DeltaFile
+30-20libpkg/pkg_manifest.c
+30-201 files