Repository: PrismJS/prism
Pull request #3507 (2022-07-26 09:01:31)

Java: Added support for constants
Java: Added support for constants.

github-actions[bot]: 
<!--
  0 failure: 
  0 warning: 
  
  1 markdown notices
  DangerID: danger-id-Danger;
-->



## No JS Changes
<p align="right">
  Generated by :no_entry_sign: <a href="https://danger.systems/js">dangerJS</a> against 35798cb3437ba88a2cafde753a52bc87d724edbd
</p>

RunDevelopment: If users really wanted to add their own Java variables, they could just do `Prism.language.java['variable'] = /\b(?:foo|bar)\b/`. Why is your new `PrismConfig` necessary?
wangliang181230: > If users really wanted to add their own Java variables, they could just do `Prism.language.java['variable'] = /\b(?:foo|bar)\b/`. Why is your new `PrismConfig` necessary?

Wait a minute, I also found this problem, so I'm developing a better solution.
wangliang181230: > If users really wanted to add their own Java variables, they could just do `Prism.language.java['variable'] = /\b(?:foo|bar)\b/`. Why is your new `PrismConfig` necessary?



> If users really wanted to add their own Java variables, they could just do `Prism.language.java['variable'] = /\b(?:foo|bar)\b/`. Why is your new `PrismConfig` necessary?

done

Patch:
diff --git a/MAINTAINERS.md b/MAINTAINERS.md
new file mode 100644
index 00000000..c7ee4991
--- /dev/null
+++ b/MAINTAINERS.md
@@ -0,0 +1,11 @@
+## Maintainers (alphabetical by user name)
+
+- [@Golmote](https://github.com/Golmote)
+- [@JaKXz](https://github.com/JaKXz) Jason Kurian
+- [@LeaVerou](https://github.com/LeaVerou) Lea Verou (original author)
+- [@mAAdhaTTah](https://github.com/mAAdhaTTah) James DiGioia <jamesorodig@gmail.com>
+- [@RunDevelopment](https://github.com/RunDevelopment) Michael Schmidt <msrd0000@gmail.com>
+
+## Former Maintainers
+
+- [@zeitgeist87](https://github.com/zeitgeist87) Andreas Rohner
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 00000000..c796689d
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,51 @@
+# Security Policy
+
+## What is considered a vulnerability?
+
+There are some types of [low-severity][severity] vulnerabilities that we will not acknowledge as CVE and treat as bugs instead.
+All vulnerabilities with a severity of medium and above will of course be acknowledged and fixed.
+
+Please see the below section on how we treat [ReDoS] vulnerabilities.
+
+If you are unsure whether a vulnerability you found qualifies, please report it as a vulnerability via email (see below).
+
+### ReDoS
+
+Prism is a regex-based syntax highlighter.
+As such, the main types of vulnerabilities reported to us are [ReDoS] vulnerabilities ([CWE-1333](https://cwe.mitre.org/data/definitions/1333.html)), aka slow regexes.
+
+However, not all ReDoS is created equal.
+A slow regex can be have a [worst-case time complexity](https://en.wikipedia.org/wiki/Time_complexity) anywhere from _O(n<sup>2</sup>)_ to _2<sup>O(n)</sup>_.
+This matters because a worst-case time complexity _≥ O(n<sup>3</sup>)_ is a [high severity][severity] vulnerability while _O(n<sup>2</sup>)_ is low or medium severity in the context of Prism.
+Furthermore, worst-case time complexities of _O(n<sup>2</sup>)_ can have 2 different causes: backtracking or moving.
+Backtracking is always fixable by rewriting the slow regex but moving is not (except in special cases).
+
+Because of their lower severity and the fact that moving is difficult or impossible to fix, we will treat regexes with worst-case time complexity of _O(n<sup>2</sup>)_ caused by moving as regular bugs and not as vulnerabilities.
+Please report them as [bugs](https://github.com/PrismJS/prism/issues/new/choose) instead of as vulnerabilities.
+
+If you found a slow regex but are unsure about the worst-case time complexity or its cause, please report it as a vulnerability via email (see below).
+
+
+## Reporting a Vulnerability
+
+***DO NOT CREATE AN ISSUE*** to report a vulnerability.
+
+Instead, please send an email to at least one of [Prism's maintainers](MAINTAINERS.md).
+See [Responsible Disclosure](https://en.wikipedia.org/wiki/Responsible_disclosure) for more details.
+
+### Procedure
+
+1.  After you send an email [a maintainer](MAINTAINERS.md), you should receive a response from the [Prism team](https://github.com/orgs/PrismJS/people) within 3 days.
+
+    We may require further information, so please keep in touch with us until the vulnerability has been fixed.
+
+2.  After the vulnerability has been confirmed and accepted, we will create a [security advisory](https://docs.github.com/en/code-security/security-advisories/about-github-security-advisories) and start working on a fix.
+
+    You will be [added as a collaborator](https://docs.github.com/en/code-security/security-advisories/adding-a-collaborator-to-a-security-advisory) (this requires a GitHub account).
+    At this point, all communication will occur using comments on the advisory and the [temporary private fork](https://docs.github.com/en/code-security/security-advisories/collaborating-in-a-temporary-private-fork-to-resolve-a-security-vulnerability).
+
+3.  After the fix has been merged, we will make a new release and publish the security advisory within one week.
+
+
+[ReDoS]: https://en.wikipedia.org/wiki/ReDoS
+[severity]: https://www.imperva.com/learn/application-security/cve-cvss-vulnerability/
diff --git a/components/prism-java.js b/components/prism-java.js
index 9d10f2fe..873154cf 100644
--- a/components/prism-java.js
+++ b/components/prism-java.js
@@ -55,7 +55,8 @@
 		'operator': {
 			pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,
 			lookbehind: true
-		}
+		},
+		'constant': /\b[A-Z][A-Z_\d]+\b/
 	});
 
 	Prism.languages.insertBefore('java', 'string', {
diff --git a/components/prism-java.min.js b/components/prism-java.min.js
index d240e507..9b90cf3c 100644
--- a/components/prism-java.min.js
+++ b/components/prism-java.min.js
@@ -1,1 +1,1 @@
-!function(e){var n=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,t="(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp("(^|[^\\w.])"+t+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[s,{pattern:RegExp("(^|[^\\w.])"+t+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()]|\\s*(?:\\[[\\s,]*\\]\\s*)?::\\s*new\\b)"),lookbehind:!0,inside:s.inside},{pattern:RegExp("(\\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\\s+)"+t+"[A-Z]\\w*\\b"),lookbehind:!0,inside:s.inside}],keyword:n,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":s,keyword:n,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp("(\\bimport\\s+)"+t+"(?:[A-Z]\\w*|\\*)(?=\\s*;)"),lookbehind:!0,inside:{namespace:s.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp("(\\bimport\\s+static\\s+)"+t+"(?:\\w+|\\*)(?=\\s*;)"),lookbehind:!0,alias:"static",inside:{namespace:s.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(/<keyword>/g,(function(){return n.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism);
\ No newline at end of file
+!function(e){var n=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,t="(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",s={pattern:RegExp("(^|[^\\w.])"+t+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[s,{pattern:RegExp("(^|[^\\w.])"+t+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=()]|\\s*(?:\\[[\\s,]*\\]\\s*)?::\\s*new\\b)"),lookbehind:!0,inside:s.inside},{pattern:RegExp("(\\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\\s+)"+t+"[A-Z]\\w*\\b"),lookbehind:!0,inside:s.inside}],keyword:n,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":s,keyword:n,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp("(\\bimport\\s+)"+t+"(?:[A-Z]\\w*|\\*)(?=\\s*;)"),lookbehind:!0,inside:{namespace:s.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp("(\\bimport\\s+static\\s+)"+t+"(?:\\w+|\\*)(?=\\s*;)"),lookbehind:!0,alias:"static",inside:{namespace:s.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(/<keyword>/g,(function(){return n.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism);
\ No newline at end of file
diff --git a/components/prism-scala.js b/components/prism-scala.js
index 9ba46492..b12f2e6b 100644
--- a/components/prism-scala.js
+++ b/components/prism-scala.js
@@ -47,3 +47,4 @@ Prism.languages.insertBefore('scala', 'triple-quoted-string', {
 
 delete Prism.languages.scala['class-name'];
 delete Prism.languages.scala['function'];
+delete Prism.languages.scala['constant'];
diff --git a/components/prism-scala.min.js b/components/prism-scala.min.js
index 6d7220d6..560000f4 100644
--- a/components/prism-scala.min.js
+++ b/components/prism-scala.min.js
@@ -1,1 +1,1 @@
-Prism.languages.scala=Prism.languages.extend("java",{"triple-quoted-string":{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},keyword:/<-|=>|\b(?:abstract|case|catch|class|def|derives|do|else|enum|extends|extension|final|finally|for|forSome|given|if|implicit|import|infix|inline|lazy|match|new|null|object|opaque|open|override|package|private|protected|return|sealed|self|super|this|throw|trait|transparent|try|type|using|val|var|while|with|yield)\b/,number:/\b0x(?:[\da-f]*\.)?[\da-f]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e\d+)?[dfl]?/i,builtin:/\b(?:Any|AnyRef|AnyVal|Boolean|Byte|Char|Double|Float|Int|Long|Nothing|Short|String|Unit)\b/,symbol:/'[^\d\s\\]\w*/}),Prism.languages.insertBefore("scala","triple-quoted-string",{"string-interpolation":{pattern:/\b[a-z]\w*(?:"""(?:[^$]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*?"""|"(?:[^$"\r\n]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*")/i,greedy:!0,inside:{id:{pattern:/^\w+/,greedy:!0,alias:"function"},escape:{pattern:/\\\$"|\$[$"]/,greedy:!0,alias:"symbol"},interpolation:{pattern:/\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,greedy:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:Prism.languages.scala}}},string:/[\s\S]+/}}}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala.function;
\ No newline at end of file
+Prism.languages.scala=Prism.languages.extend("java",{"triple-quoted-string":{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},keyword:/<-|=>|\b(?:abstract|case|catch|class|def|derives|do|else|enum|extends|extension|final|finally|for|forSome|given|if|implicit|import|infix|inline|lazy|match|new|null|object|opaque|open|override|package|private|protected|return|sealed|self|super|this|throw|trait|transparent|try|type|using|val|var|while|with|yield)\b/,number:/\b0x(?:[\da-f]*\.)?[\da-f]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e\d+)?[dfl]?/i,builtin:/\b(?:Any|AnyRef|AnyVal|Boolean|Byte|Char|Double|Float|Int|Long|Nothing|Short|String|Unit)\b/,symbol:/'[^\d\s\\]\w*/}),Prism.languages.insertBefore("scala","triple-quoted-string",{"string-interpolation":{pattern:/\b[a-z]\w*(?:"""(?:[^$]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*?"""|"(?:[^$"\r\n]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*")/i,greedy:!0,inside:{id:{pattern:/^\w+/,greedy:!0,alias:"function"},escape:{pattern:/\\\$"|\$[$"]/,greedy:!0,alias:"symbol"},interpolation:{pattern:/\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,greedy:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:Prism.languages.scala}}},string:/[\s\S]+/}}}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala.function,delete Prism.languages.scala.constant;
\ No newline at end of file


Test patch:
diff --git a/tests/languages/java/annotation_feature.test b/tests/languages/java/annotation_feature.test
index 3c645542..cc8a6a4c 100644
--- a/tests/languages/java/annotation_feature.test
+++ b/tests/languages/java/annotation_feature.test
@@ -16,7 +16,7 @@
 	["punctuation", "("],
 	"value",
 	["operator", "="],
-	"SOURCE",
+	["constant", "SOURCE"],
 	["punctuation", ")"],
 
 	["annotation", "@Target"],
@@ -24,9 +24,9 @@
 	"value",
 	["operator", "="],
 	["punctuation", "{"],
-	"PACKAGE",
+	["constant", "PACKAGE"],
 	["punctuation", ","],
-	"TYPE",
+	["constant", "TYPE"],
 	["punctuation", "}"],
 	["punctuation", ")"]
 ]
diff --git a/tests/languages/java/constant_feature.test b/tests/languages/java/constant_feature.test
new file mode 100644
index 00000000..34fbdd65
--- /dev/null
+++ b/tests/languages/java/constant_feature.test
@@ -0,0 +1,61 @@
+public class Test {
+    private static final String AAAA = "aaaaaa";
+
+    private String str = "1";
+
+    public static void main(String[] args) {
+        str += AAAA + "AAAA";
+    }
+}
+
+----------------------------------------------------
+
+[
+	["keyword", "public"],
+	["keyword", "class"],
+	["class-name", ["Test"]],
+	["punctuation", "{"],
+
+	["keyword", "private"],
+	["keyword", "static"],
+	["keyword", "final"],
+	["class-name", ["String"]],
+	["constant", "AAAA"],
+	["operator", "="],
+	["string", "\"aaaaaa\""],
+	["punctuation", ";"],
+
+	["keyword", "private"],
+	["class-name", ["String"]],
+	" str ",
+	["operator", "="],
+	["string", "\"1\""],
+	["punctuation", ";"],
+
+	["keyword", "public"],
+	["keyword", "static"],
+	["keyword", "void"],
+	["function", "main"],
+	["punctuation", "("],
+	["class-name", ["String"]],
+	["punctuation", "["],
+	["punctuation", "]"],
+	" args",
+	["punctuation", ")"],
+	["punctuation", "{"],
+
+	"\r\n        str ",
+	["operator", "+="],
+	["constant", "AAAA"],
+	["operator", "+"],
+	["string", "\"AAAA\""],
+	["punctuation", ";"],
+
+	["punctuation", "}"],
+
+	["punctuation", "}"]
+]
+
+----------------------------------------------------
+
+Checks for all constants.