Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion saltgui/static/scripts/ParseCommandLine.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,15 @@ export class ParseCommandLine {
// jobIds look like numbers but must be strings
return { value: pStr };
} else if (patInteger.test(pStr)) {
return { value: Number.parseInt(pStr, 10) };
const value = Number.parseInt(pStr, 10);
// The number travels to salt as its own decimal rendering, so it arrives
// unchanged exactly when that rendering is the text that was typed.
// 12345678901234567 renders back as ...68, and sending a different number
// than the one that was typed is worse than refusing it here.
if (String(value) !== pStr.replace(/^\+/, "")) {
return { error: "Integer argument is too large to be sent exactly. Make it a string by surrounding it with quotes or make it a float by appending .0" };
}
return { value };
} else if (patFloat.test(pStr)) {
const value = Number.parseFloat(pStr);
if (!Number.isFinite(value)) {
Expand Down
75 changes: 49 additions & 26 deletions tests/unit/ParseCommandLine.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -242,32 +242,55 @@ describe("Unittests for ParseCommandLine.js", () => {
assert.equal(args[0], 0);
assert.equal(Object.keys(params).length, 0);

// an integer that almost looks like a jobid, but one digit less
args = [];
params = {};
result = ParseCommandLine.parseCommandLine("2018082000341133831", args, params);
assert.isNull(result);
assert.equal(args.length, 1);
assert.equal(args[0], 2018082000341133831);
assert.equal(Object.keys(params).length, 0);

// an integer that almost looks like a jobid, but one digit more
args = [];
params = {};
result = ParseCommandLine.parseCommandLine("201808200034113383170", args, params);
assert.isNull(result);
assert.equal(args.length, 1);
assert.equal(args[0], 201808200034113383170);
assert.equal(Object.keys(params).length, 0);

// an integer that almost looks like a jobid, just not a true date-time
args = [];
params = {};
result = ParseCommandLine.parseCommandLine("20182820003411338317", args, params);
assert.isNull(result);
assert.equal(args.length, 1);
assert.equal(args[0], 20182820003411338317);
assert.equal(Object.keys(params).length, 0);
// Integers beyond 2**53-1 cannot be sent exactly, so they are refused
// rather than silently rounded. Expectations compare against strings on
// purpose: written as numeric literals they would be rounded by the test
// itself and could not tell a correct value from a wrong one.
const tooLargeIntegers = [
// almost a jobid, but one digit less
"2018082000341133831",
// almost a jobid, but one digit more
"201808200034113383170",
// jobid-shaped, just not a true date-time
"20182820003411338317",
// the first integer that no longer renders back as itself
"9007199254740993",
// loses its last digit: it renders back as ...68
"12345678901234567"
];
for (const nr of tooLargeIntegers) {
const label = "value " + nr;
args = [];
params = {};
result = ParseCommandLine.parseCommandLine(nr, args, params);
assert.equal(
result,
"Integer argument is too large to be sent exactly. Make it a string by surrounding it with quotes or make it a float by appending .0",
label);
assert.equal(args.length, 0, label);
}

// Anything whose decimal rendering is the text that was typed is accepted,
// which reaches past isSafeInteger: 2**53, 2**54 and 10**16 all render back
// unchanged. A real jobid is matched as a string before the integer branch,
// so it survives too.
const exactValues = [
"9007199254740991",
"9007199254740992",
"18014398509481984",
"10000000000000000",
"20180814033130818988"
];
for (const nr of exactValues) {
const label = "value " + nr;
args = [];
params = {};
result = ParseCommandLine.parseCommandLine(nr, args, params);
assert.isNull(result, label);
assert.equal(args.length, 1, label);
assert.equal(String(args[0]), nr, label);
assert.equal(Object.keys(params).length, 0, label);
}

// FLOAT

Expand Down