Project

General

Profile

« Previous | Next » 

Revision 14a7505f

Added by Dmitri Dolguikh about 6 years ago

Fixes #23433 - lease uids are now parsed correctly

View differences:

modules/dhcp_common/isc/configuration_parser.rb
end
# rubocop:enable Style/StructInheritance
class Literal < Rsec::Binary
def _parse ctx
buffer = StringIO.new
bs = false
end_of_string = false
double_quote_counter = 0
return Rsec::INVALID if ctx.peek(1) != '"'
until end_of_string
return Rsec::INVALID if ctx.eos?
c = ctx.get_byte
if bs
buffer << sprintf("\\%c", c)
bs = false
elsif c == '\\'
bs = true
elsif c == '"'
double_quote_counter += 1
end_of_string = (double_quote_counter == 2)
buffer << c
else
buffer << c
end
end
buffer.string
end
end
def literal &p
Literal.new.map p
end
NBSP = /[\ \t]+/.r
SPACE = /\s*/.r
COMMENT = /#.*/.r.^('\n') {|comment| CommentNode[comment]}
EOSTMT = ';'.r 'end of statement'
COMMA = /\s*,\s*/.r 'comma'
LITERAL = /".*?"|'.*?'/.r
HEX = /([a-fA-F0-9][a-fA-F0-9]?:)+[a-fA-F0-9][a-fA-F0-9]?/.r
MAC_ADDRESS = /([a-fA-F0-9][a-fA-F0-9]?:){5}[a-fA-F0-9][a-fA-F0-9]?/.r 'mac address'
IPV4_ADDRESS = /\d+\.\d+\.\d+\.\d+/.r 'ipv4 address'
......
def option_values
anything = /[^;,{}\s]+/.r
SPACE.join(LITERAL | anything).odd.join(COMMA).even
SPACE.join(literal | anything).odd.join(COMMA).even
end
def server_duid
Rsec::Fail.reset
keyword = word('server-duid').fail 'keyword_server_duid'
anything = /[^;,{}\s]+/.r
literal = /"([^"]|\")*"/.r
llt = seq_(word('llt') | word('LLT'), SPACE.join(anything).odd._?)
ll = seq_(word('ll') | word('LL'), SPACE.join(anything).odd._?)
en = seq_(word('en') | word('EN'), prim(:int32), LITERAL)
en = seq_(word('en') | word('EN'), prim(:int32), literal)
seq_(keyword, literal | HEX | en | llt | ll | prim(:int32), EOSTMT) {|_, duid, _| KeyValueNode[:server_duid, duid.respond_to?(:flatten) ? duid.flatten : duid]}
end
......
def lease_uid
keyword = word('uid').fail 'keyword_uid'
seq_(keyword, LITERAL, EOSTMT) {|_, value, _| KeyValueNode[:uid, value]}
seq_(keyword, literal, EOSTMT) {|_, value, _| KeyValueNode[:uid, value]}
end
def lease_hostname
keyword = word('client-hostname').fail 'keyword_client_hostname'
seq_(keyword, LITERAL | FQDN, EOSTMT) {|_, fqdn, _| KeyValueNode[:client_hostname, fqdn]}
seq_(keyword, literal | FQDN, EOSTMT) {|_, fqdn, _| KeyValueNode[:client_hostname, fqdn]}
end
def lease
......
Rsec::Fail.reset
keyword = word('group').fail 'keyword_group'
anything = /[^;,{}\s]+/.r
seq_(keyword, SPACE.join(LITERAL | anything).odd._?, LFT_BRACKET,
seq_(keyword, SPACE.join(literal | anything).odd._?, LFT_BRACKET,
SPACE.join(option | host | lazy {subnet} | lazy {group} | lazy {shared_network} | COMMENT | deleted | ignored_declaration | ignored_block).odd,
RGT_BRACKET).cached {|_, name, _, statements, _| GroupNode[name.flatten.first, statements]}
end
......
Rsec::Fail.reset
keyword = word('shared-network').fail 'keyword_shared_network'
seq_(keyword,
SPACE.join(LITERAL | FQDN).odd, LFT_BRACKET,
SPACE.join(literal | FQDN).odd, LFT_BRACKET,
SPACE.join(include_file | option | host | lazy {subnet} | lazy {group} | pool | COMMENT | deleted | ignored_declaration | ignored_block).odd,
RGT_BRACKET).cached {|_, name, _, statements, _| GroupNode[name.first, statements]}
end
......
def include_file
Rsec::Fail.reset
include_keyword = word('include').fail 'include_keyword'
seq_(include_keyword, LITERAL) do |_, filename_in_quotes|
seq_(include_keyword, literal) do |_, filename_in_quotes|
ConfigurationParser.new.parse_file(literal_to_filename(filename_in_quotes))
end
end
......
end
def parse_file(a_path)
File.open(a_path, 'r') {|f| conf.parse!(f.read, a_path)}
File.open(a_path, 'r:ASCII-8BIT') {|f| conf.parse!(f.read, a_path)}
end
# returns all_subnets, all_hosts, root_group
test/dhcp/conf_parser_test.rb
Proxy::DHCP::CommonISC::ConfigurationParser.new.lease_uid.parse!('uid "\000DELLX\000\020W\200L\310\300O022";')
assert_equal Proxy::DHCP::CommonISC::ConfigurationParser::KeyValueNode[:uid, '"\000DELLX\000\020W\200L\310\300O022"'],
Proxy::DHCP::CommonISC::ConfigurationParser.new.lease_uid.parse!('uid "\000DELLX\000\020W\200L\310\300O022" ; ')
assert_equal Proxy::DHCP::CommonISC::ConfigurationParser::KeyValueNode[:uid, '"\000\001\000\001\"L{\010RT\000A\377\305"'],
Proxy::DHCP::CommonISC::ConfigurationParser.new.lease_uid.parse!('uid "\000\001\000\001\"L{\010RT\000A\377\305" ; ')
end
def test_lease_client_name

Also available in: Unified diff