diff --git a/dix/extension.c b/dix/extension.c index fa64429e3..d6d9cd39f 100644 --- a/dix/extension.c +++ b/dix/extension.c @@ -49,6 +49,7 @@ SOFTWARE. #include #include +#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++) { diff --git a/dix/extension_priv.h b/dix/extension_priv.h new file mode 100644 index 000000000..b0c768485 --- /dev/null +++ b/dix/extension_priv.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: MIT OR X112 + * + * Copyright © 2024 Enrico Weigelt, metux IT consult + */ +#ifndef _XSERVER_EXTENSION_PRIV_H +#define _XSERVER_EXTENSION_PRIV_H + +#include "misc.h" + +#define RESERVED_EXTENSIONS 2 + +#endif /* _XSERVER_EXTENSION_PRIV_H */