Procházet zdrojové kódy

Fix file validation in worker to use fs.openSync/fs.readSync instead of readFileSync with options

Timothy Pomeroy před 4 týdny
rodič
revize
b511c58297
1 změnil soubory, kde provedl 50 přidání a 17 odebrání
  1. 50 17
      apps/service/src/file-validation-worker.ts

+ 50 - 17
apps/service/src/file-validation-worker.ts

@@ -1,6 +1,6 @@
-import { parentPort } from 'worker_threads';
 import fs from 'fs';
 import path from 'path';
+import { parentPort } from 'worker_threads';
 
 function isVideoFile(file: string): boolean {
   const ext = path.extname(file).toLowerCase();
@@ -10,23 +10,56 @@ function isVideoFile(file: string): boolean {
 
 function isValidVideoFile(file: string): boolean {
   try {
-    // Read first 64KB to check for video headers
-    const buffer = fs.readFileSync(file, { length: 65536 });
-    // Simple check for common video signatures
-    const signatures = [
-      Buffer.from([0x00, 0x00, 0x00, 0x20, 0x66, 0x74, 0x79, 0x70]), // MP4
-      Buffer.from([0x1A, 0x45, 0xDF, 0xA3]), // MKV/WebM
-      Buffer.from([0x52, 0x49, 0x46, 0x46]), // AVI
-      Buffer.from([0x00, 0x00, 0x00, 0x14, 0x66, 0x74, 0x79, 0x70, 0x71, 0x74, 0x20, 0x20]), // MOV
-    ];
-    for (const sig of signatures) {
-      if (buffer.indexOf(sig) !== -1) {
-        return true;
-      }
+    // Check if file exists and is readable
+    if (!fs.existsSync(file)) {
+      return false;
     }
-    return false;
+
+    const stats = fs.statSync(file);
+    if (stats.size === 0) {
+      return false;
+    }
+
+    // Read first few bytes to check for video file signatures
+    const buffer = Buffer.alloc(12);
+    const fd = fs.openSync(file, 'r');
+    try {
+      fs.readSync(fd, buffer, 0, 12, 0);
+    } finally {
+      fs.closeSync(fd);
+    }
+
+    // Check for common video file signatures
+    const signature = buffer.toString('hex');
+
+    // MP4 signature (ftyp box)
+    if (signature.includes('66747970')) {
+      return true;
+    }
+
+    // MKV/WebM signature (EBML)
+    if (signature.startsWith('1a45dfa3')) {
+      return true;
+    }
+
+    // AVI signature (RIFF)
+    if (
+      signature.startsWith('52494646') &&
+      buffer.toString('ascii', 8, 12) === 'AVI '
+    ) {
+      return true;
+    }
+
+    // MOV signature (ftyp)
+    if (signature.includes('66747971') || signature.includes('66747970')) {
+      return true;
+    }
+
+    // For other formats, just check if file is large enough to be a video (> 1MB)
+    // This is a basic heuristic since not all video formats have easily detectable headers
+    return stats.size > 1024 * 1024;
   } catch (error) {
-    console.warn(`Failed to validate file ${file}: ${error}`);
+    console.warn(`Error validating video file ${file}: ${error}`);
     return false;
   }
 }
@@ -43,4 +76,4 @@ parentPort?.on('message', (message) => {
       isValid,
     });
   }
-});
+});