Description
In @dub/utils, the getFileExtension(url) helper function incorrectly returns the full URL pathname (e.g. "/AVATAR" or "/API/V1/USERS") when given a URL that does not contain a file extension.
Reproduction
import { getFileExtension } from "@dub/utils";
console.log(getFileExtension("https://dub.co/avatar"));
// Output: "/AVATAR" (Expected: null)
console.log(getFileExtension("https://dub.co/api/v1/users"));
// Output: "/API/V1/USERS" (Expected: null)
Cause
In packages/utils/src/functions/urls.ts:
export const getFileExtension = (url: string): string | null => {
try {
const pathname = new URL(url).pathname;
const extension = pathname.split(".").pop(); // When pathname has no ".", returns entire pathname
return extension ? extension.toUpperCase() : null;
} catch { ... }
};
When pathname has no dot (.), pathname.split(".") yields ["/avatar"]. Calling .pop() returns "/avatar", which is truthy, so it returns "/AVATAR".
Impact
In ResourceCard (resources/page.tsx), brand logos with extensionless asset URLs display badge labels like "/LOGO · 24 KB" instead of "Unknown · 24 KB".
Proposed Fix
Verify that the extracted filename actually contains a dot before returning the extension:
export const getFileExtension = (url: string): string | null => {
try {
const pathname = new URL(url).pathname;
const filename = pathname.split("/").pop() || "";
if (!filename.includes(".")) return null;
const extension = filename.split(".").pop();
return extension && extension !== filename ? extension.toUpperCase() : null;
} catch {
return null;
}
};
Description
In
@dub/utils, thegetFileExtension(url)helper function incorrectly returns the full URL pathname (e.g."/AVATAR"or"/API/V1/USERS") when given a URL that does not contain a file extension.Reproduction
Cause
In
packages/utils/src/functions/urls.ts:When
pathnamehas no dot (.),pathname.split(".")yields["/avatar"]. Calling.pop()returns"/avatar", which is truthy, so it returns"/AVATAR".Impact
In
ResourceCard(resources/page.tsx), brand logos with extensionless asset URLs display badge labels like"/LOGO · 24 KB"instead of"Unknown · 24 KB".Proposed Fix
Verify that the extracted filename actually contains a dot before returning the extension: