Repository: moment/luxon
Pull request #1026 (2021-09-09 01:29:52)

Protect IANAZone.isValidZone from undefined
This addresses #973 (IANAZone.isValidZone(undefined) returns true).

`Intl.DateTimeFormat("en-US", { timeZone: zone }).format()` will succeed if `zone` is `undefined`.  `null`, and other non-`string` values for timeZone fail.

This adds a check to make sure `zone` is not undefined, as well as a few additional test cases for non-string values.


Patch:
diff --git a/docs/formatting.md b/docs/formatting.md
index d5b9aec1..3e05c81f 100644
--- a/docs/formatting.md
+++ b/docs/formatting.md
@@ -85,28 +85,29 @@ dt.toLocaleString(newFormat); //=>  'Thursday, 4/20/2017'
 
 Here's the full set of provided presets using the October 14, 1983 at `13:30:23` as an example.
 
-| Name                        | Description                                                        | Example in en_US                                           | Example in fr                                            |
-| --------------------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- | -------------------------------------------------------- |
-| DATE_SHORT                  | short date                                                         | 10/14/1983                                                 | 14/10/1983                                               |
-| DATE_MED                    | abbreviated date                                                   | Oct 14, 1983                                               | 14 oct. 1983                                             |
-| DATE_FULL                   | full date                                                          | October 14, 1983                                           | 14 octobre 1983                                          |
-| DATE_HUGE                   | full date with weekday                                             | Tuesday, October 14, 1983                                  | vendredi 14 octobre 1983                                 |
-| TIME_SIMPLE                 | time                                                               | 1:30 PM                                                    | 13:30                                                    |
-| TIME_WITH_SECONDS           | time with seconds                                                  | 1:30:23 PM                                                 | 13:30:23                                                 |
-| TIME_WITH_SHORT_OFFSET      | time with seconds and abbreviated named offset                     | 1:30:23 PM EDT                                             | 13:30:23 UTC−4                                           |
-| TIME_WITH_LONG_OFFSET       | time with seconds and full named offset                            | 1:30:23 PM Eastern Daylight Time                           | 13:30:23 heure d’été de l’Est                            |
-| TIME_24_SIMPLE              | 24-hour time                                                       | 13:30                                                      | 13:30                                                    |
-| TIME_24_WITH_SECONDS        | 24-hour time with seconds                                          | 13:30:23                                                   | 13:30:23                                                 |
-| TIME_24_WITH_SHORT_OFFSET   | 24-hour time with seconds and abbreviated named offset             | 13:30:23 EDT                                               | 13:30:23 UTC−4                                           |
-| TIME_24_WITH_LONG_OFFSET    | 24-hour time with seconds and full named offset                    | 13:30:23 Eastern Daylight Time                             | 13:30:23 heure d’été de l’Est                            |
-| DATETIME_SHORT              | short date & time                                                  | 10/14/1983, 1:30 PM                                        | 14/10/1983 à 13:30                                       |
-| DATETIME_MED                | abbreviated date & time                                            | Oct 14, 1983, 1:30 PM                                      | 14 oct. 1983 à 13:30                                     |
-| DATETIME_FULL               | full date and time with abbreviated named offset                   | October 14, 1983, 1:30 PM EDT                              | 14 octobre 1983 à 13:30 UTC−4                            |
-| DATETIME_HUGE               | full date and time with weekday and full named offset              | Friday, October 14, 1983, 1:30 PM Eastern Daylight Time    | vendredi 14 octobre 1983 à 13:30 heure d’été de l’Est    |
-| DATETIME_SHORT_WITH_SECONDS | short date & time with seconds                                     | 10/14/1983, 1:30:23 PM                                     | 14/10/1983 à 13:30:23                                    |
-| DATETIME_MED_WITH_SECONDS   | abbreviated date & time with seconds                               | Oct 14, 1983, 1:30:23 PM                                   | 14 oct. 1983 à 13:30:23                                  |
-| DATETIME_FULL_WITH_SECONDS  | full date and time with abbreviated named offset with seconds      | October 14, 1983, 1:30:23 PM EDT                           | 14 octobre 1983 à 13:30:23 UTC−4                         |
-| DATETIME_HUGE_WITH_SECONDS  | full date and time with weekday and full named offset with seconds | Friday, October 14, 1983, 1:30:23 PM Eastern Daylight Time | vendredi 14 octobre 1983 à 13:30:23 heure d’été de l’Est |
+| Name                         | Description                                                        | Example in en_US                                             | Example in fr                                              |
+| ---------------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------------------------------------------- |
+| `DATE_SHORT`                 | short date                                                         | `10/14/1983`                                                 | `14/10/1983`                                               |
+| `DATE_MED`                   | abbreviated date                                                   | `Oct 14, 1983`                                               | `14 oct. 1983`                                             |
+| `DATE_MED_WITH_WEEKDAY`      | abbreviated date with abbreviated weekday                          | `Fri, Oct 14, 1983`                                          | `ven. 14 oct. 1983`                                             |
+| `DATE_FULL`                  | full date                                                          | `October 14, 1983`                                           | `14 octobre 1983`                                          |
+| `DATE_HUGE`                  | full date with weekday                                             | `Friday, October 14, 1983`                                   | `vendredi 14 octobre 1983`                                 |
+| `TIME_SIMPLE`                | time                                                               | `1:30 PM`                                                    | `13:30`                                                    |
+| `TIME_WITH_SECONDS`          | time with seconds                                                  | `1:30:23 PM`                                                 | `13:30:23`                                                 |
+| `TIME_WITH_SHORT_OFFSET`     | time with seconds and abbreviated named offset                     | `1:30:23 PM EDT`                                             | `13:30:23 UTC−4`                                           |
+| `TIME_WITH_LONG_OFFSET`      | time with seconds and full named offset                            | `1:30:23 PM Eastern Daylight Time`                           | `13:30:23 heure d’été de l’Est`                            |
+| `TIME_24_SIMPLE`             | 24-hour time                                                       | `13:30`                                                      | `13:30`                                                    |
+| `TIME_24_WITH_SECONDS`       | 24-hour time with seconds                                          | `13:30:23`                                                   | `13:30:23`                                                 |
+| `TIME_24_WITH_SHORT_OFFSET`  | 24-hour time with seconds and abbreviated named offset             | `13:30:23 EDT`                                               | `13:30:23 UTC−4`                                           |
+| `TIME_24_WITH_LONG_OFFSET`   | 24-hour time with seconds and full named offset                    | `13:30:23 Eastern Daylight Time`                             | `13:30:23 heure d’été de l’Est`                            |
+| `DATETIME_SHORT`             | short date & time                                                  | `10/14/1983, 1:30 PM`                                        | `14/10/1983 à 13:30`                                       |
+| `DATETIME_MED`               | abbreviated date & time                                            | `Oct 14, 1983, 1:30 PM`                                      | `14 oct. 1983 à 13:30`                                     |
+| `DATETIME_FULL`              | full date and time with abbreviated named offset                   | `October 14, 1983, 1:30 PM EDT`                              | `14 octobre 1983 à 13:30 UTC−4`                            |
+| `DATETIME_HUGE`              | full date and time with weekday and full named offset              | `Friday, October 14, 1983, 1:30 PM Eastern Daylight Time`    | `vendredi 14 octobre 1983 à 13:30 heure d’été de l’Est`    |
+| `DATETIME_SHORT_WITH_SECONDS`| short date & time with seconds                                     | `10/14/1983, 1:30:23 PM`                                     | `14/10/1983 à 13:30:23`                                    |
+| `DATETIME_MED_WITH_SECONDS`  | abbreviated date & time with seconds                               | `Oct 14, 1983, 1:30:23 PM`                                   | `14 oct. 1983 à 13:30:23`                                  |
+| `DATETIME_FULL_WITH_SECONDS` | full date and time with abbreviated named offset with seconds      | `October 14, 1983, 1:30:23 PM EDT`                           | `14 octobre 1983 à 13:30:23 UTC−4`                         |
+| `DATETIME_HUGE_WITH_SECONDS` | full date and time with weekday and full named offset with seconds | `Friday, October 14, 1983, 1:30:23 PM Eastern Daylight Time` | `vendredi 14 octobre 1983 à 13:30:23 heure d’été de l’Est` |
 
 ### Intl
 
diff --git a/docs/math.md b/docs/math.md
index 0366af5f..2dd72e8f 100644
--- a/docs/math.md
+++ b/docs/math.md
@@ -211,7 +211,7 @@ These are always true and you can roll them up and down with consistency (e.g. `
 These should match your intuition and for most purposes they work well. But they're not just wrong; they're not even self-consistent:
 
 ```js
-dur.shiftTo('months').shiftTo('days').as('years') //=> 0.9863013698630136
+Duration.fromObject({ years:1 }).shiftTo('months').shiftTo('days').as('years') //=> 0.9863013698630136
 ```
 
 This is because 12 * 30 != 365. These errors can be annoying, but they can also cause significant issues if the errors accumulate:
diff --git a/docs/moment.md b/docs/moment.md
index e41d443d..524fef64 100644
--- a/docs/moment.md
+++ b/docs/moment.md
@@ -27,7 +27,7 @@ This happens because the `plus` method returns a new instance, leaving `d1` unmo
 1. Months in Luxon are 1-indexed instead of 0-indexed like in Moment and the native Date type.
 1. Localizations and time zones are implemented by the native Intl API (or a polyfill of it), instead of by the library itself.
 1. Luxon has both a Duration type and an Interval type. The Interval type is like Twix.
-1. Luxon lacks the relative time features of Moment and won't support it until the required [facilities](https://github.com/tc39/proposal-intl-relative-time) are provided by the browser.
+1. Luxon only supports [relative time features](#humanization) if the required [Intl.RelativeTimeFormat](https://github.com/tc39/proposal-intl-relative-time) APIs are provided by the browser or polyfills.
 
 ## Other API style differences
 
diff --git a/docs/parsing.md b/docs/parsing.md
index 25210517..cf7f0e5e 100644
--- a/docs/parsing.md
+++ b/docs/parsing.md
@@ -83,7 +83,7 @@ Both methods accept the same options, which allow you to specify a timezone, cal
 
 ### JS Date Object
 
-A native JS `Date` object can be converted into a `DateTime` using [fromJSDate](../class/src/datetime.js~DateTime.html#static-method-fromJSDate).
+A native JS `Date` object can be converted into a `DateTime` using `DateTime.fromJSDate`.
 
 An optional `zone` parameter can be provided to set the zone on the resulting object.
 
diff --git a/src/zones/IANAZone.js b/src/zones/IANAZone.js
index 960c3fc6..5975598a 100644
--- a/src/zones/IANAZone.js
+++ b/src/zones/IANAZone.js
@@ -97,6 +97,9 @@ export default class IANAZone extends Zone {
    * @return {boolean}
    */
   static isValidZone(zone) {
+    if (!zone) {
+      return false;
+    }
     try {
       new Intl.DateTimeFormat("en-US", { timeZone: zone }).format();
       return true;


Test patch:
diff --git a/test/zones/IANA.test.js b/test/zones/IANA.test.js
index 81d9138e..62b420ce 100644
--- a/test/zones/IANA.test.js
+++ b/test/zones/IANA.test.js
@@ -29,6 +29,9 @@ test("IANAZone.isValidZone", () => {
   expect(IANAZone.isValidZone("Fantasia/Castle")).toBe(false);
   expect(IANAZone.isValidZone("Sport~~blorp")).toBe(false);
   expect(IANAZone.isValidZone("")).toBe(false);
+  expect(IANAZone.isValidZone(undefined)).toBe(false);
+  expect(IANAZone.isValidZone(null)).toBe(false);
+  expect(IANAZone.isValidZone(4)).toBe(false);
 });
 
 test("IANAZone.parseGMTOffset returns a number for a valid input", () => {