public inbox for pbs-devel@lists.proxmox.com
 help / color / mirror / Atom feed
* [pbs-devel] [RFC PATCH proxmox-backup] ui: implement quoted strings in parsePropertyString
@ 2022-03-09 14:16 Dominik Csapak
  0 siblings, 0 replies; only message in thread
From: Dominik Csapak @ 2022-03-09 14:16 UTC (permalink / raw)
  To: pbs-devel

like we do in our rust propertystring parser.
code is heavily inspired by the rust code.

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
---
if we want to go the js route and not use wasm + rust code for this

i sent it as rfc for pbs (since there we have that property string
implementation), but we actually want this to live in wt, and use it in
pve and pbs both when pve gains support for these.

@thomas, the code is my attempt to write the parser as close to the
rust code as it was sensible, but i'm sure there are some js specific
improvements to be done here. i'll look over it again tomorrow
with fresh eyes and mind, but if you see some things, don't hold back ;)

 www/Utils.js | 100 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 82 insertions(+), 18 deletions(-)

diff --git a/www/Utils.js b/www/Utils.js
index 36a94211..87809364 100644
--- a/www/Utils.js
+++ b/www/Utils.js
@@ -62,32 +62,96 @@ Ext.define('PBS.Utils', {
 	return path.indexOf(PBS.Utils.dataStorePrefix) === 0;
     },
 
+    parseQuotedString: function(value) {
+	let data = "";
+	let was_backslash = false;
+	if (value[0] !== '"') {
+	    throw "not a quoted string";
+	}
+	value = value.slice(1);
+	for (let i = 0; ; i++) {
+	    if (i === value.length) {
+		throw "invalid quoted string";
+	    }
+	    if (was_backslash) {
+		was_backslash = false;
+		switch (value[i]) {
+		    case '"': data += '"'; break;
+		    case '\\': data += '\\'; break;
+		    case 'n': data += '\n'; break;
+		    default:
+			throw "unsupported escape sequence";
+		}
+	    } else {
+		switch (value[i]) {
+		    case '"': return [data, i+1];
+		    case '\\': was_backslash = true; break;
+		    default:
+			data += value[i];
+		}
+	    }
+	}
+    },
+
     parsePropertyString: function(value, defaultKey) {
-	var res = {},
-	    error;
+	let res = {};
 
 	if (typeof value !== 'string' || value === '') {
 	    return res;
 	}
 
-	Ext.Array.each(value.split(','), function(p) {
-	    var kv = p.split('=', 2);
-	    if (Ext.isDefined(kv[1])) {
-		res[kv[0]] = kv[1];
-	    } else if (Ext.isDefined(defaultKey)) {
-		if (Ext.isDefined(res[defaultKey])) {
-		    error = 'defaultKey may be only defined once in propertyString';
-		    return false; // break
+	try {
+	    while (value.length > 0) {
+		let key, current;
+		if (value[0] !== '"') {
+		    let idx = value.search(/[,=]/);
+		    if (idx !== -1 && value[idx] === '=') {
+			key = value.slice(0, idx);
+			value = value.slice(idx + 1);
+			if (Ext.isDefined(res[key])) {
+			    throw `duplicate key ${key} found`;
+			}
+		    }
+
+		    if (value[0] !== '"') {
+			let next_idx = value.search(/,/);
+			if (next_idx === -1) {
+			    current = value;
+			    value = "";
+			} else {
+			    current = value.slice(0, next_idx);
+			    value = value.slice(next_idx + 1);
+			}
+		    }
 		}
-		res[defaultKey] = kv[0];
-	    } else {
-		error = 'invalid propertyString, not a key=value pair and no defaultKey defined';
-		return false; // break
-	    }
-	    return true;
-	});
 
-	if (error !== undefined) {
+		if (key === undefined) {
+		    if (Ext.isDefined(defaultKey)) {
+			if (Ext.isDefined(res[defaultKey])) {
+			    throw 'defaultKey may be only defined once in propertyString';
+			}
+			key = defaultKey;
+		    } else {
+			throw "value without key and no defaultKey";
+		    }
+		}
+		if (current === undefined) {
+		    let [val, idx] = PVE.Parser.parseQuotedString(value);
+		    current = val;
+		    value = value.slice(idx + 1);
+		}
+
+		res[key] = current;
+
+		if (value.length > 0) {
+		    if (value[0] === ',') {
+			value = value.slice(1);
+		    } else {
+			throw "garbage after value";
+		    }
+		}
+	    }
+	} catch (error) {
 	    console.error(error);
 	    return null;
 	}
-- 
2.30.2





^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-03-09 14:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-09 14:16 [pbs-devel] [RFC PATCH proxmox-backup] ui: implement quoted strings in parsePropertyString Dominik Csapak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal