aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLukas Fleischer2013-06-04 14:47:53 +0000
committerJason A. Donenfeld2013-08-12 13:14:10 -0600
commit50e70d32f056c20db760328774d27524648fb739 (patch)
treef11c0bfac7b63143523faaa95e713d52a7cc1cf1
parent820df9c66073b1345397642b46f1885b40b620e3 (diff)
downloadcgit-50e70d32f056c20db760328774d27524648fb739.tar.gz
cgit-50e70d32f056c20db760328774d27524648fb739.tar.bz2
cgit-50e70d32f056c20db760328774d27524648fb739.zip
Use strbuf for reading configuration files
Use struct strbuf from Git instead of fixed-size buffers to remove the limit on the length of configuration file lines and refactor read_config_line() to improve readability. Note that this also fixes a buffer overflow that existed with the original fixed-size buffer implementation. Signed-off-by: Lukas Fleischer <cgit@cryptocrack.de>
-rw-r--r--configfile.c64
-rw-r--r--configfile.h2
2 files changed, 35 insertions, 31 deletions
diff --git a/configfile.c b/configfile.c
index d98989c..31fe5c8 100644
--- a/configfile.c
+++ b/configfile.c
@@ -31,45 +31,45 @@ static void skip_line(FILE *f)
31 ; 31 ;
32} 32}
33 33
34static int read_config_line(FILE *f, char *line, const char **value, int bufsize) 34static int read_config_line(FILE *f, struct strbuf *name, struct strbuf *value)
35{ 35{
36 int i = 0, isname = 0; 36 int c = next_char(f);
37 37
38 *value = NULL; 38 strbuf_reset(name);
39 while (i < bufsize - 1) { 39 strbuf_reset(value);
40 int c = next_char(f);
41 if (!isname && (c == '#' || c == ';')) {
42 skip_line(f);
43 continue;
44 }
45 if (!isname && isspace(c))
46 continue;
47 40
48 if (c == '=' && !*value) { 41 /* Skip comments and preceding spaces. */
49 line[i] = 0; 42 for(;;) {
50 *value = &line[i + 1]; 43 if (c == '#' || c == ';')
51 } else if (c == '\n' && !isname) { 44 skip_line(f);
52 i = 0; 45 else if (!isspace(c))
53 continue;
54 } else if (c == '\n' || c == EOF) {
55 line[i] = 0;
56 break; 46 break;
57 } else { 47 c = next_char(f);
58 line[i] = c;
59 }
60 isname = 1;
61 i++;
62 } 48 }
63 line[i + 1] = 0; 49
64 return i; 50 /* Read variable name. */
51 while (c != '=') {
52 if (c == '\n' || c == EOF)
53 return 0;
54 strbuf_addch(name, c);
55 c = next_char(f);
56 }
57
58 /* Read variable value. */
59 c = next_char(f);
60 while (c != '\n' && c != EOF) {
61 strbuf_addch(value, c);
62 c = next_char(f);
63 }
64
65 return 1;
65} 66}
66 67
67int parse_configfile(const char *filename, configfile_value_fn fn) 68int parse_configfile(const char *filename, configfile_value_fn fn)
68{ 69{
69 static int nesting; 70 static int nesting;
70 int len; 71 struct strbuf name = STRBUF_INIT;
71 char line[256]; 72 struct strbuf value = STRBUF_INIT;
72 const char *value;
73 FILE *f; 73 FILE *f;
74 74
75 /* cancel deeply nested include-commands */ 75 /* cancel deeply nested include-commands */
@@ -78,10 +78,12 @@ int parse_configfile(const char *filename, configfile_value_fn fn)
78 if (!(f = fopen(filename, "r"))) 78 if (!(f = fopen(filename, "r")))
79 return -1; 79 return -1;
80 nesting++; 80 nesting++;
81 while ((len = read_config_line(f, line, &value, sizeof(line))) > 0) 81 while (read_config_line(f, &name, &value))
82 fn(line, value); 82 fn(name.buf, value.buf);
83 nesting--; 83 nesting--;
84 fclose(f); 84 fclose(f);
85 strbuf_release(&name);
86 strbuf_release(&value);
85 return 0; 87 return 0;
86} 88}
87 89
diff --git a/configfile.h b/configfile.h
index 04235e5..af7ca19 100644
--- a/configfile.h
+++ b/configfile.h
@@ -1,6 +1,8 @@
1#ifndef CONFIGFILE_H 1#ifndef CONFIGFILE_H
2#define CONFIGFILE_H 2#define CONFIGFILE_H
3 3
4#include "cgit.h"
5
4typedef void (*configfile_value_fn)(const char *name, const char *value); 6typedef void (*configfile_value_fn)(const char *name, const char *value);
5 7
6extern int parse_configfile(const char *filename, configfile_value_fn fn); 8extern int parse_configfile(const char *filename, configfile_value_fn fn);