Fix a hang in fancy date picker for Ye Olde Time Years
Summary:
Fixes T12960. When the user enters a date like "1917", we currently loop ~20 million times.
Instead:
  - Be a little more careful about parsing.
  - Javascript's default behavior of interpreting "2001-02-31" as "2001-03-03" ("February 31" -> "March 3") already seems reasonable, so just let it do that.
Test Plan:
Verified these behaviors:
  - `2017-08-08` - Valid, recent.
  - `17-08-08` - Valid, recent.
  - `1917-08-08` - Valid, a century ago, no loop.
  - `2017-02-31` - "February 31", interpreted as "March 3" by Javascsript, seems reasonable.
  - `Quack` - Default, current time.
  - `0/0/0`, `0/99/0` - Default, current time.
Reviewers: avivey, chad
Reviewed By: chad
Maniphest Tasks: T12960
Differential Revision: https://secure.phabricator.com/D18383
			
			
This commit is contained in:
		| @@ -484,7 +484,7 @@ return array( | ||||
|     'rsrc/js/core/behavior-device.js' => 'bb1dd507', | ||||
|     'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '484a6e22', | ||||
|     'rsrc/js/core/behavior-error-log.js' => '6882e80a', | ||||
|     'rsrc/js/core/behavior-fancy-datepicker.js' => 'a9210d03', | ||||
|     'rsrc/js/core/behavior-fancy-datepicker.js' => 'ecf4e799', | ||||
|     'rsrc/js/core/behavior-file-tree.js' => '88236f00', | ||||
|     'rsrc/js/core/behavior-form.js' => '5c54cbf3', | ||||
|     'rsrc/js/core/behavior-gesture.js' => '3ab51e2c', | ||||
| @@ -633,7 +633,7 @@ return array( | ||||
|     'javelin-behavior-editengine-reorder-fields' => 'b59e1e96', | ||||
|     'javelin-behavior-error-log' => '6882e80a', | ||||
|     'javelin-behavior-event-all-day' => 'b41537c9', | ||||
|     'javelin-behavior-fancy-datepicker' => 'a9210d03', | ||||
|     'javelin-behavior-fancy-datepicker' => 'ecf4e799', | ||||
|     'javelin-behavior-global-drag-and-drop' => '960f6a39', | ||||
|     'javelin-behavior-herald-rule-editor' => '7ebaeed3', | ||||
|     'javelin-behavior-high-security-warning' => 'a464fe03', | ||||
| @@ -1716,13 +1716,6 @@ return array( | ||||
|       'javelin-uri', | ||||
|       'phabricator-keyboard-shortcut', | ||||
|     ), | ||||
|     'a9210d03' => array( | ||||
|       'javelin-behavior', | ||||
|       'javelin-util', | ||||
|       'javelin-dom', | ||||
|       'javelin-stratcom', | ||||
|       'javelin-vector', | ||||
|     ), | ||||
|     'a9f88de2' => array( | ||||
|       'javelin-behavior', | ||||
|       'javelin-dom', | ||||
| @@ -2105,6 +2098,13 @@ return array( | ||||
|       'javelin-dom', | ||||
|       'phabricator-draggable-list', | ||||
|     ), | ||||
|     'ecf4e799' => array( | ||||
|       'javelin-behavior', | ||||
|       'javelin-util', | ||||
|       'javelin-dom', | ||||
|       'javelin-stratcom', | ||||
|       'javelin-vector', | ||||
|     ), | ||||
|     'edf8a145' => array( | ||||
|       'javelin-behavior', | ||||
|       'javelin-uri', | ||||
|   | ||||
| @@ -287,26 +287,38 @@ JX.behavior('fancy-datepicker', function(config, statics) { | ||||
|   }; | ||||
|  | ||||
|   function getValidDate() { | ||||
|     var written_date = new Date(value_y, value_m-1, value_d); | ||||
|     var year_int = parseInt(value_y, 10); | ||||
|  | ||||
|     if (isNaN(year_int) || year_int < 0) { | ||||
|       return new Date(); | ||||
|     } | ||||
|  | ||||
|     // If the user enters "11" for the year, interpret it as "2011" (which | ||||
|     // is almost certainly what they mean) not "1911" (which is the default | ||||
|     // behavior of Javascript). | ||||
|     if (year_int < 70) { | ||||
|       year_int += 2000; | ||||
|     } | ||||
|  | ||||
|     var month_int = parseInt(value_m, 10); | ||||
|     if (isNaN(month_int) || month_int < 1 || month_int > 12) { | ||||
|       return new Date(); | ||||
|     } | ||||
|  | ||||
|     // In Javascript, January is "0", not "1", so adjust the value down. | ||||
|     month_int = month_int - 1; | ||||
|  | ||||
|     var day_int = parseInt(value_d, 10); | ||||
|     if (isNaN(day_int) || day_int < 1 || day_int > 31) { | ||||
|       return new Date(); | ||||
|     } | ||||
|  | ||||
|     var written_date = new Date(year_int, month_int, day_int); | ||||
|     if (isNaN(written_date.getTime())) { | ||||
|       return new Date(); | ||||
|     } else { | ||||
|       //year 01 should be 2001, not 1901 | ||||
|       if (written_date.getYear() < 70) { | ||||
|         value_y += 2000; | ||||
|         written_date = new Date(value_y, value_m-1, value_d); | ||||
|       } | ||||
|  | ||||
|       // adjust for a date like February 31 | ||||
|       var adjust = 1; | ||||
|       while (written_date.getMonth() !== value_m-1) { | ||||
|         written_date = new Date(value_y, value_m-1, value_d-adjust); | ||||
|         adjust++; | ||||
|       } | ||||
|  | ||||
|       return written_date; | ||||
|     } | ||||
|  | ||||
|     return written_date; | ||||
|   } | ||||
|  | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley