mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
## Summary Fixes #22475 `cookie.isExpired()` was incorrectly returning `false` for cookies with `Expires` set to Unix epoch (Thu, 01 Jan 1970 00:00:00 GMT). ## The Problem The bug had two parts: 1. **In `Cookie::isExpired()`**: The condition `m_expires < 1` incorrectly treated Unix epoch (0) as a session cookie instead of an expired cookie. 2. **In `Cookie::parse()`**: When parsing date strings that evaluate to 0 (Unix epoch), the code used implicit boolean conversion which treated 0 as false, preventing the expires value from being set. ## The Fix - Removed the `m_expires < 1` check from `isExpired()`, keeping only the check for `emptyExpiresAtValue` to identify session cookies - Fixed date parsing to use `std::isfinite()` instead of implicit boolean conversion, properly handling Unix epoch (0) ## Test Plan - Added regression test in `test/regression/issue/22475.test.ts` covering Unix epoch and edge cases - All existing cookie tests pass (`bun bd test test/js/bun/cookie/`) - Manually tested the reported issue from #22475 ```javascript const cookies = [ 'a=; Expires=Thu, 01 Jan 1970 00:00:00 GMT', 'b=; Expires=Thu, 01 Jan 1970 00:00:01 GMT' ]; for (const _cookie of cookies) { const cookie = new Bun.Cookie(_cookie); console.log(cookie.name, cookie.expires, cookie.isExpired()); } ``` Now correctly outputs: ``` a 1970-01-01T00:00:00.000Z true b 1970-01-01T00:00:01.000Z true ``` 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
51 lines
1.9 KiB
TypeScript
51 lines
1.9 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
|
|
test("issue #22475: cookie.isExpired() should return true for Unix epoch (0)", () => {
|
|
const cookies = ["a=; Expires=Thu, 01 Jan 1970 00:00:00 GMT", "b=; Expires=Thu, 01 Jan 1970 00:00:01 GMT"];
|
|
|
|
const results = [];
|
|
for (const _cookie of cookies) {
|
|
const cookie = new Bun.Cookie(_cookie);
|
|
results.push({
|
|
name: cookie.name,
|
|
expires: cookie.expires,
|
|
isExpired: cookie.isExpired(),
|
|
});
|
|
}
|
|
|
|
// Cookie 'a' with Unix epoch (0) should be expired
|
|
expect(results[0].name).toBe("a");
|
|
expect(results[0].expires).toBeDate();
|
|
expect(results[0].expires?.getTime()).toBe(0);
|
|
expect(results[0].isExpired).toBe(true);
|
|
|
|
// Cookie 'b' with 1 second after Unix epoch should also be expired
|
|
expect(results[1].name).toBe("b");
|
|
expect(results[1].expires).toBeDate();
|
|
expect(results[1].expires?.getTime()).toBe(1000);
|
|
expect(results[1].isExpired).toBe(true);
|
|
});
|
|
|
|
test("cookie.isExpired() for various edge cases", () => {
|
|
// Test Unix epoch (0) - should be expired
|
|
const epochCookie = new Bun.Cookie("test", "value", { expires: 0 });
|
|
expect(epochCookie.expires).toBeDate();
|
|
expect(epochCookie.expires?.getTime()).toBe(0);
|
|
expect(epochCookie.isExpired()).toBe(true);
|
|
|
|
// Test negative timestamp - should be expired
|
|
const negativeCookie = new Bun.Cookie("test", "value", { expires: -1 });
|
|
expect(negativeCookie.expires).toBeDate();
|
|
expect(negativeCookie.expires?.getTime()).toBe(-1000);
|
|
expect(negativeCookie.isExpired()).toBe(true);
|
|
|
|
// Test session cookie (no expires) - should not be expired
|
|
const sessionCookie = new Bun.Cookie("test", "value");
|
|
expect(sessionCookie.expires).toBeUndefined();
|
|
expect(sessionCookie.isExpired()).toBe(false);
|
|
|
|
// Test future date - should not be expired
|
|
const futureCookie = new Bun.Cookie("test", "value", { expires: Date.now() + 86400000 });
|
|
expect(futureCookie.isExpired()).toBe(false);
|
|
});
|