Skip to content

Commit 71d0fc0

Browse files
committed
lib: workaround shlib-{provides,requires} being satisfied by 32bit
1 parent 0310570 commit 71d0fc0

File tree

1 file changed

+52
-17
lines changed

1 file changed

+52
-17
lines changed

lib/transaction_check_shlibs.c

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*-
22
* Copyright (c) 2014-2020 Juan Romero Pardines.
3+
* Copyright (c) 2025-2026 Duncan Overbruck <mail@duncano.de>.
34
* All rights reserved.
45
*
56
* Redistribution and use in source and binary forms, with or without
@@ -56,6 +57,10 @@ struct shlib_entry {
5657
struct shlib_ctx {
5758
struct xbps_handle *xhp;
5859
struct shlib_entry *entries;
60+
// XXX: _32bit is a big hack because there is nothing allowing us
61+
// to separate 32bit shlibs from normal shlibs, so we collect them
62+
// in a separate hashmap based on the package name ending with `-32bit`.
63+
struct shlib_entry *entries_32bit;
5964
xbps_dictionary_t seen;
6065
xbps_array_t missing;
6166
};
@@ -69,9 +74,9 @@ shlib_entry_find(struct shlib_entry *head, const char *name)
6974
}
7075

7176
static struct shlib_entry *
72-
shlib_entry_get(struct shlib_ctx *ctx, const char *name)
77+
shlib_entry_get(struct shlib_entry **head, const char *name)
7378
{
74-
struct shlib_entry *res = shlib_entry_find(ctx->entries, name);
79+
struct shlib_entry *res = shlib_entry_find(*head, name);
7580
if (res)
7681
return res;
7782
res = calloc(1, sizeof(*res));
@@ -80,25 +85,34 @@ shlib_entry_get(struct shlib_ctx *ctx, const char *name)
8085
return NULL;
8186
}
8287
res->name = name;
83-
HASH_ADD_STR(ctx->entries, name, res);
88+
HASH_ADD_STR(*head, name, res);
8489
return res;
8590
}
8691

8792
static int
88-
collect_shlib_array(struct shlib_ctx *ctx, xbps_array_t array)
93+
collect_shlib_array(struct shlib_entry **head, xbps_array_t array)
8994
{
9095
for (unsigned int i = 0; i < xbps_array_count(array); i++) {
9196
struct shlib_entry *entry;
9297
const char *shlib = NULL;
9398
if (!xbps_array_get_cstring_nocopy(array, i, &shlib))
9499
return -EINVAL;
95-
entry = shlib_entry_get(ctx, shlib);
100+
entry = shlib_entry_get(head, shlib);
96101
if (!entry)
97102
return -errno;
98103
}
99104
return 0;
100105
}
101106

107+
static bool
108+
endswith(const char *s, const char *end, size_t len)
109+
{
110+
size_t slen = strlen(s);
111+
if (slen <= len)
112+
return false;
113+
return strcmp(s + (slen - len), end) == 0;
114+
}
115+
102116
static int
103117
collect_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
104118
{
@@ -134,7 +148,11 @@ collect_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
134148

135149
array = xbps_dictionary_get(pkgd, "shlib-provides");
136150
if (array) {
137-
int r = collect_shlib_array(ctx, array);
151+
bool is32bit =
152+
endswith(pkgname, "-32bit", sizeof("-32bit") - 1);
153+
int r = collect_shlib_array(
154+
!is32bit ? &ctx->entries : &ctx->entries_32bit,
155+
array);
138156
if (r < 0)
139157
return r;
140158
}
@@ -161,7 +179,11 @@ collect_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
161179

162180
array = xbps_dictionary_get(pkgd, "shlib-provides");
163181
if (array) {
164-
int r = collect_shlib_array(ctx, array);
182+
bool is32bit =
183+
endswith(pkgname, "-32bit", sizeof("-32bit") - 1);
184+
int r = collect_shlib_array(
185+
!is32bit ? &ctx->entries : &ctx->entries_32bit,
186+
array);
165187
if (r < 0)
166188
return r;
167189
}
@@ -174,34 +196,41 @@ collect_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
174196
static int
175197
check_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
176198
{
199+
char msg[1024];
177200
xbps_object_iterator_t iter;
178201
xbps_object_t obj;
179202

180203
for (unsigned int i = 0; i < xbps_array_count(pkgs); i++) {
181204
xbps_array_t array;
182205
xbps_dictionary_t pkgd = xbps_array_get(pkgs, i);
183206
xbps_trans_type_t ttype = xbps_transaction_pkg_type(pkgd);
207+
const char *pkgname = NULL;
208+
bool is32bit;
184209

185210
if (ttype == XBPS_TRANS_HOLD || ttype == XBPS_TRANS_REMOVE)
186211
continue;
187212

213+
if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgname", &pkgname))
214+
return -EINVAL;
215+
216+
is32bit = endswith(pkgname, "-32bit", sizeof("-32bit") - 1);
217+
188218
array = xbps_dictionary_get(pkgd, "shlib-requires");
189219
if (!array)
190220
continue;
191221
for (unsigned int j = 0; j < xbps_array_count(array); j++) {
192222
const char *pkgver = NULL;
193223
const char *shlib = NULL;
194-
char *missing;
195224
if (!xbps_array_get_cstring_nocopy(array, j, &shlib))
196225
return -EINVAL;
197-
if (shlib_entry_find(ctx->entries, shlib))
226+
if (shlib_entry_find(!is32bit ? ctx->entries : ctx->entries_32bit, shlib))
198227
continue;
199228
if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver))
200229
return -EINVAL;
201-
missing = xbps_xasprintf(
202-
"%s: broken, unresolvable shlib `%s'",
203-
pkgver, shlib);
204-
if (!xbps_array_add_cstring_nocopy(ctx->missing, missing))
230+
snprintf(msg, sizeof(msg),
231+
"%s: broken, unresolvable shlib `%s'", pkgver,
232+
shlib);
233+
if (!xbps_array_add_cstring_nocopy(ctx->missing, msg))
205234
return xbps_error_oom();
206235
}
207236
}
@@ -214,6 +243,7 @@ check_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
214243
xbps_array_t array;
215244
xbps_dictionary_t pkgd;
216245
const char *pkgname = NULL;
246+
bool is32bit;
217247

218248
pkgname = xbps_dictionary_keysym_cstring_nocopy(obj);
219249
/* ignore internal objs */
@@ -225,23 +255,24 @@ check_shlibs(struct shlib_ctx *ctx, xbps_array_t pkgs)
225255
if (xbps_dictionary_get(ctx->seen, pkgname))
226256
continue;
227257

258+
is32bit = endswith(pkgname, "-32bit", sizeof("-32bit") - 1);
259+
228260
array = xbps_dictionary_get(pkgd, "shlib-requires");
229261
if (!array)
230262
continue;
231263
for (unsigned int i = 0; i < xbps_array_count(array); i++) {
232264
const char *pkgver = NULL;
233265
const char *shlib = NULL;
234-
char *missing;
235266
if (!xbps_array_get_cstring_nocopy(array, i, &shlib))
236267
return -EINVAL;
237-
if (shlib_entry_find(ctx->entries, shlib))
268+
if (shlib_entry_find(!is32bit ? ctx->entries : ctx->entries_32bit, shlib))
238269
continue;
239270
if (!xbps_dictionary_get_cstring_nocopy(pkgd, "pkgver", &pkgver))
240271
return -EINVAL;
241-
missing = xbps_xasprintf(
272+
snprintf(msg, sizeof(msg),
242273
"%s: broken, unresolvable shlib `%s'", pkgver,
243274
shlib);
244-
if (!xbps_array_add_cstring_nocopy(ctx->missing, missing))
275+
if (!xbps_array_add_cstring_nocopy(ctx->missing, msg))
245276
return xbps_error_oom();
246277
}
247278
}
@@ -276,6 +307,10 @@ xbps_transaction_check_shlibs(struct xbps_handle *xhp, xbps_array_t pkgs)
276307
HASH_DEL(ctx.entries, entry);
277308
free(entry);
278309
}
310+
HASH_ITER(hh, ctx.entries_32bit, entry, tmp) {
311+
HASH_DEL(ctx.entries_32bit, entry);
312+
free(entry);
313+
}
279314
if (ctx.seen)
280315
xbps_object_release(ctx.seen);
281316
return r == 0;

0 commit comments

Comments
 (0)