Dear Lawzyweb

(Joining the recent stream of lazyweb posts on p.m.o…)

If you’ve paid even the slightest attention to tech news, you know Apple lost an iPhone prototype in a bar in the Bay Area. The finder sold it to Gizmodo for $5000, and Jason Chen of Gizmodo published a story with photos and details of it (and numerous followups) — a juicy tech story. More recently, San Mateo police, pursuant to a warrant, searched Jason Chen’s house, seizing numerous pieces of technology hardware. It thus becomes a juicy law story: trade secrets, protection of journalists’ sources, freedom of speech and the First Amendment, handling of lost or stolen property, lots of possible angles. In a number of them it approaches the clearly-defined boundaries of state and federal laws. Great popcorn fodder all around.

There are enough legal questions to satisfy anyone looking to argue them. There are correct answers and incorrect answers, but for a legal novice like me for whom the unknown unknowns are considerable, it’s far more productive to read others’ arguments than to hazard speculation. Also, some parts are matters of fact potentially for a jury to decide, further imperiling predictions.

Every so often, however, it’s possible to pass into realms where my knowledge is less patchy. One commentator, Peter Scheer of the First Amendment Coalition, thinks the police should have obtained a subpoena rather than a warrant, thereby according a journalist what one might claim is his due “delicacy”. Scheer closes an argument for this course of action by speculating as to why it was not taken:

Perhaps there is a more mundane explanation for the failure to use a subpoena in this case: The DA [district attorney] may have been under intense pressure (from whom? Apple, which reported the phone was stolen?) to act even before he could convene a grand jury to issue a subpoena.

If so, the DA may come to regret his haste: If a court rules he shouldn’t have used a warrant, the DA’s possession of evidence seized from Chen’s home may undermine any possible prosecution of other, more culpable, parties.

Assume arguendo that a court does indeed at some point rule the DA shouldn’t have used a warrant. Scheer then claims the seized evidence “may undermine any possible prosecution” of other parties (most likely referring to the original finder, as there is some question of whether the finder actually made a good-faith effort to return the iPhone prototype to its owner, potentially falling afoul of California law). Is this correct? The exclusionary rule forbids admissibility of evidence gained through unreasonable search or seizure in court, following straightforwardly from Weeks v. United States, 232 U. S. 383 (1914), and the Fourth Amendment. The exclusionary rule is then applicable to the states (and to local government such as San Mateo County) under Mapp v. Ohio, 367 U. S. 643 (1961). If case law stopped here it seems to me Scheer would be right — but it doesn’t. Prior to Mapp the Supreme Court held that:

In order to qualify as a “person aggrieved by an unlawful search and seizure,” [for whom evidence from an illegal search or seizure could be suppressed] one must have been a victim of a search or seizure, one against whom the search was directed, as distinguished from one who claims prejudice only through the use of evidence gathered as a consequence of a search or seizure directed at someone else.

Frankfurter, J. in Jones v. United States, 362 U. S. 257, 261 (1960)

It seems to me that, were the warrant declared invalid, evidence from the search would be suppressed in any potential prosecution of Jason Chen (and maybe Gizmodo — but in Alderman v. United States, 394 U. S. 165 (1968), the Court explicitly declined to apply the exclusionary rule with respect to evidence gained through illegal search of a “coconspirator”; Gizmodo or its other employees might or might not be such, maybe depending on whom a case targeted). However, I don’t see how evidence would be suppressed in the prosecution of anyone else — most particularly of the finder of the prototype.

The question for the la[w]zyweb: would evidence from Jason Chen’s computers, pursuant to an illegal search and seizure, be admissible in court against the original finder of the iPhone prototype? I think it would be admissible, and I think Peter Scheer is mistaken if he is suggesting that it wouldn’t.

Speculation’s fine, but as I already provide the less-educated kind I’d prefer if comments consisted of the more-educated kind. 🙂


New Mozilla developer feature: Components.utils.getGlobalForObject(obj)

Suppose you’re an extension developer implementing some sort of event listener-like interface corresponding to browser windows. You’d like listeners to stick around as long as the original browser window is open, so when the browser window’s unload event fires when the browser window is closed, you want to remove the listener. Further, for simplicity, you’d like to be able to reuse the same interface as the DOM uses: EventTarget.addEventListener(eventName, listener, bubbles). But if you do that, how do you know what browser window to associate with a listener? One possibility is that you could associate event listeners with windows if you could determine the global object that corresponded to the event listener in question. (Assume arguendo that you control all use of listeners, so every listener is straightforwardly created in the window with which it’s associated — no shenanigans passing listeners across windows.) This isn’t the only situation where one might wish to know the global object, but it does happen to be a somewhat common one.

Is it possible to determine the global object corresponding to an arbitrary object? You can through a convoluted sequence of actions involving prototype hopping using Object.getPrototypeOf and walking the “scope chain” for the object (using an obscure Mozilla-specific feature whose details I omit). More simply, if the object in question is a DOM node, you could use node.ownerDocument.defaultView, which, while quite understandable, is still DOM-specific. But wouldn’t it be much better if there were some simpler, universal way to determine this value, rather than skirting the edges of feature intentionality?

Firefox nightlies now implement support for a new method available to extensions and other privileged code: Components.utils.getGlobalForObject(obj). It’s designed to support the specific need of determining the window where an object was created. (XPCOM components of course have a global object that isn’t a window, and that global object will be returned by the method in those circumstances.) Its functionality needs little explanation:

/* in the global scope */
var global = this;
var obj = {};
function foo() { }
assertEq(Components.utils.getGlobalForObject(foo), global);
assertEq(Components.utils.getGlobalForObject(obj), global);

If you’re using the previously-noted method involving prototype- and scope-chain-hopping, you should change your code to use Components.utils.getGlobalForObject(obj) instead. This new method is much simpler and clearer, and upcoming changes mean that the old method will no longer work in future nightlies and releases. The next release is still several months out, so you should have plenty of time to adjust.

As always, you can experiment with a bleeding-edge version of Firefox that supports Components.utils.getGlobalForObject(obj) by downloading a nightly from nightly.mozilla.org. (Don’t forget to use the profile manager if you want to keep the settings you use with your primary Firefox installation pristine.)

A last note: the method as currently implemented in nightlies suffers from a small bug when used with objects from unprivileged code — objects from scripts in web pages, that sort of thing. It’s fixed in the TraceMonkey repository, and the adjustment should make its way into the mozilla-central repository (and thus into nightlies) in short order. If you only use the method on objects from privileged scripts, I don’t believe you’ll encounter any problems.



Leadership by example

From an analysis of preliminary Iraqi election results a month ago:

Many democracies, especially those that have been given their impetus by outside power, hold successful elections once or twice, then have their weak institutions perverted by “strong men” — by which is meant leaders that come to power legitimately then refuse to return it, either doing away with the institutions and practices of representative government or turning them into formulaic but meaningless (think East German elections) hypocricy [sic] that fool no one, least of all their own citizens.

When one considers mistakes of other countries, it makes George Washington‘s example all the more remarkable. Washington took the oath of office 221 years ago today to become the first President of the United States; approximately eight years later he gracefully left office, enabling a smooth and peaceful transfer of power to John Adams. This was not the first time he had set aside power for the good of all: he did likewise years before upon completion of the Revolutionary War, leaving public life rather than remain commander-in-chief or choose another position. (Contrary to popular belief, Washington did not decline a kingship. Moreover, that such an offer could have been credible is dubious given the sentiments in contemporary sources such as The Federalist Papers.)

If he does that, he will be the greatest man in the world.

King George III, upon hearing that Washington planned to “return to his farm” after winning the Revolutionary War

Happy First Inauguration, Mr. President.


More SpiderMonkey changes: ancient, esoteric, very rarely used syntax for creating getters and setters is being removed


We’ve removed support for a handful of obsolete getter/setter syntaxes in SpiderMonkey and Mozilla. This does not include { get property() { return "value"; }, set property(v) { } }, which is widely used and which is part of the latest standard. If you don’t get any syntax errors with your code, you don’t need to worry about this. If you do, skip to the end for details on how to adjust your code to cope. But really, you should read it all for the sheer joy of learning about all sorts of awful syntax you didn’t even know existed before it went away. [Or at least empathize with us liberated SpiderMonkey hackers. :-D])

Properties in JavaScript and ECMAScript 3

The fundamental data structure in JavaScript is the object: a container mapping names to values through properties. You can add, remove, or change the value associated with any property, so long as the property may be modified. All user-defined properties are infinitely modifiable in any of these ways; only a few properties defined by ECMAScript (the standard on which JavaScript is based) are not fully modifiable.

var obj1 = {};
obj.property = 17; // add
var obj2 = { property: 42 }; // add from birth
obj2.property = 17; // change it
delete obj2.property; // remove it

Properties which store values are useful, but what if you want properties which can do things when you interact with them? What if you want to have properties which map strings to lazily-computed values? Or what if you want setting a property to have side effects (as, for example, setting an array’s length to 0 removes all elements in it)?

Properties with getters and setters in JavaScript

If you want properties which have functionality beyond just holding a value, you need getters and setters, stored within accessor properties. (Properties which hold values are called data properties.) JavaScript has long included extensions to ECMAScript to create accessor properties, both syntactic:

var o1 =
    get property() { print("gotten!"); return "get"; },
    set property(v) { print("sotten!  " + v); }
var v1 = o1.property; // prints "gotten!", v1 === "get"
o1.property = "new"; // prints "sotten!  new"

…and programmatic:

var o2 = {};
o2.__defineGetter__("property", function() { print("gotten!"); return "get"; });
o2.__defineSetter__("property", function(v) { print("sotten!  " + v); });
var v2 = o2.property; // prints "gotten!", v2 === "get"
o2.property = "new"; // prints "sotten!  new"

Getters and setters are now part of ES5. The syntax demonstrated above is valid ES5; a different API, Object.defineProperty, provides more flexible support for specifying getters and setters dynamically. Developers using the old-school APIs should begin updating to use the new API as browsers make new releases supporting it. Firefox in particular will include support for Object.defineProperty in its next major release, likely to occur in the latter half of the year.

Examining antediluvian accessor syntax

Unbeknownst to the vast majority of web developers, extension developers, and even Mozilla developers, in the past JavaScript has included other getter and setter syntaxes.

Named ES5-like getters and setters

If you look up the function that acts as the getter given ES5-standard getter syntax, what’s the name of that function?

var o = { get property() { return "get"; } };
print(Object.getOwnPropertyDescriptor(o, "property").get.name);

There are a couple plausible answers here: “anonymous“, “property” (the property name), or “” (the empty string) might be reasonable. JavaScript and ES5 arbitrarily create the getter or setter as a function whose name is the empty string. What if you wanted to name that function? (Bear with me for a moment and pretend this is a compelling need, and that adding a named getter or setter programmatically is absolutely unacceptable.)

Solely by accident of implementation, in the past SpiderMonkey has parsed the following syntax to assign names to getter and setter functions:

var o = { get property getter() { return "get"; } };
// Prints "Name: getter" in past versions of SpiderMonkey (or would if
// Object.getOwnPropertyDescriptor existed; __lookupGetter__ is a
// simple workaround); previous line is syntax error elsewhere
print("Name: " + Object.getOwnPropertyDescriptor(o, "property").get.name);

SpiderMonkey internally implemented the parsing of literal getters and setters by parsing them as though the start of a function expression had just been parsed:

// Faked-up parser state when parsing normal getters/setters
var o = { get property () { } };
function () { }

Function expressions may be named or unnamed, but this wasn’t originally considered, so in the above example getter is treated as the name of the function created to correspond to the getter:

// Faked-up parser state when parsing named-getter-function syntax
var o = { get property getter() { } };
function getter() { }

No other JS engine accepts this unintentional accessor-method name token.

Getters and setters in object literals

Possibly the best-known additional syntax is for specifying getters and setters in object literals. This syntax was the original Netscape invention for getters and setters; in practice it was superseded by the newer, more function-looking syntax. SpiderMonkey is again the only engine to implement it.

function g() { print("gotten!"); return "get"; }
var o1 =
    property getter: g,
    property setter: function(v) { print("sotten!  " + v); }
var v1 = o1.property; // prints "gotten!", v1 === "get"
o1.property = "new"; // prints "sotten!"

This accessor property syntax has one large advantage over the more-common syntax previously demonstrated (and even over the unintentional named-accessor mistake shown in the previous section). Where you see property in the object literal above, you could instead see a numeric literal, or a string literal — just as you might see either in any object literal without getters or setters, e.g. { 1: "value", "o": "hai" }. Historically, in get property() { ... }, property was required to be an identifier, thus excluding numbers and non-identifier accessor properties from representation. The syntax here had the further advantage of allowing serialization to “source” (more accurately, a reasonable but not always equivalent facsimile) of objects containing non-identifier-named accessor properties, through another Netscape extension in JavaScript.

This syntax also has a few disadvantages. Since the getter and setter contextual keywords follow the property name, the eye must scan past the property name to determine whether a portion of a literal represents a data property or an accessor property. This special-case check also complicates parsing, because now the parser has to check for something beyond just a colon at such locations. (To be sure, this problem exists with get foo() { }, but it’s restricted to the single leading token get, not to all leading tokens.) Since the value assigned to the getter is parsed as an arbitrary expression, there’s no guarantee the value must be a function — that must be checked at runtime.

Assigning getters and setters to properties

This accessor syntax provides the same functionality as Object.defineProperty(obj, propname, { get: fun, enumerable: true, configurable: true }) (mutatis mutandis for setters), except as part of the language syntax rather than as part of its standard library. Again, no other engine has implemented this syntax.

var o = {};
o.property getter = function() { print("gotten!"); return "get" };
o.property setter = function() { print("sotten!"); };
var v = o.property; // prints "gotten!", v === "get"
o.property = "new"; // prints "sotten!"

This syntax is also obscure: outside SpiderMonkey source and test files, only a single file in the Mozilla source code uses it. Strangely, a trawl through AMO shows half a dozen extensions have managed to discover this syntax, despite its near-complete disuse in Mozilla itself.

Assigning getters and setters to names rather than properties

Syntactically, this is just a different flavor of the previous example:

varname getter = function() { return "get"; };
var q = varname; // "get"

Semantically, however, it’s a rather different beast. The problem is that not all names are alike in SpiderMonkey. While ECMAScript specifies all name accesses in terms of objects (pure-JS objects in ES3, tighter spec-internal artifacts in ES5), most if not all JS engines out there optimize name access based on the type of the name. Local and enclosing variable access may be some number of pointer jumps, comparisons, and an offset, rather than some sort of hash table lookup in a more general case. Global variable access can in many circumstances skip lookups in enclosing scopes, going to the global object directly. (Last and certainly least, variable access inside with almost necessarily must be essentially unoptimized and dog-slow. Friends don’t let friends use with!) These sorts of optimizations rely on names always being plain old values, not accessors (except in the global case, where the type of optimizations implemented are qualitatively quite different). Slowing down local or enclosing variable accesses just to support this very rare case would be insane.

SpiderMonkey actually hasn’t supported this syntax for awhile. I only mention it because SpiderMonkey includes code specifically to exclude it. If this syntax is seen and varname can be resolved to a var, it’s a compile-time syntax error. Otherwise, if varname resolves to a var at runtime (possible in the presence of with or eval), it’s a runtime TypeError. Last, if it doesn’t, it “works” — and you are most likely Jesse, combining syntax and features in obscure and evil ways solely to make SpiderMonkey developers’ lives hard. 😉 In sufficiently old versions of Firefox where these restrictions weren’t in place, it’s entirely conceivable this syntax may have resulted in security vulnerabilities (one large factor in its removal from SpiderMonkey).

Prefixed function expressions

Perhaps the most bizarre getter/setter syntax is a modification of the syntax for function expressions and statements. As with all the others, this syntax has only been implemented by SpiderMonkey.

getter function foo() { return "foo getter"; };
var v = foo; // "foo getter"
var q = setter function bar(v) { };

When the prefixed function is a statement in the global scope, the syntax is equivalent to Object.defineProperty(globalObject, "foo", { get: function foo() { /* ... */ }, enumerable: true, configurable: true }) (mutatis mutandis for setter). If it’s a statement in a function scope or an expression that’s not a statement, the prefix serves no purpose that I can discern, except that it affects Function.prototype.toString()‘s behavior by including the prefix in the returned string.

None of these old getter/setter syntaxes provide value

Now that ES5 has codified The One True Syntax and The One True Programmatic API, these older syntaxes bring little to the table.

  • The mistaken ES5-like named accessor get property funname() { } syntax doesn’t satisfy a compelling need.
  • property getter: in object literals provides one compelling feature: the ability to have non-identifier-named properties. As ES5’s get property() { } syntax includes these further extensions beyond what engines have already implemented, this advantage no longer exists:
    var o =
        get name() { return "names valid"; },
        set break() { this.x = "keywords too"; },
        set 1() { this.y = "numeric literals also accepted"; },
        get "custom string"() { return "arbitrary string literals too!"; }

    (property getter: has a final advantage with respect to an ancient Netscape extension, but given that extension’s dubious future I will omit the details. Suffice it to say the use case is highly esoteric, and reasonably graceful degradation is possible without property getter:.)

  • getter = and getter function are fully subsumed by Object.defineProperty.
  • varname getter = was already gone.

In sum: these syntaxes make some things slightly easier, but they don’t provide anything you can’t do with ES5’s standardized accessor support.

These syntaxes were the source of numerous bugs

In addition to not being particularly useful, these syntaxes imposed notable costs on development. Supporting so many different getter and setter syntaxes isn’t easy, and the relevant code paths are quite complicated, attempting to decide when which syntax is correct and when not (particularly as far as object serialization is concerned). This has resulted in a multitude of accessor bugs usually found by Jesse‘s fuzz-testing and almost never by real-world scripts: bugs which, in C or C++, can often lead to memory-unsafety and, in the extreme, arbitrary code execution. By my count SpiderMonkey has sixteen separate tests (corresponding to the same number of bugs) dedicated to edge cases and corner behaviors with these syntaxes: syntaxes no one uses, syntaxes superseded by newer and better ones, and syntaxes which no other JS engine currently supports, nor ever will support.

These syntaxes continue to impose costs on development. Not all related bugs have been fixed, and changes to nearby code do have to take account of this syntax. We have had at least one long-standing (but believed “mostly harmless”, in that a sanity-check fails but surrounding defensive code completely contains the problem) bug involving this syntax, which due to its relative harmlessness has gone unfixed for nearly three years (and, almost as bad, undiscovered for two of them). Recent implementation work on ES5’s strict mode support required adjustments to the area of parsing object literals (for ES5’s strict mode rejection of duplicate property names), adjustments required to work around support for these syntaxes.

In short, TANSTAAFL. We’ve paid a large cost to keep these syntaxes around, and we continue to pay to keep them around — sometimes directly, sometimes indirectly, but unavoidably if support is worthwhile.

Support for all non-ES5 accessor syntaxes has been removed from SpiderMonkey

But for the many reasons previously given, support for these obsolete syntaxes is not worthwhile, so we have removed them from SpiderMonkey. get property funname() { } was an error from the start that no one will miss. SpiderMonkey has recently implemented support for ES5 numeric- and string-literal accessor property names (support for keyword names already exists), so the remaining important use case for property getter: has been eliminated. The getter = and getter function syntaxes never provided extra value, so they too have been removed without qualms.

To give an idea of the complexity eliminated by removing these syntaxes, the patch to remove them added 116 lines of code but removed 313 lines of code. Outside of code changes (that is, adjusting or removing tests which used these features), it added 133 lines but removed 1213 lines. It’s always great deleting code like this. 🙂

Updating existing code to adapt to these removals

One nice feature of removing syntax is that the failure mode when that syntax is encountered is blindingly obvious: the script will fail to parse. Parse errors show up in the JavaScript console, so it’s easy to tell when this is the problem; SpiderMonkey’s excellent error messages should point directly at the offending location.

If by chance you do actually use any of these syntaxes, the necessary fixes are simple. Suppose the existence of these helper functions:

function accessorDescriptor(field, fun)
  var desc = { enumerable: true, configurable: true };
  desc[field] = fun;
  return desc;

function defineGetter(obj, prop, get)
  if (Object.defineProperty)
    return Object.defineProperty(obj, prop, accessorDescriptor("get", get));
  if (Object.prototype.__defineGetter__)
    return obj.__defineGetter__(prop, get);

  throw new Error("browser does not support getters");

function defineSetter(obj, prop, set)
  if (Object.defineProperty)
    return Object.defineProperty(obj, prop, accessorDescriptor("set", set));
  if (Object.prototype.__defineSetter__)
    return obj.__defineSetter__(prop, set);

  throw new Error("browser does not support setters");

Here’s how you can update each old syntax to work again:

get property funname() { }
var o = defineGetter({}, "property", function funname() { });
property setter: fun
var o = defineSetter({}, "property", fun);
obj.prop getter = fun
defineGetter(obj, "prop", fun);
setter function prop() { } (when at global scope; otherwise just remove the setter prefix)
defineSetter(obj, "prop", fun);

You can experiment with a version of Firefox with support for these obsolete syntaxes removed by downloading a nightly from nightly.mozilla.org. (Don’t forget to use the profile manager if you want to keep the settings you use with your primary Firefox installation pristine.)

A brief word on __defineGetter__ and __defineSetter__

As you may have noticed, all examples here use Object.defineProperty in preference to either __defineGetter__ or __defineSetter__, using the latter two only as fallback when the former is absent. While many browsers support these methods, not all do. Object.defineProperty is the future, and it is the standard; Microsoft has even gone on the record to say that they will not implement __defineGetter__ or __defineSetter__ in IE given the existence of the standardized method (props to them for that choice, by the way). For greatest forward compatibility with all browsers, you should use Object.defineProperty if it exists, and only fall back to __define{G,S}etter__ if it does not.

In a distant future we would like to remove support for __defineGetter__ and __defineSetter__, after ES5 adoption has taken off, so as not to distract from the standardized support. The less new web developers have to know about legacy extensions superseded by standardized alternatives, the better. This action is at least several years in the future, likely longer; being able to make the change will require preparation and adjustment in anticipation of that time. Given upcoming releases of browsers supporting ES5 functionality, there’s no better time than the present to start gradually, and gracefully, adopting standardized methods over legacy alternatives.

« NewerOlder »