From bb863f3f0ad7a548f9ba1464599790b9a641d18e Mon Sep 17 00:00:00 2001 From: Steve Ramage Date: Sat, 19 Jul 2025 07:57:11 -0700 Subject: [PATCH] feat: add support for new options such as Link.RxMaxCoalescedFrames=,FooOverUDP.UDPSourcePort=,Service.CapabilityBoundingSet= (Resolves #375) --- .../semanticdata/SemanticDataRepository.kt | 1 + .../optionvalues/SimpleGrammarOptionValues.kt | 81 +++++++++++ ...ueInspectionForSimpleGrammarOptionValue.kt | 132 ++++++++++++++++++ .../inspections/InvalidValueInspectionTest.kt | 1 + 4 files changed, 215 insertions(+) create mode 100644 src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/SimpleGrammarOptionValues.kt create mode 100644 src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionForSimpleGrammarOptionValue.kt diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/SemanticDataRepository.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/SemanticDataRepository.kt index e5fb83d6..ed4022e3 100644 --- a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/SemanticDataRepository.kt +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/SemanticDataRepository.kt @@ -155,6 +155,7 @@ class SemanticDataRepository private constructor() { validatorMap.putAll(NetworkAddressOptionValue.validators) validatorMap.putAll(InAddrPrefixesOptionValue.validators) validatorMap.putAll(UIntOptionValues.validators) + validatorMap.putAll(SimpleGrammarOptionValues.validators) fileClassToSectionNameToKeyValuesFromDoc["unit"]?.remove(SCOPE_KEYWORD) fileClassToSectionToKeyAndValidatorMap["unit"]?.remove(SCOPE_KEYWORD) } diff --git a/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/SimpleGrammarOptionValues.kt b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/SimpleGrammarOptionValues.kt new file mode 100644 index 00000000..5fd3d245 --- /dev/null +++ b/src/main/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/semanticdata/optionvalues/SimpleGrammarOptionValues.kt @@ -0,0 +1,81 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues + +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.Validator +import net.sjrx.intellij.plugins.systemdunitfiles.semanticdata.optionvalues.grammar.* + + + +class SimpleGrammarOptionValues(validatorName: String, grammar: Combinator) : GrammarOptionValue(validatorName, grammar) { + + + companion object { + + val Capabilities = FlexibleLiteralChoiceTerminal( + "CAP_AUDIT_CONTROL", + "CAP_AUDIT_READ", + "CAP_AUDIT_WRITE", + "CAP_BLOCK_SUSPEND", + "CAP_BPF", + "CAP_CHECKPOINT_RESTORE", + "CAP_CHOWN", + "CAP_DAC_OVERRIDE", + "CAP_DAC_READ_SEARCH", + "CAP_FOWNER", + "CAP_FSETID", + "CAP_IPC_LOCK", + "CAP_IPC_OWNER", + "CAP_KILL", + "CAP_LEASE", + "CAP_LINUX_IMMUTABLE", + "CAP_MAC_ADMIN", + "CAP_MAC_OVERRIDE", + "CAP_MKNOD", + "CAP_NET_ADMIN", + "CAP_NET_BIND_SERVICE", + "CAP_NET_BROADCAST", + "CAP_NET_RAW", + "CAP_PERFMON", + "CAP_SETGID", + "CAP_SETFCAP", + "CAP_SETPCAP", + "CAP_SETUID", + "CAP_SYS_ADMIN", + "CAP_SYS_BOOT", + "CAP_SYS_CHROOT", + "CAP_SYS_MODULE", + "CAP_SYS_NICE", + "CAP_SYS_PACCT", + "CAP_SYS_PTRACE", + "CAP_SYS_RAWIO", + "CAP_SYS_RESOURCE", + "CAP_SYS_TIME", + "CAP_SYS_TTY_CONFIG", + "CAP_SYSLOG", + "CAP_WAKE_ALARM" + ) + + val validators = mapOf( + Validator("config_parse_ip_port", "0") to SimpleGrammarOptionValues("config_parse_ip_port", SequenceCombinator(IntegerTerminal(0, 65536 ), EOF())), + Validator("config_parse_coalesce_u32", "0") to SimpleGrammarOptionValues("config_parse_coalesce_u32", + SequenceCombinator( + AlternativeCombinator( + // Handles hex + SequenceCombinator(LiteralChoiceTerminal("0x"), OneOrMore(RegexTerminal("[0-9a-zA-Z]{1,8}", "[0-9a-fA-F]{1,8}"))), + // Handles oct and dec formats (although not up to 32 bits for octal) + IntegerTerminal(0, 4_294_967_296), + ), + EOF())), + + Validator("config_parse_capability_set", "0") to SimpleGrammarOptionValues("config_parse_capability_set", + + SequenceCombinator( + AlternativeCombinator( + SequenceCombinator(ZeroOrOne(FlexibleLiteralChoiceTerminal("~")), Capabilities, ZeroOrMore(SequenceCombinator(WhitespaceTerminal(), Capabilities))), + FlexibleLiteralChoiceTerminal("~"), + ), + EOF())), + ) + + } +} + diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionForSimpleGrammarOptionValue.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionForSimpleGrammarOptionValue.kt new file mode 100644 index 00000000..00ee1cb3 --- /dev/null +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionForSimpleGrammarOptionValue.kt @@ -0,0 +1,132 @@ +package net.sjrx.intellij.plugins.systemdunitfiles.inspections + +import junit.framework.TestCase +import net.sjrx.intellij.plugins.systemdunitfiles.AbstractUnitFileTest + +class InvalidValueInspectionForSimpleGrammarOptionValue : AbstractUnitFileTest() { + + fun testNoWarningWhenValidPortsSpecified() { + // Fixture Setup + // language="unit file (systemd)" + val file=""" + [FooOverUDP] + Port=0 + Port=1 + Port=32768 + Port=65535 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.netdev", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + fun testWarningsWhenInvalidPortsSpecified() { + // Fixture Setup + // language="unit file (systemd)" + val file=""" + [FooOverUDP] + Port=-1 + Port=a + Port=65536 + + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.netdev", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(3, highlights) + } + + fun testNoWarningWhenValidCoalescedUint32Specified() { + // Fixture Setup + // language="unit file (systemd)" + val file=""" + [Link] + RxMaxCoalescedFrames=0 + RxMaxCoalescedFrames=0x0 + RxMaxCoalescedFrames=0x1 + RxMaxCoalescedFrames=0xab + RxMaxCoalescedFrames=0xAB + RxMaxCoalescedFrames=0455 + RxMaxCoalescedFrames=4294967295 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + fun testWarningsWhenInvalidCoalescedUint32Specified() { + // Fixture Setup + // language="unit file (systemd)" + val file=""" + [Link] + RxMaxCoalescedFrames=-1 + RxMaxCoalescedFrames=0xABZ + RxMaxCoalescedFrames=4294967296 + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.link", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(3, highlights) + } + + fun testNoWarningValidCapabilitiesAreSet() { + // Fixture Setup + // language="unit file (systemd)" + val file=""" + [Service] + CapabilityBoundingSet=CAP_SYS_ADMIN + CapabilityBoundingSet=CAP_CHOWN + CapabilityBoundingSet=CAP_DAC_OVERRIDE + CapabilityBoundingSet=CAP_MKNOD CAP_NET_ADMIN CAP_NET_RAW + CapabilityBoundingSet=~CAP_MAC_OVERRIDE + CapabilityBoundingSet=~ + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(0, highlights) + } + + fun testWarningsWhenInValidCapabilitiesAreSet() { + // Fixture Setup + // language="unit file (systemd)" + val file=""" + [Service] + CapabilityBoundingSet=CAP_CHOWNER + CapabilityBoundingSet=CAP_AUDIT_CONTROLCAP_SETGID + CapabilityBoundingSet=HELLO + CapabilityBoundingSet=CAP_SYS_BOOT ~CAP_SYS_TIME CAP_SYSLOG + """.trimIndent() + + // Execute SUT + setupFileInEditor("file.service", file) + enableInspection(InvalidValueInspection::class.java) + val highlights = myFixture.doHighlighting() + + // Verification + assertSize(4, highlights) + } + +} diff --git a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionTest.kt b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionTest.kt index b86811da..a12ee5a2 100644 --- a/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionTest.kt +++ b/src/test/kotlin/net/sjrx/intellij/plugins/systemdunitfiles/inspections/InvalidValueInspectionTest.kt @@ -22,6 +22,7 @@ class InvalidValueInspectionTest : AbstractUnitFileTest() { TTYReset=false TTYReset=f TTYReset=off + CacheDirectoryQuota= """.trimIndent()