diff --git a/openlp/plugins/remotes/html/openlp.js b/openlp/plugins/remotes/html/openlp.js
index 0c15d9c07..626ab51cb 100644
--- a/openlp/plugins/remotes/html/openlp.js
+++ b/openlp/plugins/remotes/html/openlp.js
@@ -72,7 +72,9 @@ window.OpenLP = {
);
},
loadController: function (event) {
- event.preventDefault();
+ if (event) {
+ event.preventDefault();
+ }
$.getJSON(
"/api/controller/live/text",
function (data, status) {
@@ -91,6 +93,7 @@ window.OpenLP = {
li.children("a").click(OpenLP.setSlide);
ul.append(li);
}
+ OpenLP.currentItem = data.results.item;
ul.listview("refresh");
}
);
@@ -208,9 +211,8 @@ window.OpenLP = {
},
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 @@ window.OpenLP = {
},
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 @@ window.OpenLP = {
);
$("#options").dialog("close");
$.mobile.changePage("#service-manager");
+ },
+ escapeString: function (string) {
+ return string.replace(/\\/g, "\\\\").replace(/"/g, "\\\"")
}
}
// Service Manager
diff --git a/openlp/plugins/remotes/lib/httpserver.py b/openlp/plugins/remotes/lib/httpserver.py
index b9df5ebd3..383c7fa03 100644
--- a/openlp/plugins/remotes/lib/httpserver.py
+++ b/openlp/plugins/remotes/lib/httpserver.py
@@ -111,15 +111,12 @@ the remotes.
{"results": {"items": [{...}, {...}]}}
"""
+import json
import logging
import os
-import urlparse
import re
-
-try:
- import json
-except ImportError:
- import simplejson as json
+import urllib
+import urlparse
from PyQt4 import QtCore, QtNetwork
from mako.template import Template
@@ -314,11 +311,14 @@ class HttpConnection(object):
"""
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 @@ class HttpConnection(object):
"""
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 @@ class HttpConnection(object):
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 @@ class HttpConnection(object):
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 @@ class HttpConnection(object):
``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 @@ class HttpConnection(object):
"""
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