Commit b9bb6468 authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

Lift the line length limit on config files (fixes #4338)

parent 3b7f8b1f
...@@ -183,33 +183,27 @@ int config_LoadConfigFile( vlc_object_t *p_this ) ...@@ -183,33 +183,27 @@ int config_LoadConfigFile( vlc_object_t *p_this )
rewind (file); /* no BOM, rewind */ rewind (file); /* no BOM, rewind */
} }
char line[1024]; char *line = NULL;
size_t bufsize;
ssize_t linelen;
/* Ensure consistent number formatting... */ /* Ensure consistent number formatting... */
locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL);
locale_t baseloc = uselocale (loc); locale_t baseloc = uselocale (loc);
vlc_rwlock_wrlock (&config_lock); vlc_rwlock_wrlock (&config_lock);
while (fgets (line, 1024, file) != NULL) while ((linelen = getline (&line, &bufsize, file)) != -1)
{ {
/* Ignore comments and empty lines */ line[linelen - 1] = '\0'; /* trim newline */
switch (line[0])
{
case '#':
case '[':
case '\n':
case '\0':
continue;
}
char *ptr = strchr (line, '\n'); /* Ignore comments, section and empty lines */
if (ptr != NULL) if (memchr ("#[", line[0], 3) != NULL)
*ptr = '\0'; continue;
/* look for option name */ /* look for option name */
const char *psz_option_name = line; const char *psz_option_name = line;
ptr = strchr (line, '='); char *ptr = strchr (line, '=');
if (ptr == NULL) if (ptr == NULL)
continue; /* syntax error */ continue; /* syntax error */
*ptr = '\0'; *ptr = '\0';
...@@ -261,6 +255,7 @@ int config_LoadConfigFile( vlc_object_t *p_this ) ...@@ -261,6 +255,7 @@ int config_LoadConfigFile( vlc_object_t *p_this )
} }
} }
vlc_rwlock_unlock (&config_lock); vlc_rwlock_unlock (&config_lock);
free (line);
if (ferror (file)) if (ferror (file))
{ {
...@@ -375,13 +370,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, ...@@ -375,13 +370,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
bool b_autosave ) bool b_autosave )
{ {
module_t *p_parser; module_t *p_parser;
FILE *file = NULL;
char *permanent = NULL, *temporary = NULL; char *permanent = NULL, *temporary = NULL;
char p_line[1024], *p_index2;
unsigned long i_sizebuf = 0;
char *p_bigbuffer = NULL, *p_index;
bool b_backup;
int i_index;
if( config_PrepareDir( p_this ) ) if( config_PrepareDir( p_this ) )
{ {
...@@ -389,8 +378,13 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, ...@@ -389,8 +378,13 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
return -1; return -1;
} }
file = config_OpenConfigFile( p_this ); /* List all available modules */
if( file != NULL ) module_t **list = module_list_get (NULL);
char *bigbuf = NULL;
size_t bigsize = 0;
FILE *file = config_OpenConfigFile (p_this);
if (file != NULL)
{ {
struct stat st; struct stat st;
...@@ -403,72 +397,54 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, ...@@ -403,72 +397,54 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
msg_Err (p_this, "configuration file is read-only"); msg_Err (p_this, "configuration file is read-only");
goto error; goto error;
} }
i_sizebuf = ( st.st_size < LONG_MAX ) ? st.st_size : 0;
}
p_bigbuffer = p_index = malloc( i_sizebuf+1 ); bigsize = (st.st_size < LONG_MAX) ? st.st_size : 0;
if( !p_bigbuffer ) bigbuf = malloc (bigsize + 1);
goto error; if (bigbuf == NULL)
p_bigbuffer[0] = 0; goto error;
/* List all available modules */ /* backup file into memory, we only need to backup the sections we
module_t **list = module_list_get (NULL); * won't save later on */
char *p_index = bigbuf;
char *line = NULL;
size_t bufsize;
ssize_t linelen;
bool backup = false;
/* backup file into memory, we only need to backup the sections we won't while ((linelen = getline (&line, &bufsize, file)) != -1)
* save later on */
b_backup = false;
while( file && fgets( p_line, 1024, file ) )
{
if( (p_line[0] == '[') && (p_index2 = strchr(p_line,']')))
{ {
char *p_index2;
/* we found a section, check if we need to do a backup */ if ((line[0] == '[') && (p_index2 = strchr(line,']')))
for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ )
{ {
if( ((p_index2 - &p_line[1]) /* we found a new section, check if we need to do a backup */
== (int)strlen(p_parser->psz_object_name) ) backup = true;
&& !memcmp( &p_line[1], p_parser->psz_object_name, for (int i = 0; (p_parser = list[i]) != NULL; i++)
strlen(p_parser->psz_object_name) ) )
{ {
if( !psz_module_name ) if (!strncmp (line + 1, p_parser->psz_object_name,
break; strlen (p_parser->psz_object_name))
else if( !strcmp( psz_module_name, && ((psz_module_name == NULL)
p_parser->psz_object_name ) ) || !strcmp (psz_module_name, p_parser->psz_object_name)))
{
backup = false; /* no, we will rewrite it! */
break; break;
}
} }
} }
if( list[i_index] == NULL ) /* save line if requested and line is valid (doesn't begin with a
* space, tab, or eol) */
if (backup && !memchr ("\n\t ", line[0], 3))
{ {
/* we don't have this section in our list so we need to back memcpy (p_index, line, linelen);
* it up */ p_index += linelen;
*p_index2 = 0;
#if 0
msg_Dbg( p_this, "backing up config for unknown module \"%s\"",
&p_line[1] );
#endif
*p_index2 = ']';
b_backup = true;
} }
else
{
b_backup = false;
}
}
/* save line if requested and line is valid (doesn't begin with a
* space, tab, or eol) */
if( b_backup && (p_line[0] != '\n') && (p_line[0] != ' ')
&& (p_line[0] != '\t') )
{
strcpy( p_index, p_line );
p_index += strlen( p_line );
} }
fclose (file);
file = NULL;
*p_index = '\0';
bigsize = p_index - bigbuf;
} }
if( file )
fclose( file );
file = NULL;
/* /*
* Save module config in file * Save module config in file
...@@ -533,7 +509,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, ...@@ -533,7 +509,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
vlc_rwlock_rdlock (&config_lock);*/ vlc_rwlock_rdlock (&config_lock);*/
/* Look for the selected module, if NULL then save everything */ /* Look for the selected module, if NULL then save everything */
for( i_index = 0; (p_parser = list[i_index]) != NULL; i_index++ ) for (int i = 0; (p_parser = list[i]) != NULL; i++)
{ {
module_config_t *p_item, *p_end; module_config_t *p_item, *p_end;
...@@ -647,7 +623,8 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, ...@@ -647,7 +623,8 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
/* /*
* Restore old settings from the config in file * Restore old settings from the config in file
*/ */
fputs( p_bigbuffer, file ); if (bigsize)
fwrite (bigbuf, 1, bigsize, file);
/* /*
* Flush to disk and replace atomically * Flush to disk and replace atomically
...@@ -685,7 +662,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name, ...@@ -685,7 +662,7 @@ static int SaveConfigFile( vlc_object_t *p_this, const char *psz_module_name,
free (temporary); free (temporary);
free (permanent); free (permanent);
free( p_bigbuffer ); free (bigbuf);
return 0; return 0;
error: error:
...@@ -693,7 +670,7 @@ error: ...@@ -693,7 +670,7 @@ error:
fclose( file ); fclose( file );
free (temporary); free (temporary);
free (permanent); free (permanent);
free( p_bigbuffer ); free (bigbuf);
return -1; return -1;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment