peakwinter/python-nginx

In this case, it's stuck

Closed this issue · 3 comments

zyyoo commented

when i use nginx.loadf('xxxxx').as_dict

  • this is my nginx.conf
server{
    listen 80;
    #OPEN-PORT-443
    listen 443 ssl;
    server_name www.xxx.com;
    root /wwww/wwww;
    
    location ~ .*\.(js|css)?$ {
        expires 12h;
        error_log off;
        access_log /dev/null;  # it can work
    }
}
server{
    listen 80;
    #OPEN-PORT-443
    listen 443 ssl;
    server_name www.xxx.com;
    root /wwww/wwww;
    
    location ~ .*\.(js|css)?$ {
        expires 12h;
        error_log off;
        access_log /dev/null  # it can't work
    }
}

He'll be stuck here all the time,how can i fix it ?


---->index 
        error_log off;
        access_log /dev/null
    }
}

---->index 
        access_log /dev/null
    }
}

Good catch! After debugging the regexp for Key I noticed there is a case where the regexp get stuck due to catastrophic backtracking. Instead of trying to parse the keys forever (when there is a missing semi colon) I've added a quick fix to always expect it when the Key parsing is reached.

Could you check if #36 solves this problem (i.e. the parsing will not get stuck forever but throw a new Exception) ?

I've added a test with your failing config in this PR as well.

zyyoo commented

Thank you for your time,At the moment, he won't get stuck
but It affects normal parsing;
as follows

input:
server{
    listen 80;
    #OPEN-PORT-443
    listen 443 ssl;
    server_name www.xxx.com;
    root /wwww/wwww;

    location ~ .*\.(js|css)?$ {
        expires 12h;
        error_log off;
        access_log /dev/null;  
    }
}
output:
Traceback (most recent call last):
  File "/Users/lemon/PycharmProjects/test/nginx/test2.py", line 592, in <module>
    c = loadf('nginx.conf').as_dict
  File "/Users/lemon/PycharmProjects/test/nginx/test2.py", line 556, in loadf
    return load(f)
  File "/Users/lemon/PycharmProjects/test/nginx/test2.py", line 547, in load
    return loads(fobj.read())
  File "/Users/lemon/PycharmProjects/test/nginx/test2.py", line 510, in loads
    raise ParseError("Config syntax, missing ';' at index: {}".format(index))
__main__.ParseError: Config syntax, missing ';' at index: 241

I changed the judgement condition.

if ";" not in data[index:] and data[index:].find("}") != -1:
    # If there is still something to parse, expect ';' otherwise
    # the Key regexp can get stuck due to regexp catastrophic backtracking
    raise ParseError("Config syntax, missing ';' at index: {}".format(index))

Although it can solve this problem,but I hope you can optimize the regular expression

That's true it would fail in that case, I've added your improvement for the if statement condition in #37.

Optimizing the regular expression would be good (feel free to change it if you find a better way), although I do feel that throwing a correct parse error instead of a index out of bounds exception gives the user more information about what is wrong (should probably do that in other config syntax errors as well).