Class: Rex::Parser::GraphML::Document

Inherits:
Nokogiri::XML::SAX::Document
  • Object
show all
Defined in:
lib/rex/parser/graphml.rb

Overview

The top-level document parser.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDocument

Returns a new instance of Document.



438
439
440
441
442
443
444
# File 'lib/rex/parser/graphml.rb', line 438

def initialize
  @stack = []
  @nodes = {}
  @meta_attributes = {}
  @graphml = nil
  super
end

Instance Attribute Details

#graphmlObject

Returns the value of attribute graphml.



565
566
567
# File 'lib/rex/parser/graphml.rb', line 565

def graphml
  @graphml
end

Instance Method Details

#characters(string) ⇒ Object



503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
# File 'lib/rex/parser/graphml.rb', line 503

def characters(string)
  element = @stack[-1]
  case element
  when Element::Data
    parent = @stack[-2]
    meta_attribute = @meta_attributes[element.key]
    unless meta_attribute.valid_for? parent
      raise Error::ParserError, "The #{meta_attribute.name} attribute is invalid for #{parent.class::ELEMENT_NAME} elements"
    end

    if meta_attribute.type == :string && !parent.attributes[meta_attribute.name].nil?
      # this may be run multiple times if there is an XML escape sequence in the string to concat the parts together
      parent.attributes[meta_attribute.name] << meta_attribute.convert(string)
    else
      parent.attributes[meta_attribute.name] = meta_attribute.convert(string)
    end

  when Element::Default
    @stack[-1] = Element::Default.new(value: string)

  end
end

#end_element(name) ⇒ Object



526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
# File 'lib/rex/parser/graphml.rb', line 526

def end_element(name)
  element = @stack.pop

  populate_element_default_attributes(element) if element.is_a? AttributeContainer

  case name
  when 'default'
    key = @stack[-1]
    key.default = element

  when 'edge'
    graph = @stack[-1]
    graph.edges << element

  when 'graph'
    element.edges.each do |edge|
      source_node = element.nodes[edge.source]
      raise Error::InvalidAttributeError.new('edge', 'source', details: "undefined source: '#{edge.source}'", missing: false) if source_node.nil?

      target_node = element.nodes[edge.target]
      raise Error::InvalidAttributeError.new('edge', 'target', details: "undefined target: '#{edge.target}'", missing: false) if target_node.nil?

      source_node.edges << edge
      target_node.edges << edge
    end

  when 'key'
    meta_attribute = MetaAttribute.from_key(element)
    @meta_attributes[meta_attribute.id] = meta_attribute

  when 'node'
    graph = @stack[-1]
    graph.nodes[element.id] = element

  end
end

#start_element(name, attrs = []) ⇒ Object



446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
# File 'lib/rex/parser/graphml.rb', line 446

def start_element(name, attrs = [])
  attrs = attrs.to_h

  case name
  when 'data'
    raise Error::ParserError, 'The \'data\' element must be a direct child of an attribute container' unless @stack[-1].is_a? AttributeContainer

    element = Element::Data.from_xml_attributes(attrs)

  when 'default'
    raise Error::ParserError, 'The \'default\' element must be a direct child of a \'key\' element' unless @stack[-1].is_a? Element::Key

    element = Element::Default.from_xml_attributes(attrs)

  when 'edge'
    raise Error::ParserError, 'The \'edge\' element must be a direct child of a \'graph\' element' unless @stack[-1].is_a? Element::Graph

    element = Element::Edge.from_xml_attributes(attrs, @stack[-1].edgedefault)
    @graphml.edges << element

  when 'graph'
    element = Element::Graph.from_xml_attributes(attrs)
    @stack[-1].subgraph = element if @stack[-1].is_a? Element::Node
    @graphml.graphs << element

  when 'graphml'
    element = Element::GraphML.new
    raise Error::ParserError, 'The \'graphml\' element must be a top-level element' unless @stack.empty?

    @graphml = element

  when 'key'
    raise Error::ParserError, 'The \'key\' element must be a direct child of a \'graphml\' element' unless @stack[-1].is_a? Element::GraphML

    element = Element::Key.from_xml_attributes(attrs)
    raise Error::InvalidAttributeError.new('key', 'id', details: 'duplicate key id') if @meta_attributes.key? element.id
    if @meta_attributes.values.any? { |attr| attr.name == element.attr_name }
      raise Error::InvalidAttributeError.new('key', 'attr.name', details: 'duplicate key attr.name')
    end

  when 'node'
    raise Error::ParserError, 'The \'node\' element must be a direct child of a \'graph\' element' unless @stack[-1].is_a? Element::Graph

    element = Element::Node.from_xml_attributes(attrs)
    raise Error::InvalidAttributeError.new('node', 'id', details: 'duplicate node id') if @nodes.key? element.id

    @nodes[element.id] = element
    @graphml.nodes[element.id] = element

  else
    raise Error::ParserError, 'Unknown element: ' + name

  end

  @stack.push element
end