dix: add support for reserved extension slots

In order to allow extensions being registered at fixed opcodes,
there need to be a reserved slot range. Thus `NumExtensions` needs
to start out with the upper ceiling of the reserved slot space.
Thus it cannot tell whether the array already had been allocated,
and some slots now may be NULL, so we need some extra checks.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-03-25 15:19:51 +01:00
parent d536bd7f66
commit 4560d9a3fe
2 changed files with 49 additions and 13 deletions

View File

@ -49,6 +49,7 @@ SOFTWARE.
#include <X11/X.h>
#include <X11/Xproto.h>
#include "dix/extension_priv.h"
#include "dix/registry_priv.h"
#include "misc.h"
@ -66,7 +67,12 @@ static ExtensionEntry **extensions = (ExtensionEntry **) NULL;
int lastEvent = EXTENSION_EVENT_BASE;
static int lastError = FirstExtensionError;
static unsigned int NumExtensions = 0;
static unsigned int NumExtensions = RESERVED_EXTENSIONS;
static int checkReserved(const char* name)
{
return -1;
}
ExtensionEntry *
AddExtension(const char *name, int NumEvents, int NumErrors,
@ -75,7 +81,10 @@ AddExtension(const char *name, int NumEvents, int NumErrors,
void (*CloseDownProc) (ExtensionEntry * e),
unsigned short (*MinorOpcodeProc) (ClientPtr c3))
{
int i;
if (!extensions)
extensions = calloc(NumExtensions, sizeof(ExtensionEntry*));
if (!extensions)
return NULL;
if (!MainProc || !SwappedMainProc || !MinorOpcodeProc)
return ((ExtensionEntry *) NULL);
@ -95,14 +104,19 @@ AddExtension(const char *name, int NumEvents, int NumErrors,
if (!ext->name)
goto badalloc;
i = NumExtensions;
int i = checkReserved(ext->name);
if (i == -1) {
i = NumExtensions;
ExtensionEntry **newexts = reallocarray(extensions, i + 1, sizeof(ExtensionEntry *));
if (!newexts)
goto badalloc;
ExtensionEntry **newexts = reallocarray(extensions, i + 1, sizeof(ExtensionEntry *));
if (!newexts)
goto badalloc;
NumExtensions++;
extensions = newexts;
} else {
i = i - EXTENSION_BASE;
}
NumExtensions++;
extensions = newexts;
extensions[i] = ext;
ext->index = i;
ext->base = i + EXTENSION_BASE;
@ -150,11 +164,15 @@ badalloc:
ExtensionEntry *
CheckExtension(const char *extname)
{
if (!extensions)
return NULL;
for (int i = 0; i < NumExtensions; i++) {
if (extensions[i] &&
extensions[i]->name &&
strcmp(extensions[i]->name, extname) == 0)
strcmp(extensions[i]->name, extname) == 0) {
return extensions[i];
}
}
return NULL;
}
@ -165,7 +183,7 @@ CheckExtension(const char *extname)
ExtensionEntry *
GetExtensionEntry(int major)
{
if (major < EXTENSION_BASE)
if ((major < EXTENSION_BASE) || !extensions)
return NULL;
major -= EXTENSION_BASE;
if (major >= NumExtensions)
@ -182,9 +200,12 @@ StandardMinorOpcode(ClientPtr client)
void
CloseDownExtensions(void)
{
int i;
if (!extensions)
return;
for (i = NumExtensions - 1; i >= 0; i--) {
for (int i = NumExtensions - 1; i >= 0; i--) {
if (!extensions[i])
continue;
if (extensions[i]->CloseDown)
extensions[i]->CloseDown(extensions[i]);
NumExtensions = i;
@ -195,6 +216,7 @@ CloseDownExtensions(void)
}
free(extensions);
extensions = (ExtensionEntry **) NULL;
NumExtensions = RESERVED_EXTENSIONS;
lastEvent = EXTENSION_EVENT_BASE;
lastError = FirstExtensionError;
}
@ -202,6 +224,8 @@ CloseDownExtensions(void)
static Bool
ExtensionAvailable(ClientPtr client, ExtensionEntry *ext)
{
if (!ext)
return FALSE;
if (XaceHookExtAccess(client, ext) != Success)
return FALSE;
if (!ext->base)
@ -262,7 +286,7 @@ ProcListExtensions(ClientPtr client)
};
buffer = NULL;
if (NumExtensions) {
if (NumExtensions && extensions) {
int i;
for (i = 0; i < NumExtensions; i++) {

12
dix/extension_priv.h Normal file
View File

@ -0,0 +1,12 @@
/* SPDX-License-Identifier: MIT OR X112
*
* Copyright © 2024 Enrico Weigelt, metux IT consult <info@metux.net>
*/
#ifndef _XSERVER_EXTENSION_PRIV_H
#define _XSERVER_EXTENSION_PRIV_H
#include "misc.h"
#define RESERVED_EXTENSIONS 2
#endif /* _XSERVER_EXTENSION_PRIV_H */