Skip to content

Ajv fails with new namespace regular expression #982

Closed

Description

@sei-vsarvepalli

Describe the bug
The npm project ajv issued by CVE program for Node.js based schema creation, bundling and verification (test cases). Currently the latest ajv-cli and acv-formats both fail to parse the regular expression for namespace in SSVC selections schema

To Reproduce
Steps to reproduce the behavior:
Run this scripts

npm install --loglevel verbose -g ajv-cli@^5.0.0 ajv-formats@^3.0.1 yargs          
npm list -g ajv-cli
npm list -g ajv                                    
ajv compile -s schema/imports/ssvc/SelectionList_2_0_0.schema.json --spec=draft2020 --strict=false 

The error is

schema schema/imports/ssvc/SelectionList_2_0_0.schema.json is invalid
error: Invalid regular expression: /^(x_([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+\#(([a-z]|[0-9]))+((\.|-)(([a-z]|[0-9]))+)*|[a-z]([a-z]|[0-9])(((\.|-))?(([a-z]|[0-9]))+)+(\#(([a-z]|[0-9]))+((\.|-)(([a-z]|[0-9]))+)*)?)((/|/(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo))((/((([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo)|\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+\#(([a-z]|[0-9]))+((\.|-)(([a-z]|[0-9]))+)*|\.(([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+|([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+\#(([a-z]|[0-9]))+((\.|-)(([a-z]|[0-9]))+)*)\$(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo)))+)?)?$/u: Invalid escape

Expected behavior
Validation of the Regex that is complex for namespace.

Related projects

https://github.com/ajv-validator
https://github.com/CVEProject/cve-schema

Related Issues
ajv-validator/ajv-formats#111
CVEProject/cve-schema#144

Activity

  1. sei-vsarvepalli commented on Sep 25, 2025

    @sei-vsarvepalli
    ContributorAuthor

    @bernhardreiter - we could use your help on this one for sure. The ajv npm project is in the critical path for integration to the CVE program.

  2. sei-vsarvepalli commented on Sep 25, 2025

    @sei-vsarvepalli
    ContributorAuthor

    It looks like replacing the \\# to # fixes the ajv compile issue at least. May need to update our regular expression to support this change and update the schema as appropriate before usage in production.

    Also adding @tschmidtb51 of the potential change and impact to CSAF 2.1 integration plan.

    diff SelectionList_2_0_0.schema.json fix/SelectionList_2_0_0.schema.json

    84c84
    <           "pattern": "^(x_([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+\\#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*|[a-z]([a-z]|[0-9])(((\\.|-))?(([a-z]|[0-9]))+)+(\\#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*)?)((/|/(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo))((/((([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo)|\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+\\#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*|\\.(([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+|([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+\\#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*)\\$(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo)))+)?)?$",
    ---
    >           "pattern": "^(x_([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*|[a-z]([a-z]|[0-9])(((\\.|-))?(([a-z]|[0-9]))+)+(#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*)?)((/|/(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo))((/((([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo)|\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*|\\.(([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+|([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?(\\.([a-z]|[0-9])(((([a-z]|[0-9])|-)){0,61}([a-z]|[0-9]))?)+#(([a-z]|[0-9]))+((\\.|-)(([a-z]|[0-9]))+)*)\\$(([a-zA-Z]{2,3}(-[a-zA-Z]{3}(-[a-zA-Z]{3}){0,2})?|[a-zA-Z]{4,8})(-[a-zA-Z]{4})?(-([a-zA-Z]{2}|[0-9]{3}))?(-(([a-zA-Z0-9]){5,8}|[0-9]([a-zA-Z0-9]){3}))*(-[0-9A-WY-Za-wy-z](-([a-zA-Z0-9]){2,8})+)*(-[xX](-([a-zA-Z0-9]){2,8})+)?|[xX](-([a-zA-Z0-9]){2,8})+|i-default|i-mingo)))+)?)?$",
  3. bernhardreiter commented on Sep 25, 2025

    @bernhardreiter
    Contributor

    @tschmidtb51 gave me a warning about this problem, so I've already created an upstream issue: eclipse-aascw/abnf-to-regexp#49

    Yes, just replacing \\# to # is the quick fix. I probably look at the upstream fix in the next days as well.

    There was a potential other regexp compatibility problem, but I haven't gotten the details yet.

  4. bernhardreiter commented on Sep 29, 2025

    @bernhardreiter
    Contributor

    Interesting is that \# seems to be accepted both by Javascript and Typescript as regular expression (tested with nodejs, typescript online, Webbrowser console)

    node
    r3 = new RegExp('a+\#')
    r3.test("a#")
    true
    
     r4 =  new RegExp('a+\\#')
    r4.test("a#")
    true
    

    the problems come up with unicode-aware regular expressions, e.g.

    r1 = new RegExp("\\#", "u");
    Uncaught SyntaxError: Invalid regular expression: /\#/: Invalid escape
    

    See the documentation here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Regex_invalid_identity_escape

    Here is code to directly use javascript parsing the regular expression pattern (when in the git repo root):

    var fs = require('fs');
    var f = './data/schema/v2/SelectionList_2_0_0.schema.json';
    var j = JSON.parse(fs.readFileSync(f, 'utf-8'))
    var r = new RegExp(j.$defs.Selection.properties.namespace.pattern, "u")
    

    I get no error with node --version v18.20.4.

  5. domachine commented on Sep 29, 2025

    @domachine

    Interesting is that \# seems to be accepted both by Javascript and Typescript as regular expression (tested with nodejs, typescript online, Webbrowser console)

    node
    r3 = new RegExp('a+\#')
    r3.test("a#")
    true
    
     r4 =  new RegExp('a+\\#')
    r4.test("a#")
    true
    

    Here is code to directly use javascript parsing the regular expression pattern (when in the git repo root):

    var fs = require('fs');
    var f = './data/schema/v2/SelectionList_2_0_0.schema.json';
    var j = JSON.parse(fs.readFileSync(f, 'utf-8'))
    var r = new RegExp(j.$defs.Selection.properties.namespace.pattern)
    

    I get no error with node --version v18.20.4.

    The regex is validated when constructing it with the u flag (which is also being used by ajv):

    new RegExp('a+\\#', 'u')
    

    This throws an error for me under node 22.19.0

  6. bernhardreiter commented on Sep 29, 2025

    @bernhardreiter
    Contributor

    The regex is validated when constructing it with the u flag (which is also being used by ajv)

    Yes, thanks for the hint. (You've commented while I was already editing my last comment towards that).

    Just checked: unicode aware mode seems to be correct for https://json-schema.org/understanding-json-schema/reference/string#regexp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions