From 8bfc3cb1000bfc52fb2a1dfb3ac092a31b7998a4 Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Fri, 29 Mar 2013 21:06:10 -0400 Subject: [PATCH] CRM-12193 - Validate JSON documents ---------------------------------------- * CRM-12193: In-app fundraising for CiviCRM http://issues.civicrm.org/jira/browse/CRM-12193 --- CRM/Core/CommunityMessages.php | 25 +++++++++++++- .../CRM/Core/CommunityMessagesTest.php | 34 +++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CRM/Core/CommunityMessages.php b/CRM/Core/CommunityMessages.php index e0efd96a20..21b3dc7344 100644 --- a/CRM/Core/CommunityMessages.php +++ b/CRM/Core/CommunityMessages.php @@ -92,7 +92,7 @@ class CRM_Core_CommunityMessages { if ($document['expires'] <= CRM_Utils_Time::getTimeRaw()) { $newDocument = $this->fetchDocument($this->messagesUrl); - if ($newDocument) { + if ($newDocument && $this->validateDocument($newDocument)) { $document = $newDocument; $document['expires'] = CRM_Utils_Time::getTimeRaw() + $document['ttl']; } @@ -146,4 +146,27 @@ class CRM_Core_CommunityMessages { throw new Exception('not implemented'); } + /** + * Ensure that a document is well-formed + * + * @param array $document + * @return bool + */ + public function validateDocument($document) { + if (!isset($document['ttl']) || !is_integer($document['ttl'])) { + return FALSE; + } + if (!isset($document['retry']) || !is_integer($document['retry'])) { + return FALSE; + } + if (!isset($document['messages']) || !is_array($document['messages'])) { + return FALSE; + } + foreach ($document['messages'] as $message) { + // TODO validate $message['markup'] + } + + return TRUE; + } + } diff --git a/tests/phpunit/CRM/Core/CommunityMessagesTest.php b/tests/phpunit/CRM/Core/CommunityMessagesTest.php index f4d154fc48..778ba9b4de 100644 --- a/tests/phpunit/CRM/Core/CommunityMessagesTest.php +++ b/tests/phpunit/CRM/Core/CommunityMessagesTest.php @@ -54,6 +54,18 @@ class CRM_Core_CommunityMessagesTest extends CiviUnitTestCase { CRM_Utils_HttpClient::STATUS_OK, 'this is not json!' ), + 'invalid-ttl-document' => array( + CRM_Utils_HttpClient::STATUS_OK, + json_encode(array( + 'ttl' => 'z', // not an integer! + 'retry' => 'z', // not an integer! + 'messages' => array( + array( + 'markup' => '

Invalid document

', + ), + ), + )) + ), 'hello-world' => array( CRM_Utils_HttpClient::STATUS_OK, json_encode(array( @@ -237,6 +249,28 @@ class CRM_Core_CommunityMessagesTest extends CiviUnitTestCase { $this->assertEquals(strtotime('2013-03-01 12:10:02'), $doc2['expires']); } + public function testGetDocument_NewOK_UpdateInvalidDoc() { + // first try, good response + CRM_Utils_Time::setTime('2013-03-01 10:00:00'); + $communityMessages = new CRM_Core_CommunityMessages( + $this->cache, + $this->expectOneHttpRequest($this->webResponses['hello-world']) + ); + $doc1 = $communityMessages->getDocument(); + $this->assertEquals('

Hello world

', $doc1['messages'][0]['markup']); + $this->assertEquals(strtotime('2013-03-01 10:10:00'), $doc1['expires']); + + // second try, $doc1 has expired; bad response; keep old data + CRM_Utils_Time::setTime('2013-03-01 12:00:02'); // more than 2 hours later (DEFAULT_RETRY) + $communityMessages = new CRM_Core_CommunityMessages( + $this->cache, + $this->expectOneHttpRequest($this->webResponses['invalid-ttl-document']) + ); + $doc2 = $communityMessages->getDocument(); + $this->assertEquals('

Hello world

', $doc2['messages'][0]['markup']); + $this->assertEquals(strtotime('2013-03-01 12:10:02'), $doc2['expires']); + } + /** * Generate a mock HTTP client with the expectation that it is never called. * -- 2.25.1