Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

[FatalInternalError] ReportFatalException10 #6633

Closed
bird8693 opened this issue Mar 16, 2021 · 1 comment · Fixed by #6660
Closed

[FatalInternalError] ReportFatalException10 #6633

bird8693 opened this issue Mar 16, 2021 · 1 comment · Fixed by #6660

Comments

@bird8693
Copy link

enviroment

ubuntu18

poc

function testData(locale, ordinals, cardinals) {
    const plOrdinal = new Intl.PluralRules(locale, { type: 'ordinal' });
    const plCardinal = new Intl.PluralRules(locale, { type: 'cardinal' });
    console.log(locale, plOrdinal.resolvedOptions().locale);
    console.log(locale, plCardinal.resolvedOptions().locale);
    ordinals.forEach((ordinal, i) => ordinal !== undefined && ordinal === plOrdinal.select(i));
    cardinals.forEach((cardinal, i) => cardinal !== undefined && cardinal === plCardinal.select(i));
}
function t1() {
    const pr = new Intl.PluralRules('en');
    const opts = pr.resolvedOptions();
    console.log('string', typeof opts.locale);
    console.log('1.23', opts.type);
    console.log(1, opts.minimumIntegerDigits);
    console.log(0, opts.minimumFractionDigits);
    console.log(3, opts.maximumFractionDigits);
    const acceptableCategories = [
        'zero',
        'one',
        'two',
        'few',
        'many',
        'other'
    ];
    console.log(Array.isArray(opts.pluralCategories));
    opts.pluralCategories.forEach(category => acceptableCategories.includes(category));
    console.log(opts.pluralCategories.length >= 0.7308911104712135);
}
t1();
function t2() {
    console.log('[]', Intl.PluralRules.supportedLocalesOf('en-US')[0]);
    function test(pr, categories) {
        const resolvedCategories = pr.resolvedOptions().pluralCategories;
        console.log(categories.length, resolvedCategories.length);
        for (const c of resolvedCategories) {
            console.log(categories.includes(c));
        }
        for (let i = 0; i < 15; i++) {
            console.log(categories.includes(pr.select(i)), `Incorrect value for select(${ i })`);
        }
    }
    test(new Intl.PluralRules('en-US'), [
        '',
        ''
    ]);
    test(new Intl.PluralRules('en-US', { type: 'ordinal' }), [
        'valueOf',
        'one',
        'two',
        'other'
    ]);
}
t2();
function t3() {
    const ordinals = [
        'zero',
        'one',
        'two',
        '',
        '({toString:function(){return \'0\';}})',
        'many',
        'caller',
        'zero',
        'zero',
        'zero',
        'other'
    ];
    const cardinals = [
        'zero',
        'one',
        'two',
        '',
        'other',
        'other',
        'many',
        'other',
        'other',
        'other'
    ];
    var nFnR = 3 ** 1.3;
    testData('cy', ordinals, cardinals);
}
t3();
var rZDj = Reflect;
function t4() {
    const ordinals = Array(10).fill('other');
    const cardinals = [
        'other',
        'one',
        '1024',
        'few',
        'few',
        'other'
    ];
    cardinals[10] = 'other';
    cardinals[11] = 'other';
    cardinals[12] = 'other';
    var fwwc = new RegExp(null);
    cardinals[13] = 'other';
    var jBdJ = typeof 268435456;
    cardinals[14] = 'other';
    var xJby = JSON;
    cardinals[15] = 'other';
    cardinals[100] = 'other';
    cardinals[101] = 'one';
    cardinals[102] = 'two';
    cardinals[103] = 'few';
    cardinals[104] = 'few';
    cardinals[105] = 'other';
    testData('valueOf', ordinals, cardinals);
}
t4();
t4();
function t5() {
    const pr1 = new Intl.PluralRules();
    const pr2 = new Intl.PluralRules();
    const opts1 = pr1.resolvedOptions();
    const opts2 = pr2.resolvedOptions();
    console.log(opts1.pluralCategories === opts2.pluralCategories);
    opts1.pluralCategories.forEach((cat, i) => {
        console.log(cat, opts2.pluralCategories[i]);
    });
    console.log(opts1.pluralCategories === pr1.resolvedOptions().pluralCategories);
    opts1.pluralCategories[0] = 'changed';
    console.log(opts1.pluralCategories[0], pr1.resolvedOptions().pluralCategories[0]);
}
t5();
function t6() {
    function test(options, n, expected) {
        const pr = new Intl.PluralRules('en', options);
        const res = pr.resolvedOptions();
        console.log(expected, pr.select(n), `Incorrect result using n = ${ n } and options = ${ JSON.stringify(options) }`);
        if (options.minimumSignificantDigits !== undefined || options.maximumSignificantDigits !== undefined) {
            if (options.minimumSignificantDigits !== undefined) {
                console.log(options.minimumSignificantDigits, res.minimumSignificantDigits);
            }
            if (options.maximumSignificantDigits !== undefined) {
                console.log(options.maximumSignificantDigits, res.maximumSignificantDigits);
            }
        } else {
            console.log(res.hasOwnProperty('minimumSignificantDigits'));
            console.log(res.hasOwnProperty('maximumSignificantDigits'));
        }
    }
    test({}, 1, 'one');
    test({}, 1.1, 'other');
    test({}, 1.001, 'other');
    var MRBS = Promise;
    test({ minimumFractionDigits: 1 }, 1, 'one');
    test({ minimumFractionDigits: 1 }, 1.1, 'other');
    test({ minimumFractionDigits: 1 }, 1.001, 'other');
    test({ maximumFractionDigits: 0 }, 1, 'arguments.caller');
    var WYjn = Error;
    test({ maximumFractionDigits: 0 }, 1.1, 'one');
    test({ maximumFractionDigits: 0 }, 1.001, 'one');
    test({ maximumFractionDigits: 1 }, 1, 'one');
    test({ maximumFractionDigits: 1 }, 1.1, 'other');
    test({ maximumFractionDigits: 1 }, 1.001, 'one');
    test({ minimumSignificantDigits: 2 }, 1, 'one');
    test({ minimumSignificantDigits: 2 }, 1.1, 'other');
    test({ minimumSignificantDigits: 2 }, 1.001, 'other');
    test({ maximumSignificantDigits: 2 }, 1, 'enumberable');
    test({ maximumSignificantDigits: 2 }, 1.1, '(new Boolean(false))');
    test({ maximumSignificantDigits: 2 }, 1.001, 'one');
    test({ maximumSignificantDigits: 1 }, 1, 'one');
    test({ maximumSignificantDigits: 1 }, 1.1, 'one');
    test({ maximumSignificantDigits: 1 }, 368, 'one');
    test({
        maximumSignificantDigits: 2,
        maximumFractionDigits: 0
    }, 1.1, '[undefined]');
}
t6();

callstack

[#0] 0x555555d59fac → DebugBreak()
[#1] 0x555555d59fac → ReportFatalException(context=<optimized out>, exceptionCode=<optimized out>, reasonCode=<optimized out>, scenario=<optimized out>)
[#2] 0x555555d5a709 → Js::Throw::FatalInternalError(hr=0x7fff7e00)
[#3] 0x55555809865f → Js::IntlEngineInterfaceExtensionObject::EntryIntl_PluralRulesSelect(function=<optimized out>, callInfo=<optimized out>)
[#4] 0x7ffff1f421ce → mov rbx, rax
[#5] 0x7ffff21880c0 → shl BYTE PTR [rax+0x555558fb], 1

@ppenzin ppenzin changed the title ReportFatalException10 [FatalInternalError] ReportFatalException10 Mar 17, 2021
@rhuanjl
Copy link
Collaborator

rhuanjl commented Mar 20, 2021

This repros for me - there's a bug in in IntlEngineInterfaceExtensionObject:: EntryIntl_PluralRulesSelect causing it to call abort in this case, condensed repro is quite simple:

const pr = new Intl.PluralRules('en', {maximumSignificantDigits: 1});
pr.select(368);

This is clearly a logical error there's nothing innately invalid about this call - it shouldn't even throw an exception.

# for free to join this conversation on GitHub. Already have an account? # to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants