Protecting against eval failing
authorEd Page <eopage@byu.net>
Tue, 19 Oct 2010 23:15:37 +0000 (18:15 -0500)
committerEd Page <eopage@byu.net>
Tue, 19 Oct 2010 23:15:37 +0000 (18:15 -0500)
src/backends/gvoice.py
src/gv_views.py

index 187c394..376f366 100755 (executable)
@@ -477,6 +477,8 @@ class GVoiceBackend(object):
                if contactsBody is None:
                        raise RuntimeError("Could not extract contact information")
                accountData = _fake_parse_json(contactsBody.group(1))
+               if accountData is None:
+                       return
                for contactId, contactDetails in accountData["contacts"].iteritems():
                        # A zero contact id is the catch all for unknown contacts
                        if contactId != "0":
@@ -488,6 +490,8 @@ class GVoiceBackend(object):
                voicemailPage = self._get_page(self._XML_VOICEMAIL_URL)
                voicemailHtml = self._grab_html(voicemailPage)
                voicemailJson = self._grab_json(voicemailPage)
+               if voicemailJson is None:
+                       return ()
                parsedVoicemail = self._parse_voicemail(voicemailHtml)
                voicemails = self._merge_conversation_sources(parsedVoicemail, voicemailJson)
                return voicemails
@@ -496,6 +500,8 @@ class GVoiceBackend(object):
                smsPage = self._get_page(self._XML_SMS_URL)
                smsHtml = self._grab_html(smsPage)
                smsJson = self._grab_json(smsPage)
+               if smsJson is None:
+                       return ()
                parsedSms = self._parse_sms(smsHtml)
                smss = self._merge_conversation_sources(parsedSms, smsJson)
                return smss
@@ -788,7 +794,11 @@ def safe_eval(s):
        _FALSE_REGEX = re.compile("false")
        s = _TRUE_REGEX.sub("True", s)
        s = _FALSE_REGEX.sub("False", s)
-       return eval(s, {}, {})
+       try:
+               results = eval(s, {}, {})
+       except SyntaxError:
+               _moduleLogger.exception("Oops")
+               return None
 
 
 def _fake_parse_json(flattened):
@@ -823,7 +833,9 @@ def validate_response(response):
        Validates that the JSON response is A-OK
        """
        try:
-               assert 'ok' in response and response['ok']
+               assert response is not None
+               assert 'ok' in response
+               assert response['ok']
        except AssertionError:
                raise RuntimeError('There was a problem with GV: %s' % response)
 
index f7c10df..78b727d 100644 (file)
@@ -218,33 +218,39 @@ def collapse_message(message, maxCharsPerLine, maxLines):
 
 
 def _get_contact_numbers(backend, contactId, number):
+       contactPhoneNumbers = []
        if contactId and contactId != '0':
-               contactPhoneNumbers = list(backend.get_contact_details(contactId))
-               uglyContactNumbers = (
-                       make_ugly(contactNumber)
-                       for (numberDescription, contactNumber) in contactPhoneNumbers
-               )
-               defaultMatches = [
-                       (
-                               number == contactNumber or
-                               number[1:] == contactNumber and number.startswith("1") or
-                               number[2:] == contactNumber and number.startswith("+1") or
-                               number == contactNumber[1:] and contactNumber.startswith("1") or
-                               number == contactNumber[2:] and contactNumber.startswith("+1")
-                       )
-                       for contactNumber in uglyContactNumbers
-               ]
                try:
-                       defaultIndex = defaultMatches.index(True)
-               except ValueError:
-                       contactPhoneNumbers.append(("Other", number))
-                       defaultIndex = len(contactPhoneNumbers)-1
-                       _moduleLogger.warn(
-                               "Could not find contact %r's number %s among %r" % (
-                                       contactId, number, contactPhoneNumbers
-                               )
+                       contactPhoneNumbers = list(backend.get_contact_details(contactId))
+               except KeyError:
+                       contactPhoneNumbers = []
+               if contactPhoneNumbers:
+                       uglyContactNumbers = (
+                               make_ugly(contactNumber)
+                               for (numberDescription, contactNumber) in contactPhoneNumbers
                        )
-       else:
+                       defaultMatches = [
+                               (
+                                       number == contactNumber or
+                                       number[1:] == contactNumber and number.startswith("1") or
+                                       number[2:] == contactNumber and number.startswith("+1") or
+                                       number == contactNumber[1:] and contactNumber.startswith("1") or
+                                       number == contactNumber[2:] and contactNumber.startswith("+1")
+                               )
+                               for contactNumber in uglyContactNumbers
+                       ]
+                       try:
+                               defaultIndex = defaultMatches.index(True)
+                       except ValueError:
+                               contactPhoneNumbers.append(("Other", number))
+                               defaultIndex = len(contactPhoneNumbers)-1
+                               _moduleLogger.warn(
+                                       "Could not find contact %r's number %s among %r" % (
+                                               contactId, number, contactPhoneNumbers
+                                       )
+                               )
+
+       if not contactPhoneNumbers:
                contactPhoneNumbers = [("Phone", number)]
                defaultIndex = -1