@@ -759,6 +759,20 @@ describe("loadWebMedia", () => {
759759 expect ( result . contentType ) . toBe ( "text/markdown" ) ;
760760 } ) ;
761761
762+ it ( "rejects host-read HTML files without a separate security-boundary approval" , async ( ) => {
763+ const htmlFile = path . join ( fixtureRoot , "report.html" ) ;
764+ await fs . writeFile ( htmlFile , "<!doctype html><title>Report</title><h1>Report</h1>\n" , "utf8" ) ;
765+ await expectLoadWebMediaErrorCode (
766+ loadWebMedia ( htmlFile , {
767+ maxBytes : 1024 * 1024 ,
768+ localRoots : "any" ,
769+ readFile : async ( filePath ) => await fs . readFile ( filePath ) ,
770+ hostReadCapability : true ,
771+ } ) ,
772+ "path-not-allowed" ,
773+ ) ;
774+ } ) ;
775+
762776 it . each ( [
763777 {
764778 label : "ZIP" ,
@@ -819,6 +833,7 @@ describe("loadWebMedia", () => {
819833
820834 it . each ( [
821835 { label : "CSV" , fileName : "opaque.csv" } ,
836+ { label : "HTML" , fileName : "opaque.html" } ,
822837 { label : "Markdown" , fileName : "opaque.md" } ,
823838 ] ) ( "rejects opaque non-NUL binary data disguised as %s" , async ( { fileName } ) => {
824839 const fakeTextFile = path . join ( fixtureRoot , fileName ) ;
@@ -840,6 +855,7 @@ describe("loadWebMedia", () => {
840855
841856 it . each ( [
842857 { label : "CSV" , fileName : "prefix-tail.csv" } ,
858+ { label : "HTML" , fileName : "prefix-tail.html" } ,
843859 { label : "Markdown" , fileName : "prefix-tail.md" } ,
844860 ] ) (
845861 "rejects %s files with a text prefix and binary tail after the old sample window" ,
@@ -907,6 +923,7 @@ describe("loadWebMedia", () => {
907923
908924 it . each ( [
909925 { label : "CSV" , fileName : "nul-padded.csv" } ,
926+ { label : "HTML" , fileName : "nul-padded.html" } ,
910927 { label : "Markdown" , fileName : "nul-padded.md" } ,
911928 ] ) ( "rejects NUL-padded binary data disguised as %s" , async ( { fileName } ) => {
912929 const fakeTextFile = path . join ( fixtureRoot , fileName ) ;
@@ -930,6 +947,7 @@ describe("loadWebMedia", () => {
930947
931948 it . each ( [
932949 { label : "CSV" , fileName : "bom-binary.csv" } ,
950+ { label : "HTML" , fileName : "bom-binary.html" } ,
933951 { label : "Markdown" , fileName : "bom-binary.md" } ,
934952 ] ) ( "rejects UTF-16 BOM-prefixed binary data disguised as %s" , async ( { fileName } ) => {
935953 const fakeTextFile = path . join ( fixtureRoot , fileName ) ;
@@ -953,6 +971,7 @@ describe("loadWebMedia", () => {
953971
954972 it . each ( [
955973 { label : "CSV" , fileName : "alternating-high.csv" } ,
974+ { label : "HTML" , fileName : "alternating-high.html" } ,
956975 { label : "Markdown" , fileName : "alternating-high.md" } ,
957976 ] ) ( "rejects alternating ASCII/high-byte data disguised as %s" , async ( { fileName } ) => {
958977 const fakeTextFile = path . join ( fixtureRoot , fileName ) ;
@@ -977,6 +996,7 @@ describe("loadWebMedia", () => {
977996
978997 it . each ( [
979998 { label : "CSV" , fileName : "high-bytes.csv" } ,
999+ { label : "HTML" , fileName : "high-bytes.html" } ,
9801000 { label : "Markdown" , fileName : "high-bytes.md" } ,
9811001 ] ) ( "rejects high-byte opaque data disguised as %s" , async ( { fileName } ) => {
9821002 const fakeTextFile = path . join ( fixtureRoot , fileName ) ;
0 commit comments