Topic: [Bug] Javascript bug: arrays are stringified twice

Posted under Site Bug Reports & Feature Requests

Bug overview description.
application-min.js includes the following code which modifies Array.prototype.toJSON:

Object.extend(Array.prototype, {
    toJSON: function() {
        var results = [];
        this.each(function(object) {
            var value = Object.toJSON(object);
            if (!Object.isUndefined(value)) results.push(value);
        });
        return '[' + results.join(', ') + ']';
    }
});

...and causes arrays to be stringified twice when JSON.stringify is used. This is a nightmare for script development because code that would work nearly anywhere else fails here. JSON.stringify and JSON.parse are usually symmetric, so parse undoes stringify, but on e621 you have to call parse on arrays twice. This turns pretty nasty when you have arrays nested in other objects.

This isn't a huge priority or anything, since there are some other (uncomfortable) workarounds. Xch3l wrote his own stringify function to replace the native one. You could also set Array.prototype.toJSON = undefined, but I'm not sure if that would break any other site functions.

Anyway, even if the bug/irregularity can't be fixed I wanted to document it here. Hopefully it helps someone.

What part(s) of the site page(s) are affected?
Javascript on all pages

What is the expected behavior?

var testArr = [ 'test1', 'test2' ];
console.log(JSON.stringify(testArr));
 
Expected output:	'["test1","test2"]'

What actual behavior is given instead?

e621 output:		'"[\\"test1\\", \\"test2\\"]"'

Time of incident (if applicable).
For the past several years, at least.

Can you reproduce the bug every time?
Yes

What steps did you take to replicate this bug?
Above

Errors or other messages returned (if any).
Above

Updated by KiraNoot

Looks like this is a bug with prototype.js(yuck) that was never fixed. Since we don't explicitly use the method mentioned in our code base I'll have to see if removing those overrides breaks anything or not.

Updated by anonymous

Not only are most of the overrides unnecessary (as they're overriding perfectly fine and working native functions, where the non-native implementation run orders of magnitude slower), sometimes they're quite literally destroying functionality.

For instance, try running the following code in the console on e621:

["a", "b"].reduceRight((acc, item) => acc + item)

and

["a", "b"].reduce((acc, item) => acc + item)

The array's reduceRight method functions properly. But the array's reduce function is overridden with non-working code.

The Prototype library that you're using is a relic from futaba imageboard times where I guess it served as a polyfill. The problem is that this polyfill is incorrectly implemented as it's unconditionally overriding functions instead of only in cases where the browser doesn't support them.

If you ask me you should just trash the whole prototype library.

Updated by anonymous

It's actually being used for things, which is terrifying to me. I'd love to rip it out entirely but a LOT of code relies on functions that exist in it, and probably on some of the random broken functionality, so it isn't that easy. So for anything that I pull out, it's me having to fully test all of the JS on the site. It's generally not a good use of my time, even if I feel for your plight.

Updated by anonymous

  • 1