Skip to content

Commit 71eb43f

Browse files
authored
ci: add basic validation for declarative function names (#390)
Adds basic function name validation for registered functions. As almost any sequence of strings can be URL encoded into a valid URL when URL encoded, we check for valid function names using a regex. Fixes GoogleCloudPlatform#388
1 parent 128378d commit 71eb43f

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/function_registry.ts

+19
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,31 @@ const register = (
3333
signatureType: SignatureType,
3434
userFunction: HandlerFunction
3535
): void => {
36+
if (!isValidFunctionName(functionName)) {
37+
throw new Error(`Invalid function name: ${functionName}`);
38+
}
39+
3640
registrationContainer.set(functionName, {
3741
signatureType,
3842
userFunction,
3943
});
4044
};
4145

46+
/**
47+
* Returns true if the function name is valid
48+
* - must contain only alphanumeric, numbers, or dash characters
49+
* - must be <= 63 characters
50+
* - must start with a letter
51+
* - must end with a letter or number
52+
* @param functionName the function name
53+
* @returns true if the function name is valid
54+
*/
55+
export const isValidFunctionName = (functionName: string): boolean => {
56+
// Validate function name with alpha characters, and dashes
57+
const regex = /^[A-Za-z](?:[-_A-Za-z0-9]{0,61}[A-Za-z0-9])?$/;
58+
return regex.test(functionName);
59+
};
60+
4261
/**
4362
* Get a declaratively registered function
4463
* @param functionName the name with which the function was registered

test/function_registry.ts

+18
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,22 @@ describe('function_registry', () => {
3030
assert.deepStrictEqual('cloudevent', signatureType);
3131
assert.deepStrictEqual((userFunction as () => string)(), 'CE_PASS');
3232
});
33+
34+
it('throws an error if you try to register a function with an invalid URL', () => {
35+
// Valid function names
36+
const validFunctions = ['httpFunction', 'ceFunction', 'test-func'];
37+
validFunctions.forEach(functionName => {
38+
assert.doesNotThrow(() => {
39+
FunctionRegistry.http(functionName, () => 'OK');
40+
});
41+
});
42+
43+
// Invalid function names
44+
const invalidFunctions = ['', 'foo bar', 'ស្ថានីយ'];
45+
invalidFunctions.forEach(functionName => {
46+
assert.throws(() => {
47+
FunctionRegistry.http(functionName, () => 'OK');
48+
});
49+
});
50+
});
3351
});

0 commit comments

Comments
 (0)