From: Daniel Mierswa <impulze@impulze.org>
To: linux-kernel@vger.kernel.org
Subject: Re: [RFC] Re: Parsing kernel parameters and escaping "
Date: Tue, 07 Jul 2009 02:54:18 +0200 [thread overview]
Message-ID: <4A529CBA.4030408@impulze.org> (raw)
In-Reply-To: <4A5282B4.8070302@impulze.org>
[-- Attachment #1.1: Type: text/plain, Size: 335 bytes --]
Second version of the patch, I accidently forgot to take care of out of
bounds checking when reaching the end of the kernel parameter line.
--
Mierswa, Daniel
If you still don't like it, that's ok: that's why I'm boss. I simply
know better than you do.
--- Linus Torvalds, comp.os.linux.advocacy, 1996/07/22
[-- Attachment #1.2: kernel.patch --]
[-- Type: text/plain, Size: 4265 bytes --]
From fe3bf00a0fc2db941fef41c44fc6d9eefad4d037 Mon Sep 17 00:00:00 2001
From: Daniel Mierswa <impulze@impulze.org>
Date: Tue, 7 Jul 2009 00:54:38 +0200
Subject: [PATCH] Attempt to handle quotes in kernel parameters
There was a limitation for kernel parameters with regards to quoting. It
wasn't possible to escape quotes or use quotes to form space-filled
values _inside_ parameters. This patch attempts to make that possible,
kernel parameters are now parsed as follows:
'"param= value"' [param= value][]
'param=" value "" combination "' [param][ value combination ]
'param=" \" test"' [param][ " test]
'"param"=another' [param][another]
---
kernel/params.c | 146 +++++++++++++++++++++++++++++++++++++++----------------
1 files changed, 104 insertions(+), 42 deletions(-)
diff --git a/kernel/params.c b/kernel/params.c
index de273ec..73de8f5 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -75,58 +75,120 @@ static int parse_one(char *param,
return -ENOENT;
}
-/* You can use " around spaces, but can't escape ". */
-/* Hyphens and underscores equivalent in parameter names. */
-static char *next_arg(char *args, char **param, char **val)
+/* handle quotes in tokens (parameter and values)
+ * '" foo bar "' => ' foo bar '
+ * '" foo \" "' => ' foo " '
+ */
+static void add_token(char ** token, char * args)
{
- unsigned int i, equals = 0;
- int in_quote = 0, quoted = 0;
- char *next;
+ char * iterator, * last_quote;
+ int in_quotes;
- if (*args == '"') {
- args++;
- in_quote = 1;
- quoted = 1;
+ in_quotes = 0;
+ last_quote = NULL;
+
+ for (iterator = args; *iterator; iterator++) {
+ if (*iterator == '\\' && *(iterator + 1) == '"') {
+ char * mover;
+
+ /* move all characters back */
+ for (mover = iterator; *mover; mover++) {
+ *mover = *(mover + 1);
+ }
+
+ continue;
+ }
+
+ if (*iterator != '"') {
+ continue;
+ }
+
+ if (in_quotes) {
+ char * mover;
+
+ /* move whole string back until current " is reached */
+ for (mover = last_quote; mover != iterator - 1; mover++) {
+ *mover = *(mover + 1);
+ }
+
+ /* ignore the current " and move the rest of the string back */
+ while (*mover) {
+ *mover = *(mover + 2);
+ mover++;
+ }
+
+ /* ignored 2 quotes, decrease the iterator */
+ iterator -= 2;
+ last_quote = NULL;
+ } else {
+ last_quote = iterator;
+ }
+
+ in_quotes = !in_quotes;
}
- for (i = 0; args[i]; i++) {
- if (args[i] == ' ' && !in_quote)
+ *token = args;
+}
+
+static char * next_arg(char * args, char ** param, char ** val)
+{
+ char * token, * next;
+ int in_quotes, is_escaped;
+
+ *param = *val = next = NULL;
+ in_quotes = is_escaped = 0;
+
+ /* tokenizer */
+ for (token = args; *token; token++) {
+ /* parameter or value is finished */
+ if (!in_quotes && *token == ' ') {
+ *token = '\0';
+
+ /* there're still characters in the parameter line */
+ next = token + 1;
+
+ /* remove trailing whitespace */
+ while (*next == ' ') {
+ next++;
+ }
+
break;
- if (equals == 0) {
- if (args[i] == '=')
- equals = i;
}
- if (args[i] == '"')
- in_quote = !in_quote;
- }
- *param = args;
- if (!equals)
- *val = NULL;
- else {
- args[equals] = '\0';
- *val = args + equals + 1;
-
- /* Don't include quotes in value. */
- if (**val == '"') {
- (*val)++;
- if (args[i-1] == '"')
- args[i-1] = '\0';
+ /* parameter/value split */
+ if (!in_quotes && *token == '=' && !*param) {
+ *token = '\0';
+ add_token(param, args);
+ args = token + 1;
+ continue;
}
- if (quoted && args[i-1] == '"')
- args[i-1] = '\0';
+
+ if (!is_escaped && *token == '\\') {
+ is_escaped = 1;
+ continue;
+ }
+
+ if (*token == '"' && !is_escaped) {
+ in_quotes = !in_quotes;
+ }
+
+ /* always reset escape value, only " needs it */
+ is_escaped = 0;
}
- if (args[i]) {
- args[i] = '\0';
- next = args + i + 1;
- } else
- next = args + i;
+ if (!*param) {
+ add_token(param, args);
+ } else {
+ add_token(val, args);
+ }
+
+ /* there're parameters left in the command line */
+ if (next) {
+ return next;
+ }
- /* Chew up trailing spaces. */
- while (*next == ' ')
- next++;
- return next;
+ /* end of the line */
+ return token;
}
/* Args looks like "foo=bar,bar2 baz=fuz wiz". */
--
1.6.3.3
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 198 bytes --]
next prev parent reply other threads:[~2009-07-07 0:54 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-05 13:54 Parsing kernel parameters and escaping " Daniel Mierswa
2009-07-06 23:03 ` [RFC] " Daniel Mierswa
2009-07-06 23:05 ` Daniel Mierswa
2009-07-07 0:54 ` Daniel Mierswa [this message]
2009-07-12 9:41 ` Rusty Russell
2009-07-12 17:59 ` Daniel Mierswa
2009-07-12 23:57 ` Rusty Russell
2009-07-13 2:49 ` Daniel Mierswa
2009-07-14 2:49 ` Rusty Russell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A529CBA.4030408@impulze.org \
--to=impulze@impulze.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox