kbandla / dpkt

fast, simple packet creation / parsing, with definitions for the basic TCP/IP protocols
Other
1.09k stars 271 forks source link

dpkt.http.py L125: AttributeError: 'NoneType' object has no attribute 'decode' #421

Closed puittenbroek closed 5 years ago

puittenbroek commented 6 years ago

https://github.com/kbandla/dpkt/blob/master/dpkt/http.py#L125 TL;DR; self.body can be None, where __str__ does not account for this possibility.

Code that breaks:

sip = methodstatus = None
body = body.decode('utf-8', 'replace').encode('utf-8')
try:
    sip = dpkt.sip.Request(body)
    requestresponse = 'request'
    methodstatus = sip.method
except (KeyError, dpkt.dpkt.UnpackError, ValueError):
    try:
        sip = dpkt.sip.Response(body)
        requestresponse = 'response'
        sip.method = sip.headers['cseq'].partition(' ')[2]
        methodstatus = sip.status + ' (' + sip.reason + ')'
    except (KeyError, dpkt.dpkt.UnpackError, ValueError):
        # Neither a valid sip request or response, skip the rest.
        continue

if sip and sip.headers.get('call-id') not in pcaps['callids']:
    pcaps['callids'].append(sip.headers.get('call-id'))

This raises an AttributeError:

  File "/home/uittenbroek/projects/xx/xx/base/misc/debug/utils.py", line 79, in parsecall
    if sip and sip.headers.get('call-id') not in pcaps['callids']:
  File "/home/uittenbroek/.virtualenvs/xx/local/lib/python2.7/site-packages/dpkt/http.py", line 122, in __len__
    return len(str(self))
  File "/home/uittenbroek/.virtualenvs/xx/local/lib/python2.7/site-packages/dpkt/http.py", line 239, in __str__
    self.reason) + Message.__str__(self)
  File "/home/uittenbroek/.virtualenvs/xx/local/lib/python2.7/site-packages/dpkt/http.py", line 127, in __str__
    return '%s\r\n%s' % (self.pack_hdr(), self.body.decode("utf8", "ignore"))
AttributeError: 'NoneType' object has no attribute 'decode'

Due to the Response.unpack looking at the self.status, for this specific item this status '100'. Causing is_body_allowed to be False, resulting in body not being set.

But the __str__ function always expects body to be a string type with a decode function.