Mantis#3187. Thank you kindly, DoranZemlja for a patch that:
Adds a warning for an LSL construct that exploits a popular list memory saving hack.GenericGridServerConcept
							parent
							
								
									20eb8e54ac
								
							
						
					
					
						commit
						08c76989a7
					
				| 
						 | 
				
			
			@ -218,6 +218,43 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
 | 
			
		|||
                        localID, itemID, "on_rez", new DetectParams[0],
 | 
			
		||||
                        new object[] { new LSL_Types.LSLInteger(startParam) });
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                string[] warnings = LSLCompiler.GetWarnings();
 | 
			
		||||
 | 
			
		||||
                if (warnings != null && warnings.Length != 0)
 | 
			
		||||
                {
 | 
			
		||||
                    if (presence != null && (!postOnRez))
 | 
			
		||||
                        presence.ControllingClient.SendAgentAlertMessage(
 | 
			
		||||
                                "Script saved with warnings, check debug window!",
 | 
			
		||||
                                false);
 | 
			
		||||
 | 
			
		||||
                    foreach (string warning in warnings)
 | 
			
		||||
                    {
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            // DISPLAY WARNING INWORLD
 | 
			
		||||
                            string text = "Warning:\n" + warning;
 | 
			
		||||
                            if (text.Length > 1100)
 | 
			
		||||
                                text = text.Substring(0, 1099);
 | 
			
		||||
 | 
			
		||||
                            World.SimChat(Utils.StringToBytes(text),
 | 
			
		||||
                                    ChatTypeEnum.DebugChannel, 2147483647,
 | 
			
		||||
                                    m_host.AbsolutePosition, m_host.Name, m_host.UUID,
 | 
			
		||||
                                    false);
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (Exception e2) // LEGIT: User Scripting
 | 
			
		||||
                        {
 | 
			
		||||
                            m_log.Error("[" +
 | 
			
		||||
                                    m_scriptEngine.ScriptEngineName +
 | 
			
		||||
                                    "]: Error displaying warning in-world: " +
 | 
			
		||||
                                    e2.ToString());
 | 
			
		||||
                            m_log.Error("[" +
 | 
			
		||||
                                    m_scriptEngine.ScriptEngineName + "]: " +
 | 
			
		||||
                                    "Warning:\r\n" +
 | 
			
		||||
                                    warning);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e) // LEGIT: User Scripting
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@ namespace OpenSim.Region.ScriptEngine.Interfaces
 | 
			
		|||
    public interface ICompiler
 | 
			
		||||
    {
 | 
			
		||||
        string PerformScriptCompile(string source, string asset);
 | 
			
		||||
        string[] GetWarnings();
 | 
			
		||||
        Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>>
 | 
			
		||||
                LineMap();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -40,6 +40,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
        private int m_braceCount;       // for indentation
 | 
			
		||||
        private int m_CSharpLine;       // the current line of generated C# code
 | 
			
		||||
        private int m_CSharpCol;        // the current column of generated C# code
 | 
			
		||||
        private List<string> m_warnings = new List<string>();
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Creates an 'empty' CSCodeGenerator instance.
 | 
			
		||||
| 
						 | 
				
			
			@ -152,6 +153,23 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
            return retstr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Get the set of warnings generated during compilation.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
        /// <returns></returns>
 | 
			
		||||
        public string[] GetWarnings()
 | 
			
		||||
        {
 | 
			
		||||
            return m_warnings.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddWarning(string warning)
 | 
			
		||||
        {
 | 
			
		||||
            if (!m_warnings.Contains(warning))
 | 
			
		||||
            {
 | 
			
		||||
                m_warnings.Add(warning);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Recursively called to generate each type of node. Will generate this
 | 
			
		||||
        /// node, then all it's children.
 | 
			
		||||
| 
						 | 
				
			
			@ -446,6 +464,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
        {
 | 
			
		||||
            string retstr = String.Empty;
 | 
			
		||||
 | 
			
		||||
            List<string> identifiers = new List<string>();
 | 
			
		||||
            checkForMultipleAssignments(identifiers, a);
 | 
			
		||||
 | 
			
		||||
            retstr += GenerateNode((SYMBOL) a.kids.Pop());
 | 
			
		||||
            retstr += Generate(String.Format(" {0} ", a.AssignmentType), a);
 | 
			
		||||
            foreach (SYMBOL kid in a.kids)
 | 
			
		||||
| 
						 | 
				
			
			@ -454,6 +475,62 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
            return retstr;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // This code checks for LSL of the following forms, and generates a
 | 
			
		||||
        // warning if it finds them.
 | 
			
		||||
        //
 | 
			
		||||
        // list l = [ "foo" ]; 
 | 
			
		||||
        // l = (l=[]) + l + ["bar"];
 | 
			
		||||
        // (produces l=["foo","bar"] in SL but l=["bar"] in OS)
 | 
			
		||||
        //
 | 
			
		||||
        // integer i;
 | 
			
		||||
        // integer j;
 | 
			
		||||
        // i = (j = 3) + (j = 4) + (j = 5);
 | 
			
		||||
        // (produces j=3 in SL but j=5 in OS)
 | 
			
		||||
        //
 | 
			
		||||
        // Without this check, that code passes compilation, but does not do what
 | 
			
		||||
        // the end user expects, because LSL in SL evaluates right to left instead
 | 
			
		||||
        // of left to right.
 | 
			
		||||
        //
 | 
			
		||||
        // The theory here is that producing an error and alerting the end user that
 | 
			
		||||
        // something needs to change is better than silently generating incorrect code.
 | 
			
		||||
        private void checkForMultipleAssignments(List<string> identifiers, SYMBOL s)
 | 
			
		||||
        {
 | 
			
		||||
            if (s is Assignment)
 | 
			
		||||
            {
 | 
			
		||||
                Assignment a = (Assignment)s;
 | 
			
		||||
                string newident = null;
 | 
			
		||||
 | 
			
		||||
                if (a.kids[0] is Declaration)
 | 
			
		||||
                {
 | 
			
		||||
                    newident = ((Declaration)a.kids[0]).Id;
 | 
			
		||||
                }
 | 
			
		||||
                else if (a.kids[0] is IDENT)
 | 
			
		||||
                {
 | 
			
		||||
                    newident = ((IDENT)a.kids[0]).yytext;
 | 
			
		||||
                }
 | 
			
		||||
                else if (a.kids[0] is IdentDotExpression)
 | 
			
		||||
                {
 | 
			
		||||
                    newident = ((IdentDotExpression)a.kids[0]).Name; // +"." + ((IdentDotExpression)a.kids[0]).Member;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    AddWarning(String.Format("Multiple assignments checker internal error '{0}' at line {1} column {2}.", a.kids[0].GetType(), ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position));
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (identifiers.Contains(newident))
 | 
			
		||||
                {
 | 
			
		||||
                    AddWarning(String.Format("Multiple assignments to '{0}' at line {1} column {2}; results may differ between LSL and OSSL.", newident, ((SYMBOL)a.kids[0]).Line - 1, ((SYMBOL)a.kids[0]).Position));
 | 
			
		||||
                }
 | 
			
		||||
                identifiers.Add(newident);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int index;
 | 
			
		||||
            for (index = 0; index < s.kids.Count; index++)
 | 
			
		||||
            {
 | 
			
		||||
                checkForMultipleAssignments(identifiers, (SYMBOL) s.kids[index]);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /// <summary>
 | 
			
		||||
        /// Generates the code for a ReturnStatement node.
 | 
			
		||||
        /// </summary>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
        private Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> m_positionMap; 
 | 
			
		||||
        private ICodeConverter LSL_Converter;
 | 
			
		||||
 | 
			
		||||
        private List<string> m_warnings = new List<string>();
 | 
			
		||||
 | 
			
		||||
        // private object m_syncy = new object();
 | 
			
		||||
 | 
			
		||||
        private static CSharpCodeProvider CScodeProvider = new CSharpCodeProvider();
 | 
			
		||||
| 
						 | 
				
			
			@ -336,6 +338,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
                LSL_Converter = (ICodeConverter)new CSCodeGenerator();
 | 
			
		||||
                compileScript = LSL_Converter.Convert(Script);
 | 
			
		||||
 | 
			
		||||
                // copy converter warnings into our warnings.
 | 
			
		||||
                foreach(string warning in LSL_Converter.GetWarnings())
 | 
			
		||||
                {
 | 
			
		||||
                    AddWarning(warning);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                m_positionMap = ((CSCodeGenerator) LSL_Converter).PositionMap;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -373,6 +381,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
            return CompileFromDotNetText(compileScript, l, asset);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public string[] GetWarnings()
 | 
			
		||||
        {
 | 
			
		||||
            return m_warnings.ToArray();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void AddWarning(string warning)
 | 
			
		||||
        {
 | 
			
		||||
            if (!m_warnings.Contains(warning))
 | 
			
		||||
            {
 | 
			
		||||
                m_warnings.Add(warning);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static string CreateJSCompilerScript(string compileScript)
 | 
			
		||||
        {
 | 
			
		||||
            compileScript = String.Empty +
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -33,5 +33,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
 | 
			
		|||
    public interface ICodeConverter
 | 
			
		||||
    {
 | 
			
		||||
        string Convert(string script);
 | 
			
		||||
        string[] GetWarnings();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -516,6 +516,38 @@ namespace OpenSim.Region.ScriptEngine.XEngine
 | 
			
		|||
                        m_AddingAssemblies[assembly]++;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                string[] warnings = m_Compiler.GetWarnings();
 | 
			
		||||
 | 
			
		||||
                if (warnings != null && warnings.Length != 0)
 | 
			
		||||
                {
 | 
			
		||||
                    if (presence != null && (!postOnRez))
 | 
			
		||||
                        presence.ControllingClient.SendAgentAlertMessage("Script saved with warnings, check debug window!", false);
 | 
			
		||||
 | 
			
		||||
                    foreach (string warning in warnings)
 | 
			
		||||
                    {
 | 
			
		||||
                        try
 | 
			
		||||
                        {
 | 
			
		||||
                            // DISPLAY WARNING INWORLD
 | 
			
		||||
                            string text = "Warning:\n" + warning;
 | 
			
		||||
                            if (text.Length > 1000)
 | 
			
		||||
                                text = text.Substring(0, 1000);
 | 
			
		||||
                            World.SimChat(Utils.StringToBytes(text),
 | 
			
		||||
                                          ChatTypeEnum.DebugChannel, 2147483647,
 | 
			
		||||
                                          part.AbsolutePosition,
 | 
			
		||||
                                          part.Name, part.UUID, false);
 | 
			
		||||
                        }
 | 
			
		||||
                        catch (Exception e2) // LEGIT: User Scripting
 | 
			
		||||
                        {
 | 
			
		||||
                            m_log.Error("[XEngine]: " +
 | 
			
		||||
                                    "Error displaying warning in-world: " +
 | 
			
		||||
                                    e2.ToString());
 | 
			
		||||
                            m_log.Error("[XEngine]: " +
 | 
			
		||||
                                    "Warning:\r\n" +
 | 
			
		||||
                                    warning);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception e)
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue