27 lines · 961 B · TypeScript
RawDownload
// @effect-diagnostics nodeBuiltinImport:offimport NodePath from "node:path"; export function normalizeAttachmentRelativePath(rawRelativePath: string): string | null {  const normalized = NodePath.normalize(rawRelativePath).replace(/^[/\\]+/, "");  if (normalized.length === 0 || normalized.startsWith("..") || normalized.includes("\0")) {    return null;  }  return normalized.replace(/\\/g, "/");} export function resolveAttachmentRelativePath(input: {  readonly attachmentsDir: string;  readonly relativePath: string;}): string | null {  const normalizedRelativePath = normalizeAttachmentRelativePath(input.relativePath);  if (!normalizedRelativePath) {    return null;  }   const attachmentsRoot = NodePath.resolve(input.attachmentsDir);  const filePath = NodePath.resolve(NodePath.join(attachmentsRoot, normalizedRelativePath));  if (!filePath.startsWith(`${attachmentsRoot}${NodePath.sep}`)) {    return null;  }  return filePath;}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t