Uploaded image for project: 'Puppet'
  1. Puppet
  2. PUP-7475

A regex literal for matching backslashes causes a lexer error

    Details

    • Template:
    • Team:
      Puppet Developer Experience
    • Story Points:
      1
    • Sprint:
      PDE 2017-05-03, PDE 2017-05-31
    • Release Notes:
      Bug Fix
    • Release Notes Summary:
      A literal regex for matching a backslash would cause a lexer error. This is now fixed.
    • QA Risk Assessment:
      No Action
    • QA Risk Assessment Reason:
      covered by unit tests

      Description

      Attempting to declare a regex literal for matching a single backslash results in a lexer error when the manifest is parsed.

      Reproduction Case

      Apply the following manifest which multiplies backslashes within a windows path:

      $win_path = "c:\\some\\path"
      $backslash = /\\/
       
      $escaped_path = regsubst($win_path, $backslash, '\\\\\\\\', 'G')
       
       
      notice("Escaped path is: ${escaped_path}")
      

      Outcome

      Applying the manifest results in a parser error coming from the lexer code.

      # puppet apply regex_test.pp --trace
      Error: Could not parse for environment production: no implicit conversion of nil into String on node pe-201643-master.puppetdebug.vlan
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/pops/parser/lexer2.rb:380:in `+'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/pops/parser/lexer2.rb:380:in `block in initialize'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/pops/parser/lexer2.rb:710:in `call'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/pops/parser/lexer2.rb:710:in `scan'
      /opt/puppetlabs/puppet/lib/ruby/2.1.0/racc/parser.rb:319:in `_racc_yyparse_c'
      /opt/puppetlabs/puppet/lib/ruby/2.1.0/racc/parser.rb:319:in `yyparse'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/pops/parser/parser_support.rb:240:in `_parse'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/pops/parser/parser_support.rb:84:in `parse_file'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/pops/parser/evaluating_parser.rb:41:in `parse_file'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/parser/e4_parser_adapter.rb:31:in `parse'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/node/environment.rb:512:in `perform_initial_import'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/node/environment.rb:236:in `known_resource_types'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/parser/compiler.rb:762:in `block in initvars'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/context.rb:65:in `override'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet.rb:241:in `override'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/parser/compiler.rb:760:in `initvars'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/parser/compiler.rb:422:in `initialize'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/parser/compiler.rb:33:in `new'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/parser/compiler.rb:33:in `compile'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/catalog/compiler.rb:266:in `block (2 levels) in compile'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util/profiler/around_profiler.rb:58:in `profile'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util/profiler.rb:51:in `profile'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/catalog/compiler.rb:264:in `block in compile'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util.rb:223:in `block in benchmark'
      /opt/puppetlabs/puppet/lib/ruby/2.1.0/benchmark.rb:294:in `realtime'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util.rb:222:in `benchmark'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/catalog/compiler.rb:262:in `compile'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/catalog/compiler.rb:53:in `find'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/indirector/indirection.rb:194:in `find'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application/apply.rb:256:in `block in main'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/context.rb:65:in `override'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet.rb:241:in `override'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application/apply.rb:225:in `main'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application/apply.rb:170:in `run_command'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application.rb:344:in `block in run'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util.rb:540:in `exit_on_fail'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/application.rb:344:in `run'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util/command_line.rb:132:in `run'
      /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/puppet/util/command_line.rb:72:in `execute'
      /opt/puppetlabs/puppet/bin/puppet:5:in `<main>'
      

      Expected Outcome

      Notice: Scope(Class[main]): Escaped path is: c:\\some\\path
      

      Recommended Workaround

      Enclosing the backslashes in a capture group allows a regex literal to be constructed:

      $backslash = /(\\)/
      

        Attachments

          Activity

            jsd-sla-details-panel

              People

              • Assignee:
                Unassigned
                Reporter:
                chuck Charlie Sharpsteen
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: