Skip to content

Commit 1752fba

Browse files
Sander Toonenclaude
andcommitted
Fix length(null) to return 0 instead of 4
The unary `length` operator special-cased `undefined` and arrays, then fell through to `String(s).length`. For `null` that became `String(null)` -> "null" -> 4. Treat `null` as an explicit empty value with length 0, keeping `undefined` propagating as `undefined`. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 1637568 commit 1752fba

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

packages/expreszo/src/operators/unary/logical.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,16 @@ export function not(a: any): boolean {
77
return !a;
88
}
99

10-
export function length(s: any[] | string | number | undefined): number | undefined {
10+
export function length(s: any[] | string | number | null | undefined): number | undefined {
1111
if (s === undefined) {
1212
return undefined;
1313
}
1414

15+
// `null` is an explicit empty value — its length is 0, not `String(null).length` (4).
16+
if (s === null) {
17+
return 0;
18+
}
19+
1520
if (Array.isArray(s)) {
1621
return s.length;
1722
}

packages/expreszo/test/functions/functions-string.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ describe('String Functions TypeScript Test', function () {
1515
assert.strictEqual(parser.evaluate('length(undefined)'), undefined);
1616
});
1717

18+
it('should return 0 if argument is null', function () {
19+
const parser = new Parser();
20+
assert.strictEqual(parser.evaluate('length(null)'), 0);
21+
});
22+
1823
// Note: length(123) returns 3 (number of digits) because there's also a unary operator
1924
// that handles numbers, so we don't test the error case for non-string argument
2025
});

0 commit comments

Comments
 (0)