daveshanley / vacuum

vacuum is the worlds fastest OpenAPI 3, OpenAPI 2 / Swagger linter and quality analysis tool. Built in go, it tears through API specs faster than you can think. vacuum is compatible with Spectral rulesets and generates compatible reports.
https://quobix.com/vacuum
MIT License
488 stars 39 forks source link

Escaping `*` in pattern is flagged as invalid `ECMA-262` regex #496

Closed maboehm closed 1 month ago

maboehm commented 1 month ago

We have a regular expression that matches a literal * character (it matches a cron schedule), but this is not accepted as a ECMA-262 expression:

{
  "openapi": "3.0.1",
  "info": {
    "title": "pattern-bug",
    "version": "1.0",
    "description": "example"
  },
  "paths": {},
  "components": {
    "schemas": {
      "foo": {
        "pattern": "\\*",
        "type": "string"
      }
    }
  }
}
$ vacuum lint -e -d test.json
test.json:12:9 | error    | schema `pattern` should be a ECMA-262 regular expression dialect | oas-schema-check | Schemas  | $.components.schemas['foo'].pattern

Interestingly, if I change the pattern to "^\\*" it is accepted, but e.g. "^A(\\*)" is not.

Done using version: 0.9.16

daveshanley commented 1 month ago

* is not a valid ECMA-262 expression. \\* is however. The way this works is that the rule literally compiles your expression to JavaScript and executes it in a VM inside the application.

See the code here:

https://github.com/daveshanley/vacuum/blob/main/functions/openapi/schema_type.go#L143

If the RegExp('YOUR PATTERN") fails to compile, then the violation is triggered.

To validate, try and use * as a ECMA regex on https://regex101.com/

Screenshot 2024-05-25 at 9 41 22 AM

Screenshot 2024-05-25 at 9 42 15 AM

maboehm commented 1 month ago

@daveshanley thanks for looking at this.

I think I was not clear enough. I am trying to match just an asterix *, so like this: image

The problem now is, that in the JSON, I cannot specify "pattern": "\*",, because then parsing fails with unable to process spec 'test.json', error: unable to parse specification: yaml: line 12: found unknown escape character. So I think I should be able to specify \\* - which means please escape the backslash, before interpreting this as a regex.

When I try this in yaml with

openapi: 3.0.1
info:
  title: pattern-bug
  version: "1.0"
  description: example
paths: {}
components:
  schemas:
    foo:
      pattern: \*
      type: string

I get the same error, but setting pattern: ^\* is accepted. Then again, setting pattern: ^(\*) it complains about the regex again. All three patterns are valid ECMA-262 regex