Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Httpd: fails to parse comment ending in backslash #423

Closed
domcleal opened this issue Oct 28, 2016 · 3 comments
Closed

Httpd: fails to parse comment ending in backslash #423

domcleal opened this issue Oct 28, 2016 · 3 comments

Comments

@domcleal
Copy link
Member

The following file fails to parse with the Httpd module/lens:

# a\

The comment ending in a backslash must be followed by a blank line.

@lutter
Copy link
Member

lutter commented Sep 15, 2017

I just looked, and comment_val_re says that when a line ends with \\\n (backslash + newline), the next line is the continuation of a comment, but demands that that line has at least one non-blank character on it. Is the issue here that we need to drop the requirement for non-blank continuation lines ?

@lutter
Copy link
Member

lutter commented Sep 15, 2017

I just spent some more time playing with this, and the continuation lines in Apache files really cause a big headache, as we now need to consider whitespace characters any chars matching [ \t]|\\\r?\n which is real fun when you want to say stuff like "string that starts and ends with non-whitespace". I've actually given up on calculating those regexps by hand, and added a complement function, but even with that I am having trouble describing comments and empty lines in a way that passes the typechecker.

@lutter
Copy link
Member

lutter commented Sep 17, 2017

I think I have something that might work, but it's a bit involved. I actually haven't tried it in the Httpd lens yet, but here's a demonstration how empty and comment should work there:

module Cont =

  (* An experiment in handling empty lines and comments in httpd.conf and
   * similar. What makes this challenging is that httpd.conf allows
   * continuation lines; the markers for continuation lines (backslash +
   * newline) needs to be treated like any other whitespace.  *)

  (* The continuation sequence that indicates that we should consider the
   * next line part of the current line *)
  let cont = /\\\\\r?\n/

  (* Whitespace within a line: space, tab, and the continuation sequence *)
  let ws = /[ \t]/ | cont

  (* Any possible character - '.' does not match \n *)
  let any = /(.|\n)/

  (* Newline sequence - both for Unix and DOS newlines *)
  let nl = /\r?\n/

  (* Whitespace at the end of a line *)
  let eol = del (ws* . nl) "\n"

  (* A complete line that is either just whitespace or a comment that only
   * contains whitespace *)
  let empty = [ del (ws* . /#?/ . ws* . nl) "\n" ]

  (* A comment that is not just whitespace. We define it in terms of the
   * things that are not allowed as part of such a comment:
   *   1) Starts with whitespace
   *   2) Ends with whitespace, a backslash or \r
   *   3) Unescaped newlines
   *)
  let comment =
    let comment_start = del (ws* . "#" . ws* ) "# " in
    let unesc_eol = /[^\]?/ . nl in
    (* If we had a complement operator for regular expressions, we would
     *  write this as
     *  let line = complement (ws . any*
     *                     | any* . (ws|/[\r\\]/)
     *                     | any* . unesc_eol . any* )? in
     * Printing this out with 'print_regexp line' and simplifying it while
     * checking for equality with the ruby-fa bindings, we can write this
     * as follows: *)
    let w = /[^\t\n\r \\]/ in
    let r = /[\r\\]/ in
    let s = /[ \t]/ in
    let line = (w* . (r | w . s) . /.*/)? . w+ in
    [ label "#comment" . comment_start . store line . eol ]

  let lns = (comment|empty)*

  test [eol] get " \n" = { }
  test [eol] get " \t\n" = { }
  test [eol] get "\\\n\n" = { }

  test lns get "#  \\\r\n \t \\\n\n" = { }
  test lns get "#  x\n" = { "#comment" = "x" }
  test lns get "#  x\\\n\n" = { "#comment" = "x" }
  test lns get "#  \\\r\n \tx \\\n\n" = { "#comment" = "x" }
  test lns get "  \t\\\n# x\n" = { "#comment" = "x" }
  (* Not valid as it is an incomplete 'line' *)
  test lns get "# x\\\n" = *

lutter added a commit to lutter/augeas that referenced this issue Sep 27, 2017
lutter added a commit to lutter/augeas that referenced this issue Sep 27, 2017
lutter added a commit to lutter/augeas that referenced this issue Sep 27, 2017
lutter added a commit to lutter/augeas that referenced this issue Sep 29, 2017
@lutter lutter closed this as completed in b0e4ebd Sep 29, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants