Open Bug 1138661 Opened 10 years ago Updated 2 years ago

callFunction(CallTypedArrayMethodIfWrapped, ...) as a pattern is wrong for any function with argument-count-dependent behavior

Categories

(Core :: JavaScript: Standard Library, defect)

defect

Tracking

()

People

(Reporter: Waldo, Unassigned)

Details

js> var g = newGlobal(); js> var otherTA = new g.Uint8Array(); js> otherTA.reduce(function() { throw 'not called'; }, 42) 42 js> Uint8Array.prototype.reduce.call(otherTA, function() { throw 'not called'; }, 42) typein:4:0 TypeError: reduce of empty array with no initial value The problem is the code looks like this: function TypedArrayReduce(callbackfn/*, initialValue*/) { // This function is not generic. if (!IsObject(this) || !IsTypedArray(this)) { return callFunction(CallTypedArrayMethodIfWrapped, this, callbackfn, "TypedArrayReduce"); } // Steps 1-2. var O = this; // Steps 3-5. var len = TypedArrayLength(O); // Step 6. if (arguments.length === 0) ThrowError(JSMSG_MISSING_FUN_ARG, 0, "%TypedArray%.prototype.reduce"); if (!IsCallable(callbackfn)) ThrowError(JSMSG_NOT_FUNCTION, DecompileArg(0, callbackfn)); // Step 7. if (len === 0 && arguments.length === 1) ThrowError(JSMSG_EMPTY_ARRAY_REDUCE); When we're calling the reduce method on an other-global typed array, we enter the callFunction(...) thing and pass a set of arguments *missing* |initialValue|. So the method in the other global things it wasn't passed, we hit the Step 7 special-case, and we die. It's not enough to simply pass arguments[1], because if no arguments are passed, that triggers an observable prototype-chain lookup. It has to be passed if it was provided, not be passed if it wasn't. This isn't the only instance of the problem, but at a skim of TypedArray.js, most of the cases prior to this one (and, I would assume, after it) just produce a bad error message when a callback function is passed as |undefined| by the delegating call. For example, js> Uint8Array.prototype.map.call(otherTA) typein:6:0 TypeError: callbackfn is not a function js> otherTA.map() typein:7:0 TypeError: missing argument 0 when calling function %TypedArray%.prototype.map But someone probably should carefully audit every use of callFunction with Call*IfWrapped methods to double-check all of them.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.