aboutsummaryrefslogtreecommitdiff
path: root/squashfs-tools
diff options
context:
space:
mode:
authorPhillip Lougher <phillip@squashfs.org.uk>2013-01-04 01:46:25 +0000
committerPhillip Lougher <phillip@squashfs.org.uk>2013-01-04 01:46:25 +0000
commit89dd9158ddbc17afb88715a84ed25d4166c55bb3 (patch)
tree46b41cc7eb76c89303bd6e0878efb4ec6c0f229d /squashfs-tools
parentb0ffda8e80a296c14d9b32c6162ce6e25bc6acfb (diff)
downloadsquashfs-tools-89dd9158ddbc17afb88715a84ed25d4166c55bb3.tar.gz
action: add quoted string and back slash handling to lexical analyser
Add the ability to parse strings quoted with ", and also add the ability to backslash "special characters" that would normally be treated as end of string. Quoted and non quoted strings can be specified multiply and the strings will be concatenated together. String examples "Hello World" Hello\ World This" is a "string "So"\ is\ "this" "This \" is too" etc. Also switch to using an internal buffer (increased as necessary) to return strings from the lexical analyser, rather than dynamically allocating each string returned. This reduces unnecessary overhead (mostly strings returned from the lexical analyser are discarded without being stored, the ones that are stored can be explicitly copied when necessary), and it fixes a memory leak in the parser as returned strings are not freed. Signed-off-by: Phillip Lougher <phillip@squashfs.org.uk>
Diffstat (limited to 'squashfs-tools')
-rw-r--r--squashfs-tools/action.c80
-rw-r--r--squashfs-tools/mksquashfs.c4
2 files changed, 69 insertions, 15 deletions
diff --git a/squashfs-tools/action.c b/squashfs-tools/action.c
index 5e7afbc..2a50299 100644
--- a/squashfs-tools/action.c
+++ b/squashfs-tools/action.c
@@ -2,7 +2,7 @@
* Create a squashfs filesystem. This is a highly compressed read only
* filesystem.
*
- * Copyright (c) 2011, 2012
+ * Copyright (c) 2011, 2012, 2013
* Phillip Lougher <phillip@squashfs.org.uk>
*
* This program is free software; you can redistribute it and/or
@@ -91,9 +91,16 @@ extern int read_file(char *filename, char *type, int (parse_line)(char *));
/*
* Lexical analyser
*/
+#define STR_SIZE 256
+
static int get_token(char **string)
{
- int i;
+ /* string buffer */
+ static char *str = NULL;
+ static int size = 0;
+
+ char *str_ptr;
+ int cur_size, i, quoted;
while (1) {
if (*cur_ptr == '\0')
@@ -107,26 +114,73 @@ static int get_token(char **string)
cur_ptr ++;
}
- if (token_table[i].token == -1) { /* string */
- char *start = cur_ptr ++;
- while (1) {
- if (*cur_ptr == '\0')
+ if (token_table[i].token != -1) {
+ cur_ptr += token_table[i].size;
+ return token_table[i].token;
+ }
+
+ /* string */
+ if(str == NULL) {
+ str = malloc(STR_SIZE);
+ if(str == NULL)
+ BAD_ERROR("Out of memory in get_token\n");
+ size = STR_SIZE;
+ }
+
+ /* Initialise string being read */
+ str_ptr = str;
+ cur_size = 0;
+ quoted = 0;
+
+ while(1) {
+ while(*cur_ptr == '"') {
+ cur_ptr ++;
+ quoted = !quoted;
+ }
+
+ if(*cur_ptr == '\0') {
+ /* inside quoted string EOF, otherwise end of string */
+ if(quoted)
+ return TOK_EOF;
+ else
break;
+ }
+
+ if(!quoted) {
for(i = 0; token_table[i].token != -1; i++)
if (strncmp(cur_ptr, token_table[i].string,
token_table[i].size) == 0)
break;
if (token_table[i].token != -1)
break;
+ }
+
+ if(*cur_ptr == '\\') {
cur_ptr ++;
+ if(*cur_ptr == '\0')
+ return TOK_EOF;
}
-
- *string = strndup(start, cur_ptr - start);
- return TOK_STRING;
+
+ if(cur_size + 2 > size) {
+ char *tmp;
+
+ size = (cur_size + 1 + STR_SIZE) & ~(STR_SIZE - 1);
+
+ tmp = realloc(str, size);
+ if(tmp == NULL)
+ BAD_ERROR("Out of memory in get_token\n");
+
+ str_ptr = str_ptr - str + tmp;
+ str = tmp;
+ }
+
+ *str_ptr ++ = *cur_ptr ++;
+ cur_size ++;
}
- cur_ptr += token_table[i].size;
- return token_table[i].token;
+ *str_ptr = '\0';
+ *string = str;
+ return TOK_STRING;
}
@@ -243,7 +297,7 @@ static struct expr *parse_test(char *name)
goto failed;
}
- expr->atom.argv[i] = string;
+ expr->atom.argv[i] = strdup(string);
if (i + 1 < test->args) {
token = get_token(&string);
@@ -406,7 +460,7 @@ int parse_action(char *s)
if (argv == NULL)
BAD_ERROR("Realloc failed in parse_action\n");
- argv[args ++] = string;
+ argv[args ++] = strdup(string);
token = get_token(&string);
diff --git a/squashfs-tools/mksquashfs.c b/squashfs-tools/mksquashfs.c
index b2276cf..27d9de7 100644
--- a/squashfs-tools/mksquashfs.c
+++ b/squashfs-tools/mksquashfs.c
@@ -5016,8 +5016,8 @@ int parse_num(char *arg, int *res)
#define VERSION() \
- printf("mksquashfs version 4.2-git (2012/12/31)\n");\
- printf("copyright (C) 2012 Phillip Lougher "\
+ printf("mksquashfs version 4.2-git (2013/01/02)\n");\
+ printf("copyright (C) 2013 Phillip Lougher "\
"<phillip@squashfs.org.uk>\n\n"); \
printf("This program is free software; you can redistribute it and/or"\
"\n");\