diff --git a/sdk/typescript/src/knowledge-base.ts b/sdk/typescript/src/knowledge-base.ts index ad82a3c..e150d93 100644 --- a/sdk/typescript/src/knowledge-base.ts +++ b/sdk/typescript/src/knowledge-base.ts @@ -193,6 +193,7 @@ function extractDocx(path: string, bytes: Uint8Array): string { return decodeXml( xml .replace(/<\/(?:\w+:)?p\s*>/gu, "\n") + .replace(/<(?:\w+:)?br\b[^>]*>/gu, "\n") .replace(/<(?:\w+:)?tab\b[^>]*\/>/gu, "\t") .replace(/<[^>]+>/gu, ""), ); diff --git a/sdk/typescript/tests-ts/knowledge-base.test.ts b/sdk/typescript/tests-ts/knowledge-base.test.ts index 79ca83c..8404c5c 100644 --- a/sdk/typescript/tests-ts/knowledge-base.test.ts +++ b/sdk/typescript/tests-ts/knowledge-base.test.ts @@ -41,10 +41,14 @@ async function extractedDocuments(path: string): Promise { ); } -function docx(text: string): Uint8Array { +function docx( + text: string, + secondLine?: string, + breakElement = "", +): Uint8Array { return zipSync({ "word/document.xml": strToU8( - `${text}`, + `${text}${secondLine === undefined ? "" : `${breakElement}${secondLine}`}`, ), }); } @@ -111,14 +115,22 @@ describe("scan knowledge bases", () => { join(root, "architecture.pdf"), pdf("Payment service boundary"), ); - await writeFile(join(root, "threat-model.docx"), docx("SSRF & IDOR")); + await writeFile( + join(root, "threat-model.docx"), + docx("SSRF & IDOR", "Review authentication"), + ); + await writeFile( + join(root, "paired-break.docx"), + docx("Authorization", "Review permissions", ""), + ); const knowledgeBase = await prepareKnowledgeBase([root]); temporaryDirectories.push(knowledgeBase.path); const documents = await extractedDocuments(knowledgeBase.path); expect(documents).toContain("Payment service boundary"); - expect(documents).toContain("SSRF & IDOR\n"); + expect(documents).toContain("SSRF & IDOR\nReview authentication\n"); + expect(documents).toContain("Authorization\nReview permissions\n"); }); test("cleans up documents and rediscovers directory contents on later runs", async () => {