{"record":{"id":"2efe4998e8dbc35d","repo":"affaan-m/ECC","slug":"label-must-not-contain-control-or-bidirectional","errorCode":null,"errorMessage":"${label} must not contain control or bidirectional formatting characters.","messagePattern":"(.+?) must not contain control or bidirectional formatting characters\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"scripts/lib/memory-vault-format.js","lineNumber":86,"sourceCode":"      || (codePoint >= 0x7f && codePoint <= 0x9f);\n    const isBidirectionalFormatting = (\n      (codePoint >= 0x202a && codePoint <= 0x202e)\n      || (codePoint >= 0x2066 && codePoint <= 0x2069)\n    );\n    return isControl || isBidirectionalFormatting;\n  });\n}\n\nfunction asNonEmptyString(value, label, maxChars = 10_000) {\n  if (typeof value !== 'string' || value.trim().length === 0) {\n    throw new Error(`${label} must be a non-empty string.`);\n  }\n  const normalized = value.trim();\n  if (normalized.length > maxChars) {\n    throw new Error(`${label} is too long (maximum ${maxChars} characters).`);\n  }\n  if (hasUnsafeControlCharacters(normalized)) {\n    throw new Error(`${label} must not contain control or bidirectional formatting characters.`);\n  }\n  return normalized;\n}\n\nfunction validateEnum(value, allowed, label) {\n  const normalized = asNonEmptyString(value, label, 64);\n  if (!allowed.includes(normalized)) {\n    throw new Error(`${label} must be one of: ${allowed.join(', ')}.`);\n  }\n  return normalized;\n}\n\nfunction validateSlug(value, label) {\n  const normalized = asNonEmptyString(value, label, 64);\n  if (!SLUG_PATTERN.test(normalized)) {\n    throw new Error(`${label} must be a lowercase letters/numbers slug.`);\n  }\n  return normalized;","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/affaan-m/ECC/blob/8321021c54d670126ce3b2969d5deb880b4b0c2a/scripts/lib/memory-vault-format.js#L68-L104","documentation":"After trimming and length checks, asNonEmptyString scans for unsafe control characters and bidirectional formatting characters (e.g. U+202E RTL overrides) that could corrupt display or enable Trojan-source style spoofing. Any validated memory-vault string containing them is rejected.","triggerScenarios":"Passing a string containing control characters (e.g. \\u0000-\\u001F other than allowed whitespace, \\u007F) or bidi marks (\\u200F, \\u202E, etc.) to asNonEmptyString via normalizeMemory or resolveOverride.","commonSituations":"Pasting text from PDFs or terminals that embed control characters; malicious input crafted with RTL overrides to reverse visual display; binary data accidentally decoded as a string; filenames or logs copied with stray \\x1b escape sequences.","solutions":["Strip control and bidi characters from the input, e.g. value.replace(/[\\u0000-\\u001F\\u007F\\u200B-\\u200F\\u202A-\\u202E]/g, '').","Sanitize user input at the boundary before passing to the vault.","Re-copy the text from a clean source if it was pasted from a PDF/terminal.","For bidi content, store a plain-text normalization rather than raw directional marks."],"exampleFix":"// before\nasNonEmptyString(pastedText, 'content')\n// after\nconst clean = pastedText.replace(/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F\\u200B-\\u200F\\u202A-\\u202E]/g, '')\nasNonEmptyString(clean, 'content')","handlingStrategy":"validation","validationCode":"// eslint-disable-next-line no-control-regex\nconst UNSAFE = /[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F\\u200B-\\u200F\\u202A-\\u202E]/g\nconst sanitized = String(raw).replace(UNSAFE, '')","typeGuard":"function isSafeText(v) {\n  // eslint-disable-next-line no-control-regex\n  return typeof v === 'string' && !/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F\\u200B-\\u200F\\u202A-\\u202E]/.test(v)\n}","tryCatchPattern":"try {\n  asNonEmptyString(value, 'content')\n} catch (err) {\n  if (err.message.includes('control or bidirectional')) {\n    value = value.replace(/[\\u0000-\\u0008\\u000B\\u000C\\u000E-\\u001F\\u007F\\u200B-\\u200F\\u202A-\\u202E]/g, '')\n  } else throw err\n}","preventionTips":["Sanitize all pasted/external text before storing in the vault.","Strip control and bidi characters at input boundaries (clipboard, file import).","Treat RTL-override characters in user input as suspicious (Trojan-source defense).","Re-copy text from clean sources rather than pasting from PDFs/terminals."],"tags":["validation","memory-vault","sanitization","security"],"backgroundTag":"invalid-argument-format","analyzedSha":"8321021c54d670126ce3b2969d5deb880b4b0c2a","analyzedAt":"2026-09-16T10:08:13.343Z","contentChangedAt":"2026-09-16T10:08:13.343Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}