<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>92817</bug_id>
          
          <creation_ts>2012-07-31 18:05:56 -0700</creation_ts>
          <short_desc>use strict, string property assignment throws TypeError</short_desc>
          <delta_ts>2012-08-01 14:44:52 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>JavaScriptCore</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>Unspecified</rep_platform>
          <op_sys>Unspecified</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>INVALID</resolution>
          
          
          <bug_file_loc>http://jsbin.com/araqog/4/edit</bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>0</everconfirmed>
          <reporter name="James Burke">jrburke</reporter>
          <assigned_to name="Nobody">webkit-unassigned</assigned_to>
          <cc>barraclough</cc>
    
    <cc>brendan</cc>
    
    <cc>oliver</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>683711</commentid>
    <comment_count>0</comment_count>
    <who name="James Burke">jrburke</who>
    <bug_when>2012-07-31 18:05:56 -0700</bug_when>
    <thetext>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.
      &apos;use strict&apos;;
      var value = &apos;foo&apos;,
          err, result;
      
      try {
        //THIS IS WHERE IT FAILS IN Safari 6/Nightly WebKit
        value.something = true;
      } catch (e) {
        err = e;
      }
      
      if (err) {
        result = &apos;ERROR: &apos; + err;
      } else {
        result = &apos;value.something is: &apos; + value.something;
      }
          
      document.getElementById(&apos;out&apos;).innerHTML = result;
    }

    stricty();</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684493</commentid>
    <comment_count>1</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2012-08-01 13:00:13 -0700</bug_when>
    <thetext>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 &quot;use strict&quot; or &apos;use strict&apos;. 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)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684495</commentid>
    <comment_count>2</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2012-08-01 13:03:17 -0700</bug_when>
    <thetext>Oh wait, i was misinterpreting what you were saying.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684550</commentid>
    <comment_count>3</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2012-08-01 13:53:07 -0700</bug_when>
    <thetext>This is correct behaviour.

The evaluation of  &quot;value.something = true&quot; 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 = &amp;value
2. baseValue = value
3. propertyNameReference = &amp;&quot;something&quot; // all lookup is perform as if a.b were a[&quot;b&quot;]
4. propertyNameValue = &quot;something&quot;
5. /* do nothing */
6. propertyNameString = ToString(propertyNameValue) /*&quot;something&quot;*/
7. strict = true /*we&apos;re in strict mode code*/
8. return Reference({base: baseValue /*string*/, 
                                name: propertyNameString /*&quot;something&quot;*/, 
                                strict: strict /*true*/})

we&apos;ll call the result of this lhsRef.

step 2)
Evalute the right hand side (which i won&apos;t go through as it&apos;s not relevant)

step 3) perform the assignment

PutValue(lhsRef, lhsSide /*true*/)

8.7.2 PutValue (V /*{base: string, name: &quot;something&quot;, 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&apos;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 /*&quot;something&quot;*/, W/*true*/, Throw/*true -- because we&apos;re in strict mode*/)
    1. O=ToObject(base) // yay allocate a String object
    2. /* do nothing as there&apos;s no readonly &quot;something&quot; property in prototype chain */
    3. ownDesc = GetOwnProperty(O, P) // &quot;something&quot; doesn&apos;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 &quot;something&quot; isn&apos;t a property that exists anywhere on the protochain
    6. /* do nothing as desc is null so isn&apos;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&apos;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</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684554</commentid>
    <comment_count>4</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2012-08-01 13:55:20 -0700</bug_when>
    <thetext>For reference you could run the tests at http://test262.ecmascript.org/# -- it&apos;s an ongoing endeavour to have complete coverage of the entire spec.  On Wednesday last week Safari 6 passed every test.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684566</commentid>
    <comment_count>5</comment_count>
    <who name="Oliver Hunt">oliver</who>
    <bug_when>2012-08-01 14:08:14 -0700</bug_when>
    <thetext>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&apos;t a setter on the prototype with the right name all you&apos;re doing is creating an object, assigning a property, and then throwing the object away.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684600</commentid>
    <comment_count>6</comment_count>
    <who name="Gavin Barraclough">barraclough</who>
    <bug_when>2012-08-01 14:40:25 -0700</bug_when>
    <thetext>Safari 6.0&apos;s behavior is correct here, see ECMA-262, section 8.7.2.

The expression &apos;value.something&apos; 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&apos;ll use if the special [[Put]] implementation specified below, and per step 4b the &apos;Throw&apos; argument to [[Put]] is true (since we&apos;re in strict code, this is a strict reference).  As the String object &amp; its prototypes do not contain a &apos;something&apos; property, we&apos;ll reach step 7, and throw a type error per step 7a.

cheers,
G.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684601</commentid>
    <comment_count>7</comment_count>
    <who name="Gavin Barraclough">barraclough</who>
    <bug_when>2012-08-01 14:41:11 -0700</bug_when>
    <thetext>Oh, wait, Oliver already said all this. Ooops! :-)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>684607</commentid>
    <comment_count>8</comment_count>
    <who name="James Burke">jrburke</who>
    <bug_when>2012-08-01 14:44:52 -0700</bug_when>
    <thetext>Thanks for the info, looks like the other browsers just have not implemented the matching behavior yet.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>