← Back to team overview

openlp-core team mailing list archive

[Merge] lp:~mahfiaz/openlp/bug-908226 into lp:openlp

 

mahfiaz has proposed merging lp:~mahfiaz/openlp/bug-908226 into lp:openlp.

Requested reviews:
  mahfiaz (mahfiaz)
  Tim Bentley (trb143)
  Jonathan Corwin (j-corwin)
  Raoul Snyman (raoul-snyman)
Related bugs:
  Bug #908226 in OpenLP: "Traceback when sending # or ; character from remote search or alert field"
  https://bugs.launchpad.net/openlp/+bug/908226

For more details, see:
https://code.launchpad.net/~mahfiaz/openlp/bug-908226/+merge/98090

Fixes for web remote: traceback when sending ", # or ; from search or alert field.
404 not found results when searching or sending alerts.
Double loading of song, when sending live from search result.
JS error event not found when sending element live from search result.
Tracebacks on non-debuggable JSON code or JSON data not containing required item or url not containing required data= element.
Leftover from python 2.5 era.
-- 
https://code.launchpad.net/~mahfiaz/openlp/bug-908226/+merge/98090
Your team OpenLP Core is subscribed to branch lp:openlp.
=== modified file 'openlp/plugins/remotes/html/openlp.js'
--- openlp/plugins/remotes/html/openlp.js	2012-03-17 10:40:06 +0000
+++ openlp/plugins/remotes/html/openlp.js	2012-03-18 09:33:24 +0000
@@ -72,7 +72,9 @@
     );
   },
   loadController: function (event) {
-    event.preventDefault();
+    if (event) {
+      event.preventDefault();
+    }
     $.getJSON(
       "/api/controller/live/text",
       function (data, status) {
@@ -91,6 +93,7 @@
           li.children("a").click(OpenLP.setSlide);
           ul.append(li);
         }
+        OpenLP.currentItem = data.results.item;
         ul.listview("refresh");
       }
     );
@@ -208,9 +211,8 @@
   },
   showAlert: function (event) {
     event.preventDefault();
-    var text = "{\"request\": {\"text\": \"" +
-        $("#alert-text").val().replace(/\\/g, "\\\\").replace(/"/g, "\\\"") +
-        "\"}}";
+    var alert = OpenLP.escapeString($("#alert-text").val())
+    var text = "{\"request\": {\"text\": \"" + alert + "\"}}";
     $.getJSON(
       "/api/alert",
       {"data": text},
@@ -221,9 +223,8 @@
   },
   search: function (event) {
     event.preventDefault();
-    var text = "{\"request\": {\"text\": \"" +
-        $("#search-text").val().replace(/\\/g, "\\\\").replace(/"/g, "\\\"") +
-        "\"}}";
+    var query = OpenLP.escapeString($("#search-text").val())
+    var text = "{\"request\": {\"text\": \"" + query + "\"}}";
     $.getJSON(
       "/api/" + $("#search-plugin").val() + "/search",
       {"data": text},
@@ -280,6 +281,9 @@
     );
     $("#options").dialog("close");
     $.mobile.changePage("#service-manager");
+  },
+  escapeString: function (string) { 
+    return string.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")
   }
 }
 // Service Manager

=== modified file 'openlp/plugins/remotes/lib/httpserver.py'
--- openlp/plugins/remotes/lib/httpserver.py	2012-03-17 10:23:52 +0000
+++ openlp/plugins/remotes/lib/httpserver.py	2012-03-18 09:33:24 +0000
@@ -111,15 +111,12 @@
             {"results": {"items": [{...}, {...}]}}
 """
 
+import json
 import logging
 import os
+import re
+import urllib
 import urlparse
-import re
-
-try:
-    import json
-except ImportError:
-    import simplejson as json
 
 from PyQt4 import QtCore, QtNetwork
 from mako.template import Template
@@ -314,11 +311,14 @@
         """
         log.debug(u'ready to read socket')
         if self.socket.canReadLine():
-            data = self.socket.readLine()
-            data = QtCore.QByteArray.fromPercentEncoding(data)
-            data = unicode(data, 'utf8')
-            log.debug(u'received: ' + data)
-            words = data.split(u' ')
+            data = str(self.socket.readLine())
+            try:
+                log.debug(u'received: ' + data)
+            except UnicodeDecodeError:
+                # Malicious request containing non-ASCII characters.
+                self.close()
+                return
+            words = data.split(' ')
             response = None
             if words[0] == u'GET':
                 url = urlparse.urlparse(words[1])
@@ -426,11 +426,19 @@
         """
         Send an alert.
         """
-        text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
         plugin = self.parent.plugin.pluginManager.get_plugin_by_name("alerts")
         if plugin.status == PluginStatus.Active:
+            try:
+                text = json.loads(
+                    self.url_params[u'data'][0])[u'request'][u'text']
+            except KeyError, ValueError:
+                return HttpResponse(code=u'400 Bad Request')
+            text = urllib.unquote(text)
             Receiver.send_message(u'alerts_text', [text])
-        return HttpResponse(json.dumps({u'results': {u'success': True}}),
+            success = True
+        else:
+            success = False
+        return HttpResponse(json.dumps({u'results': {u'success': success}}),
             {u'Content-Type': u'application/json'})
 
     def controller(self, type, action):
@@ -465,9 +473,14 @@
                     item[u'selected'] = (self.parent.current_slide == index)
                     data.append(item)
             json_data = {u'results': {u'slides': data}}
+            if current_item:
+                json_data[u'results'][u'item'] = self.parent.current_item._uuid
         else:
             if self.url_params and self.url_params.get(u'data'):
-                data = json.loads(self.url_params[u'data'][0])
+                try:
+                    data = json.loads(self.url_params[u'data'][0])
+                except KeyError, ValueError:
+                    return HttpResponse(code=u'400 Bad Request')
                 log.info(data)
                 # This slot expects an int within a list.
                 id = data[u'request'][u'id']
@@ -487,7 +500,10 @@
         else:
             event += u'_item'
         if self.url_params and self.url_params.get(u'data'):
-            data = json.loads(self.url_params[u'data'][0])
+            try:
+                data = json.loads(self.url_params[u'data'][0])
+            except KeyError, ValueError:
+                return HttpResponse(code=u'400 Bad Request')
             Receiver.send_message(event, data[u'request'][u'id'])
         else:
             Receiver.send_message(event)
@@ -520,7 +536,11 @@
         ``type``
             The plugin name to search in.
         """
-        text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
+        try:
+            text = json.loads(self.url_params[u'data'][0])[u'request'][u'text']
+        except KeyError, ValueError:
+            return HttpResponse(code=u'400 Bad Request')
+        text = urllib.unquote(text)
         plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
         if plugin.status == PluginStatus.Active and \
             plugin.mediaItem and plugin.mediaItem.hasSearch:
@@ -535,20 +555,28 @@
         """
         Go live on an item of type ``type``.
         """
-        id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
+        try:
+            id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
+        except KeyError, ValueError:
+            return HttpResponse(code=u'400 Bad Request')
         plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
         if plugin.status == PluginStatus.Active and plugin.mediaItem:
             plugin.mediaItem.goLive(id, remote=True)
+        return HttpResponse(code=u'200 OK')
 
     def add_to_service(self, type):
         """
         Add item of type ``type`` to the end of the service.
         """
-        id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
+        try:
+            id = json.loads(self.url_params[u'data'][0])[u'request'][u'id']
+        except KeyError, ValueError:
+            return HttpResponse(code=u'400 Bad Request')
         plugin = self.parent.plugin.pluginManager.get_plugin_by_name(type)
         if plugin.status == PluginStatus.Active and plugin.mediaItem:
             item_id = plugin.mediaItem.createItemFromId(id)
             plugin.mediaItem.addToService(item_id, remote=True)
+        return HttpResponse(code=u'200 OK')
 
     def send_response(self, response):
         http = u'HTTP/1.1 %s\r\n' % response.code


Follow ups