From 746cd7d8ca8dcf8165ebb27c48bc31504062d0da Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Tue, 17 Mar 2026 00:32:41 +0100 Subject: [PATCH 1/2] Fix #239: Handle YANG double-quoted string escape sequences per RFC 7950 StringConverter.toValue() now processes escape sequences (\\, \n, \t, \") in double-quoted strings per RFC 7950 Section 6.1.3. This fixes regex patterns with backslash escapes being incorrectly rejected. --- .../yang/YangValueConverterService.xtend | 33 ++++++++++++++++++- .../yang/tests/validation/RegexpTest.xtend | 20 +++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/YangValueConverterService.xtend b/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/YangValueConverterService.xtend index 7360b247..0a46da82 100644 --- a/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/YangValueConverterService.xtend +++ b/yang-lsp/io.typefox.yang/src/main/java/io/typefox/yang/YangValueConverterService.xtend @@ -40,7 +40,12 @@ class YangValueConverterService extends AbstractDeclarativeValueConverterService if (!n.hidden) { val seg = n.text if (isQuoted(seg)) { - result.append(seg.substring(1, seg.length-1)) + val inner = seg.substring(1, seg.length-1) + if (seg.startsWith("\"")) { + result.append(unescapeYangDoubleQuoted(inner)) + } else { + result.append(inner) + } } else { result.append(seg) } @@ -49,6 +54,32 @@ class YangValueConverterService extends AbstractDeclarativeValueConverterService return result.toString } + /** + * Process YANG double-quoted string escape sequences per RFC 7950 Section 6.1.3. + */ + def static String unescapeYangDoubleQuoted(String s) { + val bsIndex = s.indexOf('\\') + if (bsIndex < 0) return s + val sb = new StringBuilder(s.length) + sb.append(s, 0, bsIndex) + var i = bsIndex + while (i < s.length) { + val c = s.charAt(i) + if (c === 0x5C && i + 1 < s.length) { + val next = s.charAt(i + 1) + if (next === 0x6E) { sb.append('\n'); i += 2 } + else if (next === 0x74) { sb.append('\t'); i += 2 } + else if (next === 0x22) { sb.append('"'); i += 2 } + else if (next === 0x5C) { sb.append('\\'); i += 2 } + else { sb.append(c); i++ } + } else { + sb.append(c) + i++ + } + } + return sb.toString + } + def static boolean isQuoted(String text) { if(text.length < 2) { return false diff --git a/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/validation/RegexpTest.xtend b/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/validation/RegexpTest.xtend index 7a583030..fad3aa66 100644 --- a/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/validation/RegexpTest.xtend +++ b/yang-lsp/io.typefox.yang/src/test/java/io/typefox/yang/tests/validation/RegexpTest.xtend @@ -46,6 +46,26 @@ class RegexpTest extends AbstractYangTest { assertNoErrors(foo.allContents.filter(Pattern).head, TYPE_ERROR) } + @Test def void testIssue239() { + val foo = load(''' + module foo { + yang-version 1.1; + namespace urn:ietf:params:xml:ns:yang:foo; + prefix foo; + + typedef foo { + type string { + pattern "[a-zA-Z0-9!$%\\^()\\[\\]_\\-~{}.+]*"; + } + } + } + ''') + val p = foo.allContents.filter(Pattern).head + System.out.println("Issue 239 regexp value: [" + p.regexp + "]") + validator.validate(foo) + assertNoErrors(p, TYPE_ERROR) + } + @Test def void testIllegalPattern_0() { val foo = load(''' module foo { From 94c5684680355183d03750ba85ffe270f027f127 Mon Sep 17 00:00:00 2001 From: Siddharth Sharma Date: Tue, 17 Mar 2026 00:38:31 +0100 Subject: [PATCH 2/2] Fix CI: Upgrade deprecated GitHub Actions from v3 to v4 actions/upload-artifact v3 was deprecated and now auto-fails. Upgrade checkout, setup-java, and upload-artifact to v4. --- .github/workflows/main.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6b8b8809..faec902b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,9 +22,9 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: 11 distribution: adopt @@ -53,19 +53,19 @@ jobs: with: files: yang-lsp/**/test-results/**/*.xml - name: Archive yang-language-server - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: yang-language-server_${{ env.PROJECT_VERSION }} path: | yang-lsp/build/yang-language-server_[0-9]*.zip - name: Archive yang-language-server_diagram-extension - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: yang-language-server_diagram-extension_${{ env.PROJECT_VERSION }} path: | yang-lsp/build/yang-language-server_diagram-extension*.zip - name: Archive yang-tool_cli - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: yang-tool_cli_${{ env.PROJECT_VERSION }} path: |