WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED INVALID
92817
use strict, string property assignment throws TypeError
https://bugs.webkit.org/show_bug.cgi?id=92817
Summary
use strict, string property assignment throws TypeError
James Burke
Reported
2012-07-31 18:05:56 PDT
In strict mode, assigning to a property on a string throws a TypeError in Safari 6 and in Nightly WebKit, Version 6.0 (8536.25, 537+). This does not occur in other strict-aware browsers, tested with Firefox 15 and Chrome 20. They allow the assignment but then later reads of the property return undefined. It may be that I misunderstood the strict mode rules, but in that case I am surprised the browsers do not agree in this case. In case the URL to the JSBin goes away, the script code is the following: function stricty() { //comment out use strict and no error thrown. //No error thrown in other strict-aware browsers. 'use strict'; var value = 'foo', err, result; try { //THIS IS WHERE IT FAILS IN Safari 6/Nightly WebKit value.something = true; } catch (e) { err = e; } if (err) { result = 'ERROR: ' + err; } else { result = 'value.something is: ' + value.something; } document.getElementById('out').innerHTML = result; } stricty();
Attachments
Add attachment
proposed patch, testcase, etc.
Oliver Hunt
Comment 1
2012-08-01 13:00:13 PDT
My reading of ECMA-262 says that comments are not relevant in determination of strict mode: 14.1 Directive Prologues and the Use Strict Directive A Directive Prologue is the longest sequence of ExpressionStatement productions occurring as the initial SourceElement productions of a Program or FunctionBody and where each ExpressionStatement in the sequence consists entirely of a StringLiteral token followed a semicolon. The semicolon may appear explicitly or may be inserted by automatic semicolon insertion. A Directive Prologue may be an empty sequence. A Use Strict Directive is an ExpressionStatement in a Directive Prologue whose StringLiteral is either the exact character sequences "use strict" or 'use strict'. A Use Strict Directive may not contain an EscapeSequence or LineContinuation. Comments of any form are not statement expressions (they are explicitly treated as a single space character)
Oliver Hunt
Comment 2
2012-08-01 13:03:17 PDT
Oh wait, i was misinterpreting what you were saying.
Oliver Hunt
Comment 3
2012-08-01 13:53:07 PDT
This is correct behaviour. The evaluation of "value.something = true" is evaluated with by getting the reference for the left hand side, then evaluating the right hand side, then calling put value. step 1) get the reference for assignment: 11.2.1 Property Accessors 1. essentially baseReference = &value 2. baseValue = value 3. propertyNameReference = &"something" // all lookup is perform as if a.b were a["b"] 4. propertyNameValue = "something" 5. /* do nothing */ 6. propertyNameString = ToString(propertyNameValue) /*"something"*/ 7. strict = true /*we're in strict mode code*/ 8. return Reference({base: baseValue /*string*/, name: propertyNameString /*"something"*/, strict: strict /*true*/}) we'll call the result of this lhsRef. step 2) Evalute the right hand side (which i won't go through as it's not relevant) step 3) perform the assignment PutValue(lhsRef, lhsSide /*true*/) 8.7.2 PutValue (V /*{base: string, name: "something", strict: true}*/, W/*rhs side, so the value: true*/) 1. V is a reference so do nothing 2. base=GetBase(V) /*string*/ 3. /* do nothing as we've got a reference */ 4. V is a property reference so we now do: a. base is a primitive type (string) so put = a special internal version of [[Put]] also defined in 8.7.2 b. put(base, V.name, W, V.strict) Internal [[Put]](base /* our string*/, P /*"something"*/, W/*true*/, Throw/*true -- because we're in strict mode*/) 1. O=ToObject(base) // yay allocate a String object 2. /* do nothing as there's no readonly "something" property in prototype chain */ 3. ownDesc = GetOwnProperty(O, P) // "something" doesn't existing on the String object so this is null 4. /* do nothing as ownDesc is null*/ 5. desc = GetProperty(O, P) // also null as "something" isn't a property that exists anywhere on the protochain 6. /* do nothing as desc is null so isn't an accessor property */ 7. We are trying to assign a property to a temporary object a. Throw is true, so we throw a TypeError. So this is the correct behaviour, and the long (even though it's abbreviated) and winding path to throwing an exception here in strict mode. You should file bugs on the other browsers for not doing this correctly. :D
Oliver Hunt
Comment 4
2012-08-01 13:55:20 PDT
For reference you could run the tests at
http://test262.ecmascript.org/
# -- it's an ongoing endeavour to have complete coverage of the entire spec. On Wednesday last week Safari 6 passed every test.
Oliver Hunt
Comment 5
2012-08-01 14:08:14 PDT
The linked test case is actually making the kind of mistake this exception was specifically designed to prevent -- attaching properties to primitive types does not work, as you are simply attaching the properties to a temporary. If there isn't a setter on the prototype with the right name all you're doing is creating an object, assigning a property, and then throwing the object away.
Gavin Barraclough
Comment 6
2012-08-01 14:40:25 PDT
Safari 6.0's behavior is correct here, see ECMA-262, section 8.7.2. The expression 'value.something' returns a property reference, and per section 11.13.1 step 5 this calls PutValue (8.7.2). The base of the reference is a primitive string, so per step 4a the put method we'll use if the special [[Put]] implementation specified below, and per step 4b the 'Throw' argument to [[Put]] is true (since we're in strict code, this is a strict reference). As the String object & its prototypes do not contain a 'something' property, we'll reach step 7, and throw a type error per step 7a. cheers, G.
Gavin Barraclough
Comment 7
2012-08-01 14:41:11 PDT
Oh, wait, Oliver already said all this. Ooops! :-)
James Burke
Comment 8
2012-08-01 14:44:52 PDT
Thanks for the info, looks like the other browsers just have not implemented the matching behavior yet.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug