From 5a2895977ac12e21721513095061ce0239c6b3ba Mon Sep 17 00:00:00 2001 From: Mic Bowman Date: Fri, 8 Feb 2013 22:43:15 -0800 Subject: [PATCH] Make JsonStore path parsing more robust. Should fix the invalid path problem. --- .../Scripting/JsonStore/JsonStore.cs | 88 ++++++++++++------- .../JsonStore/JsonStoreScriptModule.cs | 12 ++- 2 files changed, 69 insertions(+), 31 deletions(-) diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs index 666f4ad8ea..fbee753ef3 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStore.cs @@ -49,7 +49,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private OSD m_ValueStore; + protected virtual OSD ValueStore { get; set; } protected class TakeValueCallbackClass { @@ -81,7 +81,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore protected static Regex m_ParsePassFour = new Regex("\\.+"); // expression used to validate the full path, this is canonical representation - protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)+$"); + protected static Regex m_ValidatePath = new Regex("^\\.(({[^}]+}|\\[[0-9]+\\]|\\[\\+\\])\\.)*$"); // expression used to match path components protected static Regex m_PathComponent = new Regex("\\.({[^}]+}|\\[[0-9]+\\]|\\[\\+\\]+)"); @@ -98,9 +98,17 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// /// // ----------------------------------------------------------------- - public static string CanonicalPathExpression(string path) + public static bool CanonicalPathExpression(string ipath, out string opath) { - return PathExpressionToKey(ParsePathExpression(path)); + Stack path; + if (! ParsePathExpression(ipath,out path)) + { + opath = ""; + return false; + } + + opath = PathExpressionToKey(path); + return true; } public JsonStore(string value) @@ -109,9 +117,9 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore m_ReadStore = new List(); if (String.IsNullOrEmpty(value)) - m_ValueStore = new OSDMap(); + ValueStore = new OSDMap(); else - m_ValueStore = OSDParser.DeserializeJson(value); + ValueStore = OSDParser.DeserializeJson(value); } // ----------------------------------------------------------------- @@ -121,8 +129,11 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool TestPath(string expr, bool useJson) { - Stack path = ParsePathExpression(expr); - OSD result = ProcessPathExpression(m_ValueStore,path); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) return false; @@ -140,8 +151,14 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool GetValue(string expr, out string value, bool useJson) { - Stack path = ParsePathExpression(expr); - OSD result = ProcessPathExpression(m_ValueStore,path); + Stack path; + if (! ParsePathExpression(expr,out path)) + { + value = ""; + return false; + } + + OSD result = ProcessPathExpression(ValueStore,path); return ConvertOutputValue(result,out value,useJson); } @@ -174,10 +191,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool TakeValue(string expr, bool useJson, TakeValueCallback cback) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + string pexpr = PathExpressionToKey(path); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) { m_TakeStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); @@ -205,10 +225,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- public bool ReadValue(string expr, bool useJson, TakeValueCallback cback) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + string pexpr = PathExpressionToKey(path); - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) { m_ReadStore.Add(new TakeValueCallbackClass(pexpr,useJson,cback)); @@ -235,10 +258,13 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- protected bool SetValueFromExpression(string expr, OSD ovalue) { - Stack path = ParsePathExpression(expr); + Stack path; + if (! ParsePathExpression(expr,out path)) + return false; + if (path.Count == 0) { - m_ValueStore = ovalue; + ValueStore = ovalue; return true; } @@ -249,7 +275,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore if (pexpr != "") pexpr += "."; - OSD result = ProcessPathExpression(m_ValueStore,path); + OSD result = ProcessPathExpression(ValueStore,path); if (result == null) return false; @@ -366,34 +392,36 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore /// use a stack because we process the path in inverse order later /// // ----------------------------------------------------------------- - protected static Stack ParsePathExpression(string path) + protected static bool ParsePathExpression(string expr, out Stack path) { - Stack m_path = new Stack(); + path = new Stack(); // add front and rear separators - path = "." + path + "."; + expr = "." + expr + "."; - // add separators for quoted paths - path = m_ParsePassOne.Replace(path,".$0.",-1,0); + // add separators for quoted exprs + expr = m_ParsePassOne.Replace(expr,".$0.",-1,0); // add separators for array references - path = m_ParsePassTwo.Replace(path,".$0.",-1,0); + expr = m_ParsePassTwo.Replace(expr,".$0.",-1,0); // add quotes to bare identifier - path = m_ParsePassThree.Replace(path,".{$1}",-1,0); + expr = m_ParsePassThree.Replace(expr,".{$1}",-1,0); // remove extra separators - path = m_ParsePassFour.Replace(path,".",-1,0); + expr = m_ParsePassFour.Replace(expr,".",-1,0); // validate the results (catches extra quote characters for example) - if (m_ValidatePath.IsMatch(path)) + if (m_ValidatePath.IsMatch(expr)) { - MatchCollection matches = m_PathComponent.Matches(path,0); + MatchCollection matches = m_PathComponent.Matches(expr,0); foreach (Match match in matches) - m_path.Push(match.Groups[1].Value); + path.Push(match.Groups[1].Value); + + return true; } - return m_path; + return false; } // ----------------------------------------------------------------- @@ -566,4 +594,4 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore return 0; } } -} \ No newline at end of file +} diff --git a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs index a0f89d3074..b1caaf4501 100644 --- a/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs +++ b/OpenSim/Region/OptionalModules/Scripting/JsonStore/JsonStoreScriptModule.cs @@ -285,7 +285,16 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore [ScriptInvocation] public string JsonList2Path(UUID hostID, UUID scriptID, object[] pathlist) { - return JsonStore.CanonicalPathExpression(ConvertList2Path(pathlist)); + string ipath = ConvertList2Path(pathlist); + string opath; + + if (JsonStore.CanonicalPathExpression(ipath,out opath)) + return opath; + + // This won't parse if passed to the other routines as opposed to + // returning an empty string which is a valid path and would overwrite + // the entire store + return "**INVALID**"; } // ----------------------------------------------------------------- @@ -405,6 +414,7 @@ namespace OpenSim.Region.OptionalModules.Scripting.JsonStore // ----------------------------------------------------------------- protected void GenerateRuntimeError(string msg) { + m_log.InfoFormat("[JsonStore] runtime error: {0}",msg); throw new Exception("JsonStore Runtime Error: " + msg); }