From ae7bb2620df65d01b7428b842ca9b3e97107558f Mon Sep 17 00:00:00 2001 From: "igor%mir2.org" Date: Wed, 19 Feb 2003 08:51:51 +0000 Subject: [PATCH] Fixing http://bugzilla.mozilla.org/show_bug.cgi?id=193700 : Attempts to access/modify properties of null or undefined are explicitly checked to include in error messages the property name so it would be possible on error in x.y.z to know if it is x or y that was undefined or null. Inspired by suggestion from Russell Gold. --- .../org/mozilla/javascript/Interpreter.java | 12 +++++- .../org/mozilla/javascript/NativeGlobal.java | 19 ++++++++++ .../org/mozilla/javascript/ScriptRuntime.java | 38 ++++++++++--------- .../javascript/resources/Messages.properties | 12 ++++++ 4 files changed, 61 insertions(+), 20 deletions(-) diff --git a/js/rhino/src/org/mozilla/javascript/Interpreter.java b/js/rhino/src/org/mozilla/javascript/Interpreter.java index 9ce66ad1a945..3ad7932f1b9e 100644 --- a/js/rhino/src/org/mozilla/javascript/Interpreter.java +++ b/js/rhino/src/org/mozilla/javascript/Interpreter.java @@ -2769,10 +2769,14 @@ public class Interpreter { if (id != DBL_MRK) { result = ScriptRuntime.getElem(lhs, id, scope); } else { + double val = stackDbl[stackTop]; + if (lhs == null || lhs == Undefined.instance) { + throw NativeGlobal.undefReadError( + lhs, ScriptRuntime.toString(val), scope); + } Scriptable obj = (lhs instanceof Scriptable) ? (Scriptable)lhs : ScriptRuntime.toObject(cx, scope, lhs); - double val = stackDbl[stackTop]; int index = (int)val; if (index == val) { result = ScriptRuntime.getElem(obj, index); @@ -2798,10 +2802,14 @@ public class Interpreter { if (id != DBL_MRK) { result = ScriptRuntime.setElem(lhs, id, rhs, scope); } else { + double val = stackDbl[stackTop - 1]; + if (lhs == null || lhs == Undefined.instance) { + throw NativeGlobal.undefWriteError( + lhs, ScriptRuntime.toString(val), rhs, scope); + } Scriptable obj = (lhs instanceof Scriptable) ? (Scriptable)lhs : ScriptRuntime.toObject(cx, scope, lhs); - double val = stackDbl[stackTop - 1]; int index = (int)val; if (index == val) { result = ScriptRuntime.setElem(obj, index, rhs); diff --git a/js/rhino/src/org/mozilla/javascript/NativeGlobal.java b/js/rhino/src/org/mozilla/javascript/NativeGlobal.java index a4b9983aae55..5c9a92d2e9dd 100644 --- a/js/rhino/src/org/mozilla/javascript/NativeGlobal.java +++ b/js/rhino/src/org/mozilla/javascript/NativeGlobal.java @@ -561,6 +561,25 @@ public class NativeGlobal implements IdFunctionMaster { ScriptRuntime.getMessage1(messageId, arg1), scope); } + static RuntimeException undefReadError(Object object, String property, + Scriptable scope) + { + String msg = (object == null) ? "msg.null.prop.read" + : "msg.undef.prop.read"; + return NativeGlobal.typeError1(msg, property, scope); + } + + static RuntimeException undefWriteError(Object object, String property, + Object value, Scriptable scope) + { + String msg = (object == null) ? "msg.null.prop.write" + : "msg.undef.prop.write"; + String valueStr = (value instanceof Scriptable) + ? value.toString() : ScriptRuntime.toString(value); + return constructError(Context.getContext(), "TypeError", + ScriptRuntime.getMessage2(msg, property, valueStr), scope); + } + /** * The NativeError functions * diff --git a/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java b/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java index 0785d962faa6..c939a9fce426 100644 --- a/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java +++ b/js/rhino/src/org/mozilla/javascript/ScriptRuntime.java @@ -702,20 +702,15 @@ public class ScriptRuntime { } public static Object getProp(Object obj, String id, Scriptable scope) { + if (obj == null || obj == Undefined.instance) { + throw NativeGlobal.undefReadError(obj, id, scope); + } Scriptable start; if (obj instanceof Scriptable) { start = (Scriptable) obj; } else { start = toObject(scope, obj); } - if (start == null || start == Undefined.instance) { - String msg = start == null ? "msg.null.to.object" - : "msg.undefined"; - throw NativeGlobal.constructError( - Context.getContext(), "ConversionError", - ScriptRuntime.getMessage0(msg), - scope); - } Object result = ScriptableObject.getProperty(start, id); if (result != Scriptable.NOT_FOUND) return result; @@ -832,14 +827,14 @@ public class ScriptRuntime { public static Object setProp(Object obj, String id, Object value, Scriptable scope) { - Scriptable start; - try { - start = (Scriptable) obj; - } catch(ClassCastException e) { - start = toObject(scope, obj); + if (obj == null || obj == Undefined.instance) { + throw NativeGlobal.undefWriteError(obj, id, value, scope); } - if (start == null) { - throw NativeGlobal.typeError0("msg.null.to.object", scope); + Scriptable start; + if (obj instanceof Scriptable) { + start = (Scriptable)obj; + } else { + start = toObject(scope, obj); } ScriptableObject.putProperty(start, id, value); return value; @@ -948,6 +943,10 @@ public class ScriptRuntime { index = 0; } } + if (obj == null || obj == Undefined.instance) { + String property = (s != null) ? s : Integer.toString(index); + throw NativeGlobal.undefReadError(obj, property, scope); + } Scriptable start; try { start = (Scriptable)obj; @@ -1007,11 +1006,14 @@ public class ScriptRuntime { index = 0; } } - + if (obj == null || obj == Undefined.instance) { + String property = (s != null) ? s : Integer.toString(index); + throw NativeGlobal.undefWriteError(obj, property, value, scope); + } Scriptable start; - try { + if (obj instanceof Scriptable) { start = (Scriptable) obj; - } catch (ClassCastException e) { + } else { start = toObject(scope, obj); } if (s != null) { diff --git a/js/rhino/src/org/mozilla/javascript/resources/Messages.properties b/js/rhino/src/org/mozilla/javascript/resources/Messages.properties index 45cc764c3324..458a3e9e2061 100644 --- a/js/rhino/src/org/mozilla/javascript/resources/Messages.properties +++ b/js/rhino/src/org/mozilla/javascript/resources/Messages.properties @@ -366,6 +366,18 @@ msg.cyclic.value =\ msg.is.not.defined =\ "{0}" is not defined. +msg.undef.prop.read =\ + Cannot read property "{0}" from undefined + +msg.null.prop.read =\ + Cannot read property "{0}" from null + +msg.undef.prop.write =\ + Cannot set property "{0}" of undefined to "{1}" + +msg.null.prop.write =\ + Cannot set property "{0}" of null to "{1}" + msg.isnt.function =\ {0} is not a function.