britram / python-ipfix

IPFIX implementation for Python 3.x
GNU Lesser General Public License v3.0
40 stars 20 forks source link

Better support for fixed length strings in SVG message drawing code. #21

Open nickbroon opened 7 years ago

nickbroon commented 7 years ago

If the basic example of a string is changed to a fixed length of 13 (which exactly matches the string length passed to the data record) it works just fine:

import ipfix
import ipfix.vis
from IPython.display import SVG

def draw_message(msg, length=256):
    return SVG(ipfix.vis.MessageBufferRenderer(msg, raster=4).render(length=length))

def draw_template(tmpl):
    ofd = ipfix.vis.OctetFieldDrawing(raster=4)
    ipfix.vis.draw_template(ofd, tmpl)
    return SVG(ofd.render((90,30)))

ipfix.ie.use_iana_default()
vtmpl = ipfix.template.for_specs(262, "wlanSSID[13]")
draw_template(vtmpl)

msg = ipfix.message.MessageBuffer()
msg.begin_export(8304)
msg.add_template(vtmpl)
msg.export_new_set(262)
msg.export_namedict({'wlanSSID':                 'ietf-a-v6only'})
draw_message(msg)

If it's changed to 12 it also works just fine, truncating the string to fit.

If it's changed to 14, or any other larger value, it crashes. I'm guessing that it needs to correctly zero pad the string.

---------------------------------------------------------------------------
ExpatError                                Traceback (most recent call last)
<ipython-input-3-9dedd178bbfb> in <module>()
      5 msg.export_namedict({'wlanSSID':                 'ietf-a-v6only',
      6                      'protocolIdentifier':       6})
----> 7 draw_message(msg)

<ipython-input-1-ffa57e3f6760> in draw_message(msg, length)
      5 
      6 def draw_message(msg, length=256):
----> 7     return SVG(ipfix.vis.MessageBufferRenderer(msg, raster=4).render(length=length))
      8 
      9 def draw_template(tmpl):

/usr/lib/python3/dist-packages/IPython/core/display.py in __init__(self, data, url, filename)
    388                 data = None
    389 
--> 390         self.data = data
    391         self.url = url
    392         self.filename = None if filename is None else unicode_type(filename)

/usr/lib/python3/dist-packages/IPython/core/display.py in data(self, svg)
    496         from xml.dom import minidom
    497         svg = cast_bytes_py2(svg)
--> 498         x = minidom.parseString(svg)
    499         # get svg tag (should be 1)
    500         found_svg = x.getElementsByTagName('svg')

/usr/lib/python3.5/xml/dom/minidom.py in parseString(string, parser)
   1966     if parser is None:
   1967         from xml.dom import expatbuilder
-> 1968         return expatbuilder.parseString(string)
   1969     else:
   1970         from xml.dom import pulldom

/usr/lib/python3.5/xml/dom/expatbuilder.py in parseString(string, namespaces)
    923     else:
    924         builder = ExpatBuilder()
--> 925     return builder.parseString(string)
    926 
    927 

/usr/lib/python3.5/xml/dom/expatbuilder.py in parseString(self, string)
    221         parser = self.getParser()
    222         try:
--> 223             parser.Parse(string, True)
    224             self._setup_subset(string)
    225         except ParseEscape:

ExpatError: not well-formed (invalid token): line 1, column 4720
britram commented 6 years ago

Argh. Yeah, this code was designed as a hack for a tutorial I did, pretty much the night before. I really don't have the cycles to swap this back in at the moment, but pull requests will be enthusiastically accepted here. :)

britram commented 6 years ago

Note that the SVG drawing code has been moved into its own package visipfix, which will be uploaded to pypi shortly...