Browse Source

Fix cookie expiry time calculation on 32bit systems.

strtotime() misbehaves on 32bit systems when the resulting timestamp
would overflow an integer. Use a DateTime to workaround this issue.

Fixes #3868
mark_story 12 years ago
parent
commit
3aa189eb3a

+ 4 - 4
lib/Cake/Controller/Component/CookieComponent.php

@@ -387,20 +387,20 @@ class CookieComponent extends Component {
  * @return integer Unix timestamp
  */
 	protected function _expire($expires = null) {
-		$now = time();
 		if (is_null($expires)) {
 			return $this->_expires;
 		}
 		$this->_reset = $this->_expires;
-
 		if (!$expires) {
 			return $this->_expires = 0;
 		}
+		$now = new DateTime();
 
 		if (is_int($expires) || is_numeric($expires)) {
-			return $this->_expires = $now + intval($expires);
+			return $this->_expires = $now->format('U') + intval($expires);
 		}
-		return $this->_expires = strtotime($expires, $now);
+		$now->modify($expires);
+		return $this->_expires = $now->format('U');
 	}
 
 /**

+ 25 - 0
lib/Cake/Test/Case/Controller/Component/CookieComponentTest.php

@@ -202,6 +202,31 @@ class CookieComponentTest extends CakeTestCase {
 	}
 
 /**
+ * test write with distant future cookies
+ *
+ * @return void
+ */
+	public function testWriteFarFuture() {
+		$this->Cookie->write('Testing', 'value', false, '+90 years');
+		$future = new DateTime('now');
+		$future->modify('+90 years');
+
+		$expected = array(
+			'name' => $this->Cookie->name . '[Testing]',
+			'value' => 'value',
+			'path' => '/',
+			'domain' => '',
+			'secure' => false,
+			'httpOnly' => false);
+		$result = $this->Controller->response->cookie($this->Cookie->name . '[Testing]');
+
+		$this->assertEquals($future->format('U'), $result['expire'], '', 3);
+		unset($result['expire']);
+
+		$this->assertEquals($expected, $result);
+	}
+
+/**
  * test write with httpOnly cookies
  *
  * @return void