geostyler / geostyler-openlayers-parser

GeoStyler Style Parser implementation for OpenLayers styles
BSD 2-Clause "Simplified" License
36 stars 26 forks source link

Allow raw strings for regex functions #699

Closed geographika closed 1 year ago

geographika commented 1 year ago

Description

A MapServer class such as in the tests here :

  CLASS
    EXPRESSION {bus,bank}

Converts to the following GeoStyler style (see here):

    filter: [
      '==', {
        name: 'strMatches',
        args: [{
          name: 'property',
          args: ['name']
        }, '/(bus|bank)/']

When this is converted to an OpenLayers style function using the code in OlStyleUtil

      case 'strMatches':
        return new RegExp(args[1] as string).test(args[0] as string);

The forward slashes are escaped and no features are matched:

r = new RegExp(args[1])
/\/(bus|bank)\//

// this is what we want
r = new RegExp(/(bus|bank)/)
/(bus|bank)/

// but as a string is passed they are escaped:

r = new RegExp('/(bus|bank)/')
/\/(bus|bank)\//

This pull request strips the start and trailing '\' from the string. As discussed with @jansule there may be issues if flags are stored in GeoStyler regex strings e.g. /pattern/gmi. To support this however would require passing 'gmi' to the flags parameter of the RegEx constructor e.g. new RegExp('pattern', 'gmi')

The following approach works for all cases r = new RegExp(eval(args[1])) but using eval is problematic. Initially I thought String.raw was an option but this doesn't work correctly.

Related issues or pull requests

Originally added as an issue at https://github.com/geostyler/geostyler-mapfile-parser/issues/247

Pull request type

Do you introduce a breaking change?

Checklist

KaiVolland commented 1 year ago

Can you point to the line where eval is used? I can't find it.

geographika commented 1 year ago

Can you point to the line where eval is used? I can't find it.

@KaiVolland - it was an alternate approach to the one used in this pull request, and would be to simply change the line to:

        return new RegExp(eval(args[1])).test(args[0] as string);

As the string is in a regex format /pattern/ this can be used by the RegExp constructor.

geographika commented 1 year ago

Closing in favour of #702