Skip to content

Redefining Function.prototype.toString causes typed array constructors to throw TypeError #279

@paul-calvelage

Description

@paul-calvelage

This is a bug I discovered while working on a Javascript kata, where the author had redefined Function.prototype.toString in the preloaded code section, I am guessing in an attempt to prevent cheating. I then attempted a solution using typed arrays and stumbled onto this. Luckily I have enough honor points to poke around the beta kata to see what is happening.

Anyway, I can reproduce the problem on other kata, which is why I am reporting it here rather than just to the author. The steps below are sufficient to duplicate the issue on any kata.

For some reason I am not able to grasp, redefining Function.prototype.toString causes the typed array constructors, such as Int16Array, to throw a TypeError (not directly, but via the backend of Codewars somewhere). This is unexpected, and I'm sure the author was not trying to block the use of typed arrays by hiding the source code of functions.

How to reproduce the problem:

Step 1: (While logged in...) Train on any random Javascript kata (it doesn't matter, say http://www.codewars.com/kata/56dae9dc54c0acd29d00109a/train/javascript just for example).
Step 2: In the "Your Solution" editor paste:

Function.prototype.toString = {};
var x = new Int16Array();
var y = new Int16Array();

Step 3: In the "Your Test Cases" editor paste:

Test.expect(true);

Step 4: Click "Run Tests"

Expected behavior: "Test Passed" appears in the "Output" window highlighted in green. This is expected since Test.expect(true) should pass and new Int16Array() should not throw an error.
Buggy behavior: "TypeError: Cannot convert object to primitive value" appears in the "Output" window highlighted in red.

solution
test
error

Clues

Something in the backend could be calling toString on Int16Array. This code:

Function.prototype.toString = function() { console.log(this); };
var x = new Int16Array();
var y = new Int16Array();

produces:

[Function: get]
[Function: set]
[Function: slice]
[Function: subarray]
[Function: slice]
Test Passed

And this:

Function.prototype.toString = function() { Int16Array(); };
var x = new Int16Array();
var y = new Int16Array();

is enough to blow up the stack via recursion

RangeError: Maximum call stack size exceeded

So why is toString being called on Int16Array functions? Is noderunner doing it or something else?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions