|
| 1 | +import { assertNoSurroundingWhitespace, strictUrlPathSegment } from '@/tools/strict-url-path' |
1 | 2 | import { safeUrlPathSegment } from '@/tools/url-path' |
2 | 3 |
|
3 | | -/** |
4 | | - * Refuses an identifier carrying leading or trailing whitespace. |
5 | | - * |
6 | | - * This exists because trimming is not a neutral convenience on an identifier |
7 | | - * that was **not** trimmed before. Every BigQuery path identifier here was |
8 | | - * previously interpolated as `encodeURIComponent(params.projectId)`, so a padded |
9 | | - * value became `%20%20my-project%20%20`, which names no project — GCP project |
10 | | - * ids match `[a-z][a-z0-9-]{5,29}` and cannot contain whitespace — and the |
11 | | - * request failed cleanly. Guarding the path with `safeUrlPathSegment` trims, |
12 | | - * which silently resolves that same value to the **real** `my-project`: |
13 | | - * |
14 | | - * ``` |
15 | | - * before: /bigquery/v2/projects/%20%20my-project%20%20/datasets/prod_dataset -> 404 |
16 | | - * after: /bigquery/v2/projects/my-project/datasets/prod_dataset -> deletes it |
17 | | - * ``` |
18 | | - * |
19 | | - * On `google_bigquery_delete_dataset` and `google_bigquery_delete_table` that |
20 | | - * converts a request that did nothing into one that destroys a real dataset or |
21 | | - * table, irreversibly. The rule this encodes is therefore narrow and testable: |
22 | | - * **this change must not turn a failing request into a succeeding one.** |
23 | | - * |
24 | | - * Rejection rather than trimming is not a consistency argument — that reasoning |
25 | | - * averages over sites with very different blast radii and is exactly what would |
26 | | - * excuse the deletion above. It stands on two facts specific to these values: |
27 | | - * no legitimate BigQuery identifier contains surrounding whitespace, so nothing |
28 | | - * real is refused; and the pre-existing behaviour for these particular |
29 | | - * parameters was already a clean failure, so refusing preserves it while adding |
30 | | - * an error that names the offending parameter instead of an opaque 404. |
31 | | - * |
32 | | - * Identifiers that this PR did **not** newly trim keep `safeUrlPathSegment`. |
33 | | - * `datasetId` on the two delete tools, for instance, was already |
34 | | - * `.trim()`-ed before this branch, so trimming it is not a change made here and |
35 | | - * refusing it would break callers whose stored value works today. That is a |
36 | | - * real pre-existing hazard, but it is not this change's to introduce or to |
37 | | - * silently alter. |
38 | | - */ |
39 | | -function assertNoSurroundingWhitespace(value: string | number | bigint, paramName: string): void { |
40 | | - if (typeof value === 'string' && value !== value.trim()) { |
41 | | - throw new Error( |
42 | | - `${paramName} cannot have leading or trailing whitespace (received ${JSON.stringify(value)})` |
43 | | - ) |
44 | | - } |
45 | | -} |
46 | | - |
47 | | -/** |
48 | | - * Path-segment guard for an identifier this change newly began trimming. |
49 | | - * |
50 | | - * See {@link assertNoSurroundingWhitespace} for why padding is refused here |
51 | | - * rather than trimmed away. |
52 | | - */ |
53 | | -export function strictBigQueryPathSegment( |
54 | | - value: string | number | bigint, |
55 | | - paramName: string |
56 | | -): string { |
57 | | - assertNoSurroundingWhitespace(value, paramName) |
58 | | - return safeUrlPathSegment(value, paramName) |
59 | | -} |
60 | | - |
61 | 4 | /** |
62 | 5 | * Returns the canonical, unencoded form of an identifier that appears in both |
63 | 6 | * the request path and the request body. |
@@ -97,3 +40,9 @@ export function strictCanonicalBigQueryId( |
97 | 40 | assertNoSurroundingWhitespace(value, paramName) |
98 | 41 | return canonicalBigQueryId(value, paramName) |
99 | 42 | } |
| 43 | + |
| 44 | +/** |
| 45 | + * Path-segment guard for a BigQuery identifier this change newly began |
| 46 | + * trimming. See `strictUrlPathSegment` for why padding is refused. |
| 47 | + */ |
| 48 | +export const strictBigQueryPathSegment = strictUrlPathSegment |
0 commit comments