Skip to content

Commit

Permalink
feat: rule no-unsafe-values (#30)
Browse files Browse the repository at this point in the history
* feat: rule no-unsafe-values

Fixes #29

* Update src/rules/no-unsafe-values.js

Co-authored-by: Nicholas C. Zakas <[email protected]>

* fixups

---------

Co-authored-by: Nicholas C. Zakas <[email protected]>
  • Loading branch information
bmeck and nzakas authored Nov 7, 2024
1 parent ad022d9 commit 6988e5c
Show file tree
Hide file tree
Showing 2 changed files with 192 additions and 0 deletions.
60 changes: 60 additions & 0 deletions src/rules/no-unsafe-values.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/**
* @fileoverview Rule to detect unsafe values in JSON.
* @author Bradley Meck Farias
*/

export default {
meta: {
type: "problem",

docs: {
description: "Disallow JSON values that are unsafe for interchange",
},

messages: {
unsafeNumber: "Number outside safe range found.",
loneSurrogate: "Lone surrogate '{{ surrogate }}' found.",
},
},

create(context) {
return {
Number(node) {
if (Number.isFinite(node.value) !== true) {
context.report({
loc: node.loc,
messageId: "unsafeNumber",
});
}
},
String(node) {
if (node.value.isWellFormed) {
if (node.value.isWellFormed()) {
return;
}
}
// match any high surrogate and, if it exists, a paired low surrogate
// match any low surrogate not already matched
const surrogatePattern =
/[\uD800-\uDBFF][\uDC00-\uDFFF]?|[\uDC00-\uDFFF]/gu;
let match = surrogatePattern.exec(node.value);
while (match) {
// only need to report non-paired surrogates
if (match[0].length < 2) {
context.report({
loc: node.loc,
messageId: "loneSurrogate",
data: {
surrogate: JSON.stringify(match[0]).slice(
1,
-1,
),
},
});
}
match = surrogatePattern.exec(node.value);
}
},
};
},
};
132 changes: 132 additions & 0 deletions tests/rules/no-unsafe-values.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* @fileoverview Tests for no-empty-keys rule.
* @author Bradley Meck Farias
*/

//------------------------------------------------------------------------------
// Imports
//------------------------------------------------------------------------------

import rule from "../../src/rules/no-unsafe-values.js";
import json from "../../src/index.js";
import { RuleTester } from "eslint";

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

const ruleTester = new RuleTester({
plugins: {
json,
},
language: "json/json",
});

ruleTester.run("no-unsafe-values", rule, {
valid: [
"123",
{
code: "1234",
language: "json/json5",
},
{
code: "12345",
language: "json/json5",
},
'"🔥"',
'"\\ud83d\\udd25"',
],
invalid: [
{
code: "2e308",
errors: [
{
messageId: "unsafeNumber",
line: 1,
column: 1,
endLine: 1,
endColumn: 6,
},
],
},
{
code: "-2e308",
errors: [
{
messageId: "unsafeNumber",
line: 1,
column: 1,
endLine: 1,
endColumn: 7,
},
],
},
{
code: '"\ud83d"',
errors: [
{
messageId: "loneSurrogate",
line: 1,
column: 1,
endLine: 1,
endColumn: 4,
},
],
},
{
code: '"\\ud83d"',
errors: [
{
messageId: "loneSurrogate",
line: 1,
column: 1,
endLine: 1,
endColumn: 9,
},
],
},
{
code: '"\udd25"',
errors: [
{
messageId: "loneSurrogate",
line: 1,
column: 1,
endLine: 1,
endColumn: 4,
},
],
},
{
code: '"\\udd25"',
errors: [
{
messageId: "loneSurrogate",
line: 1,
column: 1,
endLine: 1,
endColumn: 9,
},
],
},
{
code: '"\ud83d\ud83d"',
errors: [
{
message: "Lone surrogate '\\ud83d' found.",
line: 1,
column: 1,
endLine: 1,
endColumn: 5,
},
{
message: "Lone surrogate '\\ud83d' found.",
line: 1,
column: 1,
endLine: 1,
endColumn: 5,
},
],
},
],
});

0 comments on commit 6988e5c

Please sign in to comment.