1 // ██████╗ █████╗ ███████╗███████╗██╗███╗ ██╗ ██████╗ 2 // ██╔══██╗██╔══██╗██╔════╝██╔════╝██║████╗ ██║██╔════╝ 3 // ██████╔╝███████║███████╗███████╗██║██╔██╗ ██║██║ ███╗ 4 // ██╔═══╝ ██╔══██║╚════██║╚════██║██║██║╚██╗██║██║ ██║ 5 // ██║ ██║ ██║███████║███████║██║██║ ╚████║╚██████╔╝ 6 // ╚═╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ 7 8 #[cfg(test)] 9 mod passing { 10 use assert_cmd::prelude::*; 11 use std::env; 12 use std::process::Command; 13 14 #[test] isolate_data_url()15 fn isolate_data_url() { 16 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 17 let out = cmd 18 .arg("-M") 19 .arg("-I") 20 .arg("data:text/html,Hello%2C%20World!") 21 .output() 22 .unwrap(); 23 24 // STDERR should be empty 25 assert_eq!(String::from_utf8_lossy(&out.stderr), ""); 26 27 // STDOUT should contain isolated HTML 28 assert_eq!( 29 String::from_utf8_lossy(&out.stdout), 30 "<html><head>\ 31 <meta http-equiv=\"Content-Security-Policy\" content=\"default-src 'unsafe-inline' data:;\"></meta>\ 32 </head><body>Hello, World!</body></html>\n" 33 ); 34 35 // Exit code should be 0 36 out.assert().code(0); 37 } 38 39 #[test] remove_css_from_data_url()40 fn remove_css_from_data_url() { 41 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 42 let out = cmd 43 .arg("-M") 44 .arg("-c") 45 .arg("data:text/html,<style>body{background-color:pink}</style>Hello") 46 .output() 47 .unwrap(); 48 49 // STDERR should be empty 50 assert_eq!(String::from_utf8_lossy(&out.stderr), ""); 51 52 // STDOUT should contain HTML with no CSS 53 assert_eq!( 54 String::from_utf8_lossy(&out.stdout), 55 "<html><head>\ 56 <meta http-equiv=\"Content-Security-Policy\" content=\"style-src 'none';\"></meta>\ 57 <style></style>\ 58 </head><body>Hello</body></html>\n" 59 ); 60 61 // Exit code should be 0 62 out.assert().code(0); 63 } 64 65 #[test] remove_fonts_from_data_url()66 fn remove_fonts_from_data_url() { 67 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 68 let out = cmd 69 .arg("-M") 70 .arg("-F") 71 .arg("data:text/html,<style>@font-face { font-family: myFont; src: url(font.woff); }</style>Hi") 72 .output() 73 .unwrap(); 74 75 // STDERR should be empty 76 assert_eq!(String::from_utf8_lossy(&out.stderr), ""); 77 78 // STDOUT should contain HTML with no web fonts 79 assert_eq!( 80 String::from_utf8_lossy(&out.stdout), 81 "<html><head>\ 82 <meta http-equiv=\"Content-Security-Policy\" content=\"font-src 'none';\"></meta>\ 83 <style></style>\ 84 </head><body>Hi</body></html>\n" 85 ); 86 87 // Exit code should be 0 88 out.assert().code(0); 89 } 90 91 #[test] remove_frames_from_data_url()92 fn remove_frames_from_data_url() { 93 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 94 let out = cmd 95 .arg("-M") 96 .arg("-f") 97 .arg("data:text/html,<iframe src=\"https://duckduckgo.com\"></iframe>Hi") 98 .output() 99 .unwrap(); 100 101 // STDERR should be empty 102 assert_eq!(String::from_utf8_lossy(&out.stderr), ""); 103 104 // STDOUT should contain HTML with no iframes 105 assert_eq!( 106 String::from_utf8_lossy(&out.stdout), 107 "<html><head>\ 108 <meta http-equiv=\"Content-Security-Policy\" content=\"frame-src 'none'; child-src 'none';\"></meta>\ 109 </head><body><iframe src=\"\"></iframe>Hi</body></html>\n" 110 ); 111 112 // Exit code should be 0 113 out.assert().code(0); 114 } 115 116 #[test] remove_images_from_data_url()117 fn remove_images_from_data_url() { 118 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 119 let out = cmd 120 .arg("-M") 121 .arg("-i") 122 .arg("data:text/html,<img src=\"https://google.com\"/>Hi") 123 .output() 124 .unwrap(); 125 126 // STDERR should be empty 127 assert_eq!(String::from_utf8_lossy(&out.stderr), ""); 128 129 // STDOUT should contain HTML with no images 130 assert_eq!( 131 String::from_utf8_lossy(&out.stdout), 132 format!( 133 "<html>\ 134 <head>\ 135 <meta http-equiv=\"Content-Security-Policy\" content=\"img-src data:;\"></meta>\ 136 </head>\ 137 <body>\ 138 <img src=\"{empty_image}\">\ 139 Hi\ 140 </body>\ 141 </html>\n", 142 empty_image = empty_image!() 143 ) 144 ); 145 146 // Exit code should be 0 147 out.assert().code(0); 148 } 149 150 #[test] remove_js_from_data_url()151 fn remove_js_from_data_url() { 152 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 153 let out = cmd 154 .arg("-M") 155 .arg("-j") 156 .arg("data:text/html,<script>alert(2)</script>Hi") 157 .output() 158 .unwrap(); 159 160 // STDERR should be empty 161 assert_eq!(String::from_utf8_lossy(&out.stderr), ""); 162 163 // STDOUT should contain HTML with no JS 164 assert_eq!( 165 String::from_utf8_lossy(&out.stdout), 166 "<html>\ 167 <head>\ 168 <meta http-equiv=\"Content-Security-Policy\" content=\"script-src 'none';\"></meta>\ 169 <script></script></head>\ 170 <body>Hi</body>\ 171 </html>\n" 172 ); 173 174 // Exit code should be 0 175 out.assert().code(0); 176 } 177 } 178 179 // ███████╗ █████╗ ██╗██╗ ██╗███╗ ██╗ ██████╗ 180 // ██╔════╝██╔══██╗██║██║ ██║████╗ ██║██╔════╝ 181 // █████╗ ███████║██║██║ ██║██╔██╗ ██║██║ ███╗ 182 // ██╔══╝ ██╔══██║██║██║ ██║██║╚██╗██║██║ ██║ 183 // ██║ ██║ ██║██║███████╗██║██║ ╚████║╚██████╔╝ 184 // ╚═╝ ╚═╝ ╚═╝╚═╝╚══════╝╚═╝╚═╝ ╚═══╝ ╚═════╝ 185 186 #[cfg(test)] 187 mod failing { 188 use assert_cmd::prelude::*; 189 use std::env; 190 use std::process::Command; 191 192 #[test] bad_input_data_url()193 fn bad_input_data_url() { 194 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 195 let out = cmd.arg("data:,Hello%2C%20World!").output().unwrap(); 196 197 // STDERR should contain error description 198 assert_eq!( 199 String::from_utf8_lossy(&out.stderr), 200 "Unsupported document media type\n" 201 ); 202 203 // STDOUT should contain HTML 204 assert_eq!(String::from_utf8_lossy(&out.stdout), ""); 205 206 // Exit code should be 1 207 out.assert().code(1); 208 } 209 210 #[test] security_disallow_local_assets_within_data_url_targets()211 fn security_disallow_local_assets_within_data_url_targets() { 212 let mut cmd = Command::cargo_bin(env!("CARGO_PKG_NAME")).unwrap(); 213 let out = cmd 214 .arg("-M") 215 .arg("data:text/html,%3Cscript%20src=\"src/tests/data/basic/local-script.js\"%3E%3C/script%3E") 216 .output() 217 .unwrap(); 218 219 // STDERR should be empty 220 assert_eq!(String::from_utf8_lossy(&out.stderr), ""); 221 222 // STDOUT should contain HTML with no JS in it 223 assert_eq!( 224 String::from_utf8_lossy(&out.stdout), 225 "<html><head><script src=\"data:application/javascript;base64,\"></script></head><body></body></html>\n" 226 ); 227 228 // Exit code should be 0 229 out.assert().code(0); 230 } 231 } 232