@@ -54,13 +54,13 @@ export function sparkleBuildFloorsFromShortVersion(
|
54 | 54 | return null; |
55 | 55 | } |
56 | 56 | |
57 | | -const year = Number.parseInt(match[1], 10); |
58 | | -const month = Number.parseInt(match[2], 10); |
59 | | -const patch = Number.parseInt(match[3], 10); |
| 57 | +const year = Number(match[1]); |
| 58 | +const month = Number(match[2]); |
| 59 | +const patch = Number(match[3]); |
60 | 60 | if ( |
61 | | -!Number.isInteger(year) || |
62 | | -!Number.isInteger(month) || |
63 | | -!Number.isInteger(patch) || |
| 61 | +!Number.isSafeInteger(year) || |
| 62 | +!Number.isSafeInteger(month) || |
| 63 | +!Number.isSafeInteger(patch) || |
64 | 64 | month < 1 || |
65 | 65 | month > 12 || |
66 | 66 | patch < 1 |
@@ -87,24 +87,39 @@ export function sparkleBuildFloorsFromShortVersion(
|
87 | 87 | // Keep old appcast entries byte-stable, then switch to YYMMPPPPLL so |
88 | 88 | // monthly patches beyond 31 stay monotonic without pretending to be dates. |
89 | 89 | const releaseKey = monthlyPatchReleaseKey(year, month, patch); |
| 90 | +const laneFloor = releaseKey + lane; |
| 91 | +if (!isSafeSparkleFloor(releaseKey) || !isSafeSparkleFloor(laneFloor)) { |
| 92 | +return null; |
| 93 | +} |
90 | 94 | return { |
91 | 95 | releaseKey, |
92 | 96 | legacyFloor: releaseKey, |
93 | | -laneFloor: releaseKey + lane, |
| 97 | + laneFloor, |
94 | 98 | lane, |
95 | 99 | }; |
96 | 100 | } |
97 | 101 | |
98 | 102 | const releaseKey = legacyDateReleaseKey(year, month, patch); |
99 | 103 | const legacyFloor = Number(`${releaseKey}0`); |
100 | 104 | const laneFloor = Number(`${releaseKey}${String(lane).padStart(2, "0")}`); |
| 105 | +if ( |
| 106 | +!isSafeSparkleFloor(releaseKey) || |
| 107 | +!isSafeSparkleFloor(legacyFloor) || |
| 108 | +!isSafeSparkleFloor(laneFloor) |
| 109 | +) { |
| 110 | +return null; |
| 111 | +} |
101 | 112 | return { releaseKey, legacyFloor, laneFloor, lane }; |
102 | 113 | } |
103 | 114 | |
104 | 115 | export function canonicalSparkleBuildFromVersion(shortVersion: string): number | null { |
105 | 116 | return sparkleBuildFloorsFromShortVersion(shortVersion)?.laneFloor ?? null; |
106 | 117 | } |
107 | 118 | |
| 119 | +function isSafeSparkleFloor(value: number): boolean { |
| 120 | +return Number.isSafeInteger(value) && value > 0; |
| 121 | +} |
| 122 | + |
108 | 123 | function runCli(args: string[]): number { |
109 | 124 | const [command, version] = args; |
110 | 125 | if (command !== "canonical-build" || !version) { |
|