oxlint-plugin-react-doctor 0.5.6-dev.424d8f9 → 0.5.6-dev.431e515

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +10 -65
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -890,64 +890,24 @@ const advancedEventHandlerRefs = defineRule({
890
890
  });
891
891
  //#endregion
892
892
  //#region src/plugin/rules/security-scan/utils/strip-comments-preserving-positions.ts
893
- const WHITESPACE_PATTERN = /\s/;
894
- const quotedLiteralHasWhitespace = (content, openQuoteIndex, delimiter) => {
895
- for (let cursor = openQuoteIndex + 1; cursor < content.length; cursor += 1) {
896
- const character = content[cursor];
897
- if (character === "\\") {
898
- cursor += 1;
899
- continue;
900
- }
901
- if (character === delimiter) return false;
902
- if (WHITESPACE_PATTERN.test(character)) return true;
903
- }
904
- return false;
905
- };
906
- const blankNonCodePreservingPositions = (content, blankStringContents) => {
893
+ const stripCommentsPreservingPositions = (content) => {
907
894
  const characters = content.split("");
908
895
  let stringDelimiter = null;
909
- let isBlankingString = false;
910
- const templateExpressionDepths = [];
911
896
  let index = 0;
912
- const blankUnlessNewline = (offset) => {
913
- if (offset < content.length && content[offset] !== "\n") characters[offset] = " ";
914
- };
915
897
  while (index < content.length) {
916
898
  const character = content[index];
917
899
  const nextCharacter = content[index + 1];
918
900
  if (stringDelimiter !== null) {
919
901
  if (character === "\\") {
920
- if (isBlankingString) {
921
- blankUnlessNewline(index);
922
- blankUnlessNewline(index + 1);
923
- }
924
- index += 2;
925
- continue;
926
- }
927
- if (character === stringDelimiter) {
928
- stringDelimiter = null;
929
- index += 1;
930
- continue;
931
- }
932
- if (blankStringContents && stringDelimiter === "`" && character === "$" && nextCharacter === "{") {
933
- templateExpressionDepths.push(0);
934
- stringDelimiter = null;
935
902
  index += 2;
936
903
  continue;
937
904
  }
938
- if (isBlankingString) blankUnlessNewline(index);
905
+ if (character === stringDelimiter) stringDelimiter = null;
939
906
  index += 1;
940
907
  continue;
941
908
  }
942
- if (character === "\"" || character === "'") {
909
+ if (character === "\"" || character === "'" || character === "`") {
943
910
  stringDelimiter = character;
944
- isBlankingString = blankStringContents && quotedLiteralHasWhitespace(content, index, character);
945
- index += 1;
946
- continue;
947
- }
948
- if (character === "`") {
949
- stringDelimiter = "`";
950
- isBlankingString = blankStringContents;
951
911
  index += 1;
952
912
  continue;
953
913
  }
@@ -966,42 +926,29 @@ const blankNonCodePreservingPositions = (content, blankStringContents) => {
966
926
  index += 2;
967
927
  break;
968
928
  }
969
- blankUnlessNewline(index);
929
+ if (content[index] !== "\n") characters[index] = " ";
970
930
  index += 1;
971
931
  }
972
932
  continue;
973
933
  }
974
- if (templateExpressionDepths.length > 0) {
975
- const innermost = templateExpressionDepths.length - 1;
976
- if (character === "{") templateExpressionDepths[innermost] += 1;
977
- else if (character === "}") if (templateExpressionDepths[innermost] === 0) {
978
- templateExpressionDepths.pop();
979
- stringDelimiter = "`";
980
- isBlankingString = blankStringContents;
981
- } else templateExpressionDepths[innermost] -= 1;
982
- }
983
934
  index += 1;
984
935
  }
985
936
  return characters.join("");
986
937
  };
987
- const stripCommentsPreservingPositions = (content) => blankNonCodePreservingPositions(content, false);
988
- const stripCommentsAndStringLiteralsPreservingPositions = (content) => blankNonCodePreservingPositions(content, true);
989
938
  //#endregion
990
939
  //#region src/plugin/rules/security-scan/utils/scan-by-pattern.ts
991
940
  const strippedContentCache = /* @__PURE__ */ new WeakMap();
992
- const stringStrippedContentCache = /* @__PURE__ */ new WeakMap();
993
- const getScannableContent = (file, ignoreStringLiterals = false) => {
941
+ const getScannableContent = (file) => {
994
942
  if (!SOURCE_FILE_PATTERN.test(file.relativePath)) return file.content;
995
- const cache = ignoreStringLiterals ? stringStrippedContentCache : strippedContentCache;
996
- const cachedContent = cache.get(file);
943
+ const cachedContent = strippedContentCache.get(file);
997
944
  if (cachedContent !== void 0) return cachedContent;
998
- const strippedContent = ignoreStringLiterals ? stripCommentsAndStringLiteralsPreservingPositions(file.content) : stripCommentsPreservingPositions(file.content);
999
- cache.set(file, strippedContent);
945
+ const strippedContent = stripCommentsPreservingPositions(file.content);
946
+ strippedContentCache.set(file, strippedContent);
1000
947
  return strippedContent;
1001
948
  };
1002
- const scanByPattern = ({ shouldScan, pattern, requireAll, suppressWhen, ignoreStringLiterals, message }) => (file) => {
949
+ const scanByPattern = ({ shouldScan, pattern, requireAll, suppressWhen, message }) => (file) => {
1003
950
  if (!shouldScan(file)) return [];
1004
- const content = getScannableContent(file, ignoreStringLiterals);
951
+ const content = getScannableContent(file);
1005
952
  if (requireAll !== void 0 && !requireAll.every((gate) => gate.test(content))) return [];
1006
953
  const matchedPattern = (pattern instanceof RegExp ? [pattern] : pattern).find((candidate) => candidate.test(content));
1007
954
  if (matchedPattern === void 0) return [];
@@ -1026,7 +973,6 @@ const agentToolCapabilityRisk = defineRule({
1026
973
  shouldScan: (file) => isProductionSourcePath(file.relativePath) && AGENT_TOOL_CONTEXT_PATH_PATTERN.test(file.relativePath),
1027
974
  pattern: AGENT_TOOL_DEFINITION_PATTERN,
1028
975
  requireAll: [AGENT_TOOL_DANGEROUS_CAPABILITY_PATTERN],
1029
- ignoreStringLiterals: true,
1030
976
  message: "An agent-callable tool appears to expose network, filesystem, shell, or code-execution capability."
1031
977
  })
1032
978
  });
@@ -13521,7 +13467,6 @@ const mcpToolCapabilityRisk = defineRule({
13521
13467
  shouldScan: (file) => isProductionSourcePath(file.relativePath),
13522
13468
  pattern: /\bserver\.\s*tool\s*\(|\bregisterTool\s*\(|\bsetRequestHandler\s*\(\s*CallToolRequestSchema/,
13523
13469
  requireAll: [/\bfrom\s+["']@modelcontextprotocol\/sdk[^"']*["']|\bMcpServer\b|\bMcpAgent\b/, AGENT_TOOL_DANGEROUS_CAPABILITY_PATTERN],
13524
- ignoreStringLiterals: true,
13525
13470
  message: "An MCP tool/resource/prompt handler appears to expose file, shell, network, or code-execution capability."
13526
13471
  })
13527
13472
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-react-doctor",
3
- "version": "0.5.6-dev.424d8f9",
3
+ "version": "0.5.6-dev.431e515",
4
4
  "description": "oxlint plugin for React Doctor: diagnose React codebases for security, performance, correctness, accessibility, bundle-size, and architecture issues",
5
5
  "keywords": [
6
6
  "accessibility",