From 9186ab95943b7c2467a0f27f30bed9db3c589b9d Mon Sep 17 00:00:00 2001
From: VirtualTam <virtualtam@flibidi.net>
Date: Sat, 27 Jun 2015 14:57:44 +0200
Subject: LinkDB::filterDay(): check input date format

Signed-off-by: VirtualTam <virtualtam@flibidi.net>
---
 application/LinkDB.php |  5 ++++-
 application/Utils.php  | 15 +++++++++++++++
 index.php              |  8 +++++++-
 tests/LinkDBTest.php   | 23 +++++++++++++----------
 tests/UtilsTest.php    | 19 +++++++++++++++++++
 5 files changed, 58 insertions(+), 12 deletions(-)

diff --git a/application/LinkDB.php b/application/LinkDB.php
index a673b086..82763618 100644
--- a/application/LinkDB.php
+++ b/application/LinkDB.php
@@ -375,7 +375,10 @@ You use the community supported version of the original Shaarli project, by Seba
      */
     public function filterDay($day)
     {
-        // TODO: check input format
+        if (! checkDateFormat('Ymd', $day)) {
+            throw new Exception('Invalid date format');
+        }
+
         $filtered = array();
         foreach ($this->links as $l) {
             if (startsWith($l['linkdate'], $day)) {
diff --git a/application/Utils.php b/application/Utils.php
index 82220bfc..a1e97b35 100644
--- a/application/Utils.php
+++ b/application/Utils.php
@@ -69,4 +69,19 @@ function sanitizeLink(&$link)
     $link['description'] = escape($link['description']);
     $link['tags'] = escape($link['tags']);
 }
+
+/**
+ * Checks if a string represents a valid date
+ *
+ * @param string        a string-formatted date
+ * @param format        the expected DateTime format of the string
+ * @return              whether the string is a valid date
+ * @see                 http://php.net/manual/en/class.datetime.php
+ * @see                 http://php.net/manual/en/datetime.createfromformat.php
+ */
+function checkDateFormat($format, $string)
+{
+    $date = DateTime::createFromFormat($format, $string);
+    return $date && $date->format($string) == $string;
+}
 ?>
diff --git a/index.php b/index.php
index 561f946e..5771dd88 100644
--- a/index.php
+++ b/index.php
@@ -957,7 +957,13 @@ function showDaily()
         if ($i<count($days)-1) $nextday=$days[$i+1];
     }
 
-    $linksToDisplay=$LINKSDB->filterDay($day);
+    try {
+        $linksToDisplay = $LINKSDB->filterDay($day);
+    } catch (Exception $exc) {
+        error_log($exc);
+        $linksToDisplay = [];
+    }
+
     // We pre-format some fields for proper output.
     foreach($linksToDisplay as $key=>$link)
     {
diff --git a/tests/LinkDBTest.php b/tests/LinkDBTest.php
index ee8dbee3..8b0bd23b 100644
--- a/tests/LinkDBTest.php
+++ b/tests/LinkDBTest.php
@@ -396,19 +396,22 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
 
     /**
      * Use an invalid date format
+     * @expectedException              Exception
+     * @expectedExceptionMessageRegExp /Invalid date format/
      */
-    public function testFilterInvalidDay()
+    public function testFilterInvalidDayWithChars()
     {
-        $this->assertEquals(
-            0,
-            sizeof(self::$privateLinkDB->filterDay('Rainy day, dream away'))
-        );
+        self::$privateLinkDB->filterDay('Rainy day, dream away');
+    }
 
-        // TODO: check input format
-        $this->assertEquals(
-            6,
-            sizeof(self::$privateLinkDB->filterDay('20'))
-        );
+    /**
+     * Use an invalid date format
+     * @expectedException              Exception
+     * @expectedExceptionMessageRegExp /Invalid date format/
+     */
+    public function testFilterInvalidDayDigits()
+    {
+        self::$privateLinkDB->filterDay('20');
     }
 
     /**
diff --git a/tests/UtilsTest.php b/tests/UtilsTest.php
index bbba99f2..90392dfb 100644
--- a/tests/UtilsTest.php
+++ b/tests/UtilsTest.php
@@ -74,5 +74,24 @@ class UtilsTest extends PHPUnit_Framework_TestCase
         $this->assertTrue(endsWith('å!ùµ', 'ùµ', false));
         $this->assertTrue(endsWith('µ$åù', 'åù', true));
     }
+
+    /**
+     * Check valid date strings, according to a DateTime format
+     */
+    public function testCheckValidDateFormat()
+    {
+        $this->assertTrue(checkDateFormat('Ymd', '20150627'));
+        $this->assertTrue(checkDateFormat('Y-m-d', '2015-06-27'));
+    }
+
+    /**
+     * Check erroneous date strings, according to a DateTime format
+     */
+    public function testCheckInvalidDateFormat()
+    {
+        $this->assertFalse(checkDateFormat('Ymd', '2015'));
+        $this->assertFalse(checkDateFormat('Y-m-d', '2015-06'));
+        $this->assertFalse(checkDateFormat('Ymd', 'DeLorean'));
+    }
 }
 ?>
-- 
cgit v1.2.3