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-device.js' => 'bb1dd507', | ||||||
|     'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '484a6e22', |     'rsrc/js/core/behavior-drag-and-drop-textarea.js' => '484a6e22', | ||||||
|     'rsrc/js/core/behavior-error-log.js' => '6882e80a', |     '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-file-tree.js' => '88236f00', | ||||||
|     'rsrc/js/core/behavior-form.js' => '5c54cbf3', |     'rsrc/js/core/behavior-form.js' => '5c54cbf3', | ||||||
|     'rsrc/js/core/behavior-gesture.js' => '3ab51e2c', |     'rsrc/js/core/behavior-gesture.js' => '3ab51e2c', | ||||||
| @@ -633,7 +633,7 @@ return array( | |||||||
|     'javelin-behavior-editengine-reorder-fields' => 'b59e1e96', |     'javelin-behavior-editengine-reorder-fields' => 'b59e1e96', | ||||||
|     'javelin-behavior-error-log' => '6882e80a', |     'javelin-behavior-error-log' => '6882e80a', | ||||||
|     'javelin-behavior-event-all-day' => 'b41537c9', |     '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-global-drag-and-drop' => '960f6a39', | ||||||
|     'javelin-behavior-herald-rule-editor' => '7ebaeed3', |     'javelin-behavior-herald-rule-editor' => '7ebaeed3', | ||||||
|     'javelin-behavior-high-security-warning' => 'a464fe03', |     'javelin-behavior-high-security-warning' => 'a464fe03', | ||||||
| @@ -1716,13 +1716,6 @@ return array( | |||||||
|       'javelin-uri', |       'javelin-uri', | ||||||
|       'phabricator-keyboard-shortcut', |       'phabricator-keyboard-shortcut', | ||||||
|     ), |     ), | ||||||
|     'a9210d03' => array( |  | ||||||
|       'javelin-behavior', |  | ||||||
|       'javelin-util', |  | ||||||
|       'javelin-dom', |  | ||||||
|       'javelin-stratcom', |  | ||||||
|       'javelin-vector', |  | ||||||
|     ), |  | ||||||
|     'a9f88de2' => array( |     'a9f88de2' => array( | ||||||
|       'javelin-behavior', |       'javelin-behavior', | ||||||
|       'javelin-dom', |       'javelin-dom', | ||||||
| @@ -2105,6 +2098,13 @@ return array( | |||||||
|       'javelin-dom', |       'javelin-dom', | ||||||
|       'phabricator-draggable-list', |       'phabricator-draggable-list', | ||||||
|     ), |     ), | ||||||
|  |     'ecf4e799' => array( | ||||||
|  |       'javelin-behavior', | ||||||
|  |       'javelin-util', | ||||||
|  |       'javelin-dom', | ||||||
|  |       'javelin-stratcom', | ||||||
|  |       'javelin-vector', | ||||||
|  |     ), | ||||||
|     'edf8a145' => array( |     'edf8a145' => array( | ||||||
|       'javelin-behavior', |       'javelin-behavior', | ||||||
|       'javelin-uri', |       'javelin-uri', | ||||||
|   | |||||||
| @@ -287,27 +287,39 @@ JX.behavior('fancy-datepicker', function(config, statics) { | |||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   function getValidDate() { |   function getValidDate() { | ||||||
|     var written_date = new Date(value_y, value_m-1, value_d); |     var year_int = parseInt(value_y, 10); | ||||||
|  |  | ||||||
|     if (isNaN(written_date.getTime())) { |     if (isNaN(year_int) || year_int < 0) { | ||||||
|       return new Date(); |       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 |     // If the user enters "11" for the year, interpret it as "2011" (which | ||||||
|       var adjust = 1; |     // is almost certainly what they mean) not "1911" (which is the default | ||||||
|       while (written_date.getMonth() !== value_m-1) { |     // behavior of Javascript). | ||||||
|         written_date = new Date(value_y, value_m-1, value_d-adjust); |     if (year_int < 70) { | ||||||
|         adjust++; |       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(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return written_date; |     return written_date; | ||||||
|   } |   } | ||||||
|   } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   // Render the day-of-week and calendar views. |   // Render the day-of-week and calendar views. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 epriestley
					epriestley