This project has moved. For the latest updates, please go here.

Prevent override of application assigned objects and values?

Jan 7, 2012 at 11:50 PM

On your home page you have the cool silverlight demo.  If I type in there:

console = 1

...then the console.log and so on, no longer works because console now equals 1.

Is it possible to prevent this overriding of built in objects and values?

Thanks.

Coordinator
Jan 8, 2012 at 3:56 AM

Yes, you can use Object.defineProperty.  For example, to protect the console variable from modification and deletion, do the following:

Object.defineProperty(this, "console", {
  writable: false,
  configurable: false
});
Jan 8, 2012 at 2:36 PM
Edited Jan 8, 2012 at 2:36 PM

Sorry, where do I put this code?

{code:c#}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Jurassic;
using Jurassic.Library;

namespace jurastest
{
    class Program
    {
        static void Main(string[] args)
        {
            ScriptEngine js = new ScriptEngine();
            js.SetGlobalValue("console", new console(js));

            while (true)
            {
                Console.Write("> ");
                String src = Console.ReadLine();

                try
                {
                    object result = js.Evaluate(src);

                    if (!(result is Jurassic.Undefined))
                        Console.WriteLine("js: " + result);
                }
                catch (JavaScriptException e)
                {
                    Console.WriteLine("error: " + e.Message + " at line " + e.LineNumber);
                }
            }
        }
    }

    class console : ObjectInstance
    {
        public console(ScriptEngine engine)
            : base(engine)
        {
            this.PopulateFunctions();
        }

        [JSFunction(Name = "log")]
        public static void log(string text)
        {
            Console.WriteLine(text);
        }
    }
}

{code:c#}

Thanks. 

Jan 8, 2012 at 4:53 PM

OK, I see your reply is a javascript.  What I mean is can I set an equilivant of your code from C# within my app?

Thanks.

Coordinator
Jan 8, 2012 at 9:40 PM
Edited Jan 8, 2012 at 9:41 PM

The direct equivalent is the following:

var attributes = new ObjectInstance(js);
attributes["writable"] = false;
attributes["configurable"] = false;
ObjectConstructor.DefineProperty(js.Global, "console", attributes);

But there is an easier way.  Replace your SetGlobalValue line with the following:

js.Global.DefineProperty("console", new PropertyDescriptor(
    new console(js), PropertyAttributes.Sealed), throwOnError: true);
Jan 8, 2012 at 11:21 PM

Hi there.  Thanks for your reply.

Your code successfully prevents "console" from being overridden, however "console.log" can still be overridden.  Can this also be preventable?

Thank you.

Coordinator
Jan 9, 2012 at 1:07 AM

Yes, via the same technique. 

var console = new console(js); // Previously defined.
console.DefineProperty("log", new PropertyDescriptor(
  console["log"], PropertyAttributes.Sealed), throwOnError: true);
Jan 9, 2012 at 12:41 PM

Thank you, that's perfect.