Handle IPv6 address brackets correctly in bypass list. Fix #998.

This commit is contained in:
FelisCatus 2017-02-26 00:32:37 -05:00
parent 2292507673
commit bf3df2b707
4 changed files with 73 additions and 20 deletions

View File

@ -306,6 +306,7 @@ module.exports = exports =
ip: null
scheme: null
url: null
normalizedPattern: ''
server = condition.pattern
if server == '<local>'
cache.host = server
@ -313,6 +314,7 @@ module.exports = exports =
parts = server.split '://'
if parts.length > 1
cache.scheme = parts[0]
cache.normalizedPattern = cache.scheme + '://'
server = parts[1]
parts = server.split '/'
@ -322,36 +324,43 @@ module.exports = exports =
if addr and not isNaN(prefixLen)
cache.ip =
conditionType: 'IpCondition'
ip: parts[0]
ip: @normalizeIp addr
prefixLength: prefixLen
cache.normalizedPattern += cache.ip.ip + '/' + cache.ip.prefixLength
return cache
if server.charCodeAt(server.length - 1) != ']'.charCodeAt(0)
# The server can be an IP address with or without brackets.
serverIp = @parseIp(server)
if not serverIp?
pos = server.lastIndexOf(':')
if pos >= 0
matchPort = server.substring(pos + 1)
server = server.substring(0, pos)
serverIp = @parseIp server
serverRegex = null
serverIp = @parseIp server
if serverIp?
if serverIp.regularExpressionString?
regexStr = serverIp.regularExpressionString(true)
serverRegex = '\\[' + regexStr + '\\]'
server = @normalizeIp serverIp
if serverIp.v4
cache.normalizedPattern += server
else
server = @normalizeIp serverIp
else if server.charCodeAt(0) == '.'.charCodeAt(0)
server = '*' + server
cache.normalizedPattern += '[' + server + ']'
else
if server.charCodeAt(0) == '.'.charCodeAt(0)
server = '*' + server
cache.normalizedPattern = server
if matchPort
if not serverRegex?
serverRegex = shExp2RegExp(server)
serverRegex = serverRegex.substring(1, serverRegex.length - 1)
cache.port = matchPort
cache.normalizedPattern += ':' + cache.port
# In URL, IPv6 server addresses need to be bracketed.
if serverIp? and not serverIp.v4
server = '[' + server + ']'
serverRegex = shExp2RegExp(server)
serverRegex = serverRegex.substring(1, serverRegex.length - 1)
scheme = cache.scheme ? '[^:]+'
cache.url = @safeRegex('^' + scheme + ':\\/\\/' + serverRegex +
':' + matchPort + '\\/')
else if server != '*'
if serverRegex
serverRegex = '^' + serverRegex + '$'
else
serverRegex = shExp2RegExp server, trimAsterisk: true
# In host, IPv6 server addresses are never bracketed.
serverRegex = shExp2RegExp server, trimAsterisk: true
cache.host = @safeRegex(serverRegex)
return cache
match: (condition, request, cache) ->
@ -374,6 +383,13 @@ module.exports = exports =
return false if not cache.host.test(request.host)
return false if cache.url? and !cache.url.test(request.url)
return true
str: (condition) ->
analyze = @_handler(condition).analyze
cache = analyze.call(exports, condition)
if cache.normalizedPattern
return cache.normalizedPattern
else
return condition.pattern
compile: (condition, cache) ->
cache = cache.analyzed
if cache.url?

View File

@ -246,7 +246,7 @@ module.exports = exports =
}
{
conditionType: 'BypassCondition'
pattern: '::1'
pattern: '[::1]'
}
{
conditionType: 'BypassCondition'

View File

@ -183,6 +183,13 @@ describe 'Conditions', ->
result = Conditions.analyze(cond)
testCond(cond, 'http://[::1]:8080/', 'match')
testCond(cond, 'http://[1::1]:8080/', not 'match')
it 'should correctly support IPv6 canonicalization 2', ->
cond =
conditionType: 'BypassCondition'
pattern: '[::1]'
result = Conditions.analyze(cond)
testCond(cond, 'http://[::1]:8080/', 'match')
testCond(cond, 'http://[1::1]:8080/', not 'match')
it 'should parse IPv4 CIDR notation', ->
cond =
@ -559,6 +566,32 @@ describe 'Conditions', ->
result.should.equal('HostWildcard: ' + condition.pattern)
cond = Conditions.fromStr(result)
cond.should.eql(condition)
it 'should encode & decode BypassCondition correctly', ->
condition =
conditionType: 'BypassCondition'
pattern: '127.0.0.1/16'
result = Conditions.str(condition)
result.should.equal('Bypass: 127.0.0.1/16')
cond = Conditions.fromStr(result)
cond.should.eql(condition)
it 'should add brackets for IPv6 hosts in BypassCondition', ->
condition =
conditionType: 'BypassCondition'
pattern: '::1'
result = Conditions.str(condition)
result.should.equal('Bypass: [::1]')
cond = Conditions.fromStr(result)
cond.conditionType.should.equal('BypassCondition')
cond.pattern.should.equal('[::1]')
it 'should add brackets for IPv6 hosts with scheme in BypassCondition', ->
condition =
conditionType: 'BypassCondition'
pattern: 'http://::1'
result = Conditions.str(condition)
result.should.equal('Bypass: http://[::1]')
cond = Conditions.fromStr(result)
cond.conditionType.should.equal('BypassCondition')
cond.pattern.should.equal('http://[::1]')
it 'should encode & decode IpCondition correctly', ->
condition =
conditionType: 'IpCondition'

View File

@ -74,6 +74,10 @@ class ChromeOptions extends OmegaTarget.Options
chrome.browserAction.setBadgeText(text: '')
return
_formatBypassItem: (condition) ->
str = OmegaPac.Conditions.str(condition)
i = str.indexOf(' ')
return str.substr(i + 1)
_fixedProfileConfig: (profile) ->
config = {}
config['mode'] = 'fixed_servers'
@ -101,8 +105,8 @@ class ChromeOptions extends OmegaTarget.Options
if config['mode'] != 'direct'
rules['bypassList'] = bypassList = []
for rule in profile.bypassList
bypassList.push(rule.pattern)
for condition in profile.bypassList
bypassList.push(@_formatBypassItem(condition))
config['rules'] = rules
return config