@vizzly-testing/cli 0.22.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -45,9 +45,10 @@ export function createScreenshotRouter({
45
45
  return true;
46
46
  } catch (error) {
47
47
  output.debug('Screenshot processing error:', {
48
- error: error.message
48
+ error: error.message,
49
+ stack: error.stack
49
50
  });
50
- sendError(res, 500, 'Failed to process screenshot');
51
+ sendError(res, 500, `Failed to process screenshot: ${error.message}`);
51
52
  return true;
52
53
  }
53
54
  }
@@ -11,7 +11,7 @@ import { platform } from 'node:os';
11
11
  * @param {string} url - URL to validate
12
12
  * @returns {boolean} True if safe
13
13
  */
14
- function isValidUrl(url) {
14
+ export function isValidBrowserUrl(url) {
15
15
  if (typeof url !== 'string' || url.length === 0) {
16
16
  return false;
17
17
  }
@@ -28,7 +28,7 @@ function isValidUrl(url) {
28
28
  */
29
29
  export async function openBrowser(url) {
30
30
  // Validate URL to prevent command injection
31
- if (!isValidUrl(url)) {
31
+ if (!isValidBrowserUrl(url)) {
32
32
  return false;
33
33
  }
34
34
  return new Promise(resolve => {
@@ -27,17 +27,32 @@ export function isBase64(str) {
27
27
  // Strip data URI prefix if present (e.g., data:image/png;base64,...)
28
28
  let base64Content = str;
29
29
  if (str.startsWith('data:')) {
30
- const match = str.match(/^data:[a-zA-Z0-9+/.-]+;base64,(.+)$/);
30
+ let match = str.match(/^data:[a-zA-Z0-9+/.-]+;base64,(.+)$/);
31
31
  if (!match) {
32
32
  return false; // Has data: prefix but invalid format
33
33
  }
34
34
  base64Content = match[1];
35
35
  }
36
36
 
37
- // Base64 regex: groups of 4 chars [A-Za-z0-9+/], with optional padding
38
- // Valid endings: no padding, or 2/3 chars + padding (= or ==)
39
- const base64Pattern = /^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
40
- return base64Pattern.test(base64Content);
37
+ // Quick check: base64 only contains these characters
38
+ // Use a simple character class check instead of a complex regex to avoid
39
+ // catastrophic backtracking on large strings
40
+ if (!/^[A-Za-z0-9+/=]+$/.test(base64Content)) {
41
+ return false;
42
+ }
43
+
44
+ // Check length is valid (must be multiple of 4, accounting for padding)
45
+ let len = base64Content.length;
46
+ if (len % 4 !== 0) {
47
+ return false;
48
+ }
49
+
50
+ // Check padding is valid (only at end, max 2 = chars)
51
+ let paddingMatch = base64Content.match(/=+$/);
52
+ if (paddingMatch && paddingMatch[0].length > 2) {
53
+ return false;
54
+ }
55
+ return true;
41
56
  }
42
57
 
43
58
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vizzly-testing/cli",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "description": "Visual review platform for UI developers and designers",
5
5
  "keywords": [
6
6
  "visual-testing",
@@ -87,7 +87,8 @@
87
87
  "registry": "https://registry.npmjs.org/"
88
88
  },
89
89
  "dependencies": {
90
- "@vizzly-testing/honeydiff": "^0.7.1",
90
+ "@vizzly-testing/honeydiff": "^0.8.0",
91
+ "@vizzly-testing/static-site": "^0.0.11",
91
92
  "ansis": "^4.2.0",
92
93
  "commander": "^14.0.0",
93
94
  "cosmiconfig": "^9.0.0",