xkb: use ssize_t for XKM byte counts

The ReadXkm* section readers return the number of bytes they consumed,
or -1 when they give up. That contract was spelled as int, while the
counters accumulating their results were a mix of int and unsigned, and
XkmGetCARD8/16/32() took the counter by reference as an int *.

XkmReadFile() also returns an unsigned, but that value is a bitmask of
the sections it could not read, not a byte count. Keeping byte counts in
unsigned variables right next to it makes the two easy to confuse, and
the confusion has a concrete cost: XkmReadFile() kept the readers'
results in an unsigned tmp, so the -1 that every one of the seven
readers it dispatches to can return became UINT_MAX. That passed the
tmp > 0 test below, and the section which had just failed to read was
marked as defined and cleared from the mask of sections reported as
missing.

Use ssize_t, the usual type for "a number of bytes, or -1 on failure",
for every byte count in this file: the section readers' return type, the
local counters, the counter XkmGetCARD8/16/32() take by reference, and
the return values of XkmSkipPadding() and XkmGetCountedString(). An
unsigned in this file now only ever denotes a bitmask, and a failing
section reader is no longer taken for a successful one.

ReadXkmKeyTypes() used a single tmp both for byte counts and as the
in/out element count handed to XkmInsureTypedSize(), which needs an
int *. That second use gets its own variable.

Signed-off-by: Mikhail Dmitrichenko <m.dmitrichenko222@gmail.com>
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2304>
(cherry picked from commit bad7edcab0)
This commit is contained in:
Mikhail Dmitrichenko 2026-09-14 12:23:40 +03:00 • committed by Enrico Weigelt
commit 3bb0f25410

View file

@ -83,7 +83,7 @@ XkmInsureSize(void *oldPtr, int oldCount, int *newCountRtrn, int elemSize)
#define XkmInsureTypedSize(p,o,n,t) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t))))
static CARD8
XkmGetCARD8(FILE * file, int *pNRead)
XkmGetCARD8(FILE * file, ssize_t *pNRead)
{
int tmp;
@ -94,7 +94,7 @@ XkmGetCARD8(FILE * file, int *pNRead)
}
static CARD16
XkmGetCARD16(FILE * file, int *pNRead)
XkmGetCARD16(FILE * file, ssize_t *pNRead)
{
CARD16 val;
@ -104,7 +104,7 @@ XkmGetCARD16(FILE * file, int *pNRead)
}
static CARD32
XkmGetCARD32(FILE * file, int *pNRead)
XkmGetCARD32(FILE * file, ssize_t *pNRead)
{
CARD32 val;
@ -113,10 +113,11 @@ XkmGetCARD32(FILE * file, int *pNRead)
return val;
}
static int
static ssize_t
XkmSkipPadding(FILE * file, unsigned pad)
{
register int i, nRead = 0;
register int i;
ssize_t nRead = 0;
for (i = 0; i < pad; i++) {
if (getc(file) != EOF)
@ -125,10 +126,11 @@ XkmSkipPadding(FILE * file, unsigned pad)
return nRead;
}
static int
static ssize_t
XkmGetCountedString(FILE * file, char *str, int max_len)
{
int count, nRead = 0;
int count;
ssize_t nRead = 0;
count = XkmGetCARD16(file, &nRead);
if (count > 0) {
@ -160,12 +162,12 @@ XkmGetCountedString(FILE * file, char *str, int max_len)
/***====================================================================***/
static int
static ssize_t
ReadXkmVirtualMods(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
{
register unsigned int i, bit;
unsigned int bound, named, tmp;
int nRead = 0;
ssize_t nRead = 0;
if (XkbAllocServerMap(xkb, XkbVirtualModsMask, 0) != Success) {
_XkbLibError(_XkbErrBadAlloc, "ReadXkmVirtualMods", 0);
@ -203,13 +205,15 @@ ReadXkmVirtualMods(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
/***====================================================================***/
static int
static ssize_t
ReadXkmKeycodes(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
{
register int i;
unsigned minKC, maxKC, nAl;
int nRead = 0;
ssize_t nRead = 0;
char name[100] = { 0 };
XkbKeyNamePtr pN;
name[0] = '\0';
@ -270,13 +274,13 @@ ReadXkmKeycodes(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
/***====================================================================***/
static int
static ssize_t
ReadXkmKeyTypes(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
{
register unsigned i, n;
unsigned num_types;
int nRead = 0;
int tmp;
ssize_t tmp, nRead = 0;
int nMapEntries;
XkbKeyTypePtr type;
xkmKeyTypeDesc wire = { 0 };
XkbKTMapEntryPtr entry;
@ -321,8 +325,9 @@ ReadXkmKeyTypes(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
_XkbLibError(_XkbErrBadTypeWidth, "ReadXkmKeyTypes", i);
return -1;
}
tmp = wire.nMapEntries;
XkmInsureTypedSize(type->map, type->map_count, &tmp, XkbKTMapEntryRec);
nMapEntries = wire.nMapEntries;
XkmInsureTypedSize(type->map, type->map_count, &nMapEntries,
XkbKTMapEntryRec);
if ((wire.nMapEntries > 0) && (type->map == NULL)) {
_XkbLibError(_XkbErrBadValue, "ReadXkmKeyTypes", wire.nMapEntries);
return -1;
@ -358,7 +363,7 @@ ReadXkmKeyTypes(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
xkmModsDesc p_entry;
XkbModsPtr pre;
XkmInsureTypedSize(type->preserve, type->map_count, &tmp,
XkmInsureTypedSize(type->preserve, type->map_count, &nMapEntries,
XkbModsRec);
if (type->preserve == NULL) {
_XkbLibError(_XkbErrBadMatch, "ReadXkmKeycodes", 0);
@ -412,7 +417,7 @@ ReadXkmKeyTypes(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
/***====================================================================***/
static int
static ssize_t
ReadXkmCompatMap(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
{
register int i;
@ -420,8 +425,11 @@ ReadXkmCompatMap(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
char name[100] = { 0 };
XkbSymInterpretPtr interp;
xkmSymInterpretDesc wire = { 0 };
unsigned tmp;
int nRead = 0;
ssize_t nRead = 0;
XkbCompatMapPtr compat;
XkbAction *act;
@ -606,14 +614,18 @@ ReadXkmCompatMap(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
return nRead;
}
static int
static ssize_t
ReadXkmIndicators(FILE * file, XkbDescPtr xkb, XkbChangesPtr changes)
{
register unsigned nLEDs;
xkmIndicatorMapDesc wire = { 0 };
char buf[100] = { 0 };
unsigned tmp;
int nRead = 0;
ssize_t nRead = 0;
if ((xkb->indicators == NULL) && (XkbAllocIndicatorMaps(xkb) != Success)) {
_XkbLibError(_XkbErrBadAlloc, "indicator rec", 0);
@ -697,14 +709,18 @@ FindTypeForKey(XkbDescPtr xkb, Atom name, unsigned width, KeySym * syms)
return &xkb->map->types[XkbTwoLevelIndex];
}
static int
static ssize_t
ReadXkmSymbols(FILE * file, XkbDescPtr xkb)
{
register int i, g, s, totalVModMaps;
xkmKeySymMapDesc wireMap = { 0 };
char buf[100] = { 0 };
unsigned minKC, maxKC, groupNames, tmp;
int nRead = 0;
ssize_t nRead = 0;
if ((tmp = XkmGetCountedString(file, buf, 100)) < 1)
return -1;
@ -883,14 +899,18 @@ ReadXkmSymbols(FILE * file, XkbDescPtr xkb)
return nRead;
}
static int
static ssize_t
ReadXkmGeomDoodad(FILE * file, XkbGeometryPtr geom, XkbSectionPtr section)
{
XkbDoodadPtr doodad;
xkmDoodadDesc doodadWire = { 0 };
char buf[100] = { 0 };
unsigned tmp;
int nRead = 0;
ssize_t nRead = 0;
nRead += XkmGetCountedString(file, buf, 100);
tmp = fread(&doodadWire, SIZEOF(xkmDoodadDesc), 1, file);
@ -938,12 +958,15 @@ ReadXkmGeomDoodad(FILE * file, XkbGeometryPtr geom, XkbSectionPtr section)
return nRead;
}
static int
static ssize_t
ReadXkmGeomOverlay(FILE * file, XkbGeometryPtr geom, XkbSectionPtr section)
{
char buf[100] = { 0 };
unsigned tmp;
int nRead = 0;
ssize_t nRead = 0;
XkbOverlayPtr ol;
XkbOverlayRowPtr row;
xkmOverlayDesc olWire = { 0 };
@ -978,15 +1001,19 @@ ReadXkmGeomOverlay(FILE * file, XkbGeometryPtr geom, XkbSectionPtr section)
return nRead;
}
static int
static ssize_t
ReadXkmGeomSection(FILE * file, XkbGeometryPtr geom)
{
register int i;
XkbSectionPtr section;
xkmSectionDesc sectionWire = { 0 };
unsigned tmp;
int nRead = 0;
ssize_t nRead = 0;
char buf[100] = { 0 };
Atom nameAtom;
nRead += XkmGetCountedString(file, buf, 100);
@ -1058,14 +1085,18 @@ ReadXkmGeomSection(FILE * file, XkbGeometryPtr geom)
return nRead;
}
static int
static ssize_t
ReadXkmGeometry(FILE * file, XkbDescPtr xkb)
{
register int i;
char buf[100] = { 0 };
unsigned tmp;
int nRead = 0;
ssize_t nRead = 0;
xkmGeometryDesc wireGeom = { 0 };
XkbGeometryPtr geom;
XkbGeometrySizesRec sizes = { 0 };
@ -1202,7 +1233,7 @@ XkmReadTOC(FILE * file, xkmFileInfo * file_info, int max_toc,
xkmSectionInfo * toc)
{
unsigned hdr, tmp;
int nRead = 0;
ssize_t nRead = 0;
unsigned i, size_toc;
hdr = (('x' << 24) | ('k' << 16) | ('m' << 8) | XkmFileVersion);
@ -1239,8 +1270,11 @@ XkmReadFile(FILE * file, unsigned need, unsigned want, XkbDescPtr *xkb)
{
register unsigned i;
xkmSectionInfo toc[MAX_TOC] = { 0 }, tmpTOC = { 0 };
xkmFileInfo fileInfo = { 0 };
unsigned tmp, nRead = 0;
ssize_t tmp, nRead = 0;
unsigned which = need | want;
if (!XkmReadTOC(file, &fileInfo, MAX_TOC, toc))