config: Preserve section data when parsing duplicate files

Previously, when parsing multiple configuration files containing the same
section names, only the last occurrence of each section would be retained.
Earlier definitions were silently discarded due to unconditional memory
allocation and overwriting of pointers during parsing.

This resulted in incomplete or incorrect configuration state when users
intended to merge or extend configuration through multiple files.

The section parsing functions in Files.c, Flags.c, and Module.c now
accept existing section pointers. These functions allocate new memory only
if the input pointer is NULL, preserving earlier data when re-parsing.

read.c has been updated to detect and pass existing section pointers when
encountering duplicate sections across files, preventing loss of prior content.

With these changes, the parser properly accumulates and merges configuration
data across multiple files, ensuring that all relevant settings are preserved.

Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/467
Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2045>
This commit is contained in:
liuheng 2025-07-10 11:39:40 +08:00 committed by Marge Bot
parent 0d39d7a8f3
commit 9b6f72395a
5 changed files with 33 additions and 15 deletions

View file

@ -76,14 +76,20 @@ static const xf86ConfigSymTabRec FilesTab[] = {
#define CLEANUP xf86freeFiles
XF86ConfFilesPtr
xf86parseFilesSection(void)
xf86parseFilesSection(XF86ConfFilesPtr ptr)
{
int i, j;
int k, l;
char *str;
int token;
parsePrologue(XF86ConfFilesPtr, XF86ConfFilesRec)
if (ptr == NULL)
{
if((ptr=calloc(1, sizeof(XF86ConfFilesRec))) == NULL)
{
return NULL;
}
}
while ((token = xf86getToken(FilesTab)) != ENDSECTION) {
switch (token) {

View file

@ -84,11 +84,17 @@ static const xf86ConfigSymTabRec ServerFlagsTab[] = {
#define CLEANUP xf86freeFlags
XF86ConfFlagsPtr
xf86parseFlagsSection(void)
xf86parseFlagsSection(XF86ConfFlagsPtr ptr)
{
int token;
parsePrologue(XF86ConfFlagsPtr, XF86ConfFlagsRec)
if (ptr == NULL)
{
if((ptr=calloc(1, sizeof(XF86ConfFlagsRec))) == NULL)
{
return NULL;
}
}
while ((token = xf86getToken(ServerFlagsTab)) != ENDSECTION) {
int hasvalue = FALSE;

View file

@ -118,11 +118,17 @@ xf86parseModuleSubSection(XF86LoadPtr head, char *name)
}
XF86ConfModulePtr
xf86parseModuleSection(void)
xf86parseModuleSection(XF86ConfModulePtr ptr)
{
int token;
parsePrologue(XF86ConfModulePtr, XF86ConfModuleRec)
if (ptr == NULL)
{
if((ptr=calloc(1, sizeof(XF86ConfModuleRec))) == NULL)
{
return NULL;
}
}
while ((token = xf86getToken(ModuleTab)) != ENDSECTION) {
switch (token) {

View file

@ -38,12 +38,12 @@ void xf86freeDeviceList(XF86ConfDevicePtr ptr);
int xf86validateDevice(XF86ConfigPtr p);
/* Files.c */
XF86ConfFilesPtr xf86parseFilesSection(void);
XF86ConfFilesPtr xf86parseFilesSection(XF86ConfFilesPtr ptr);
void xf86printFileSection(FILE * cf, XF86ConfFilesPtr ptr);
void xf86freeFiles(XF86ConfFilesPtr p);
/* Flags.c */
XF86ConfFlagsPtr xf86parseFlagsSection(void);
XF86ConfFlagsPtr xf86parseFlagsSection(XF86ConfFlagsPtr ptr);
void xf86printServerFlagsSection(FILE * f, XF86ConfFlagsPtr flags);
void xf86freeFlags(XF86ConfFlagsPtr flags);
@ -68,7 +68,7 @@ void xf86freeLayoutList(XF86ConfLayoutPtr ptr);
int xf86validateLayout(XF86ConfigPtr p);
/* Module.c */
XF86ConfModulePtr xf86parseModuleSection(void);
XF86ConfModulePtr xf86parseModuleSection(XF86ConfModulePtr ptr);
void xf86printModuleSection(FILE * cf, XF86ConfModulePtr ptr);
extern _X_EXPORT XF86LoadPtr xf86addNewLoadDirective(XF86LoadPtr head,
const char *name, int type,

View file

@ -113,12 +113,12 @@ xf86readConfigFile(void)
if (xf86nameCompare(xf86_lex_val.str, "files") == 0) {
free(xf86_lex_val.str);
xf86_lex_val.str = NULL;
HANDLE_RETURN(conf_files, xf86parseFilesSection());
HANDLE_RETURN(conf_files, xf86parseFilesSection(ptr->conf_files));
}
else if (xf86nameCompare(xf86_lex_val.str, "serverflags") == 0) {
free(xf86_lex_val.str);
xf86_lex_val.str = NULL;
HANDLE_RETURN(conf_flags, xf86parseFlagsSection());
HANDLE_RETURN(conf_flags, xf86parseFlagsSection(ptr->conf_flags));
}
else if (xf86nameCompare(xf86_lex_val.str, "pointer") == 0) {
free(xf86_lex_val.str);
@ -177,7 +177,7 @@ xf86readConfigFile(void)
else if (xf86nameCompare(xf86_lex_val.str, "module") == 0) {
free(xf86_lex_val.str);
xf86_lex_val.str = NULL;
HANDLE_RETURN(conf_modules, xf86parseModuleSection());
HANDLE_RETURN(conf_modules, xf86parseModuleSection(ptr->conf_modules));
}
else if (xf86nameCompare(xf86_lex_val.str, "serverlayout") == 0) {
free(xf86_lex_val.str);