Bug 478047 - Assignments to a property that has a getter but not a setter should throw a TypeError. r=igor
authorBlake Kaplan <mrbkap@gmail.com>
Wed, 11 Feb 2009 19:48:00 -0800
changeset 25100 975b36c50d33c8de608e798fcde43043db10bf68
parent 25099 99f3744acfef8e6e14f20aa9ecbdb452a1720f23
child 25101 6758dedadadcf1c6743fa8bbc57830a01e6e8bae
push idunknown
push userunknown
push dateunknown
reviewersigor
bugs478047
milestone1.9.2a1pre
Bug 478047 - Assignments to a property that has a getter but not a setter should throw a TypeError. r=igor
js/src/jsobj.cpp
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -1,10 +1,10 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
- * vim: set ts=8 sw=4 et tw=78:
+ * vim: set ts=8 sw=4 et tw=79:
  *
  * ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
  * The contents of this file are subject to the Mozilla Public License Version
  * 1.1 (the "License"); you may not use this file except in compliance with
  * the License. You may obtain a copy of the License at
  * http://www.mozilla.org/MPL/
@@ -3896,19 +3896,25 @@ js_NativeSet(JSContext *cx, JSObject *ob
         /* If sprop has a stub setter, keep scope locked and just store *vp. */
         if (SPROP_HAS_STUB_SETTER(sprop))
             goto set_slot;
     } else {
         /*
          * Allow API consumers to create shared properties with stub setters.
          * Such properties lack value storage, so setting them is like writing
          * to /dev/null.
+         *
+         * But we can't short-circuit if there's a scripted getter or setter
+         * since we might need to throw. In that case, we let SPROP_SET
+         * decide whether to throw an exception. See bug 478047.
          */
-        if (SPROP_HAS_STUB_SETTER(sprop))
+        if (!(sprop->attrs & JSPROP_GETTER) && SPROP_HAS_STUB_SETTER(sprop)) {
+            JS_ASSERT(!(sprop->attrs & JSPROP_SETTER));
             return JS_TRUE;
+        }
     }
 
     sample = cx->runtime->propertyRemovals;
     JS_UNLOCK_SCOPE(cx, scope);
     JS_PUSH_TEMP_ROOT_SPROP(cx, sprop, &tvr);
     ok = SPROP_SET(cx, sprop, obj, obj, vp);
     JS_POP_TEMP_ROOT(cx, &tvr);
     if (!ok)