Skip to content

Commit 3d39892

Browse files
committed
Handle encrypted .gridsetx files in validator
Added support for detecting and handling encrypted .gridsetx files in GridsetValidator, issuing a warning and skipping content validation. Removed the requirement for a wordlists element in gridset files. Updated tests to cover encrypted file handling and the absence of wordlists.
1 parent e01475c commit 3d39892

4 files changed

Lines changed: 57 additions & 18 deletions

File tree

.envrc.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export AZURE_TRANSLATOR_KEY="" # Replace with your Azure Translator key
22
export AZURE_TRANSLATOR_REGION="" # Replace with your Azure Translator region
33
export GOOGLE_TRANSLATE_KEY=""
4-
export GEMINI_API_KEY=""
4+
export GEMINI_API_KEY=""
5+
export GRIDSET_PASSWORD="" # Password for encrypted Grid3 archives (.gridsetx)

examples/.DS_Store

-6 KB
Binary file not shown.

src/validation/gridsetValidator.ts

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,24 @@ export class GridsetValidator extends BaseValidator {
5555
): Promise<ValidationResult> {
5656
this.reset();
5757

58+
const isEncrypted = filename.toLowerCase().endsWith('.gridsetx');
59+
5860
// eslint-disable-next-line @typescript-eslint/require-await
5961
await this.add_check('filename', 'file extension', async () => {
6062
if (!filename.match(/\.gridsetx?$/)) {
6163
this.warn('filename should end with .gridset or .gridsetx');
6264
}
6365
});
6466

67+
// For encrypted .gridsetx files, we can't validate the content
68+
if (isEncrypted) {
69+
// eslint-disable-next-line @typescript-eslint/require-await
70+
await this.add_check('encrypted_format', 'encrypted gridsetx file', async () => {
71+
this.warn('gridsetx files are encrypted and cannot be fully validated');
72+
});
73+
return this.buildResult(filename, filesize, 'gridset');
74+
}
75+
6576
let xmlObj: any = null;
6677
await this.add_check('xml_parse', 'valid XML', async () => {
6778
try {
@@ -97,7 +108,7 @@ export class GridsetValidator extends BaseValidator {
97108
*/
98109
private async validateGridsetStructure(
99110
gridset: any,
100-
filename: string,
111+
_filename: string,
101112
_content: Buffer | Uint8Array
102113
): Promise<void> {
103114
// Check for required elements
@@ -171,22 +182,6 @@ export class GridsetValidator extends BaseValidator {
171182
this.warn('gridset should have a styles element for consistent formatting');
172183
}
173184
});
174-
175-
// Check for wordlists
176-
await this.add_check('wordlists', 'wordlists element', async () => {
177-
const wordlists = gridset.wordlists || gridset.Wordlists;
178-
if (!wordlists) {
179-
this.warn('gridset should have a wordlists element for vocabulary support');
180-
}
181-
});
182-
183-
// Validate file references if it's a .gridsetx file (encrypted)
184-
if (filename.endsWith('.gridsetx')) {
185-
await this.add_check('encrypted_format', 'encrypted gridsetx', async () => {
186-
// Gridsetx files are encrypted, so we can't validate much
187-
this.warn('gridsetx files are encrypted and cannot be fully validated');
188-
});
189-
}
190185
}
191186

192187
/**

test/validation.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,49 @@ describe('Validation System', () => {
183183

184184
expect(result.valid).toBe(false);
185185
});
186+
187+
it('should handle encrypted .gridsetx files', async () => {
188+
// .gridsetx files are encrypted, so we just validate the extension
189+
const encryptedContent = Buffer.from('encrypted binary data');
190+
const result = await new GridsetValidator().validate(
191+
encryptedContent,
192+
'test.gridsetx',
193+
encryptedContent.length
194+
);
195+
196+
expect(result).toBeDefined();
197+
expect(result.format).toBe('gridset');
198+
// Should have warning about encryption
199+
const hasEncryptionWarning = result.results.some(
200+
(r) => r.type === 'encrypted_format' && r.warnings && r.warnings.length > 0
201+
);
202+
expect(hasEncryptionWarning).toBe(true);
203+
});
204+
205+
it('should not require wordlists element', async () => {
206+
const gridsetWithoutWordlists = `<?xml version="1.0" encoding="utf-8"?>
207+
<gridset id="test" name="Test Gridset">
208+
<pages>
209+
<page id="page1" name="Page 1">
210+
<cells>
211+
<cell id="cell1" label="Hello"/>
212+
</cells>
213+
</page>
214+
</pages>
215+
<fixedCellSize width="100" height="100"/>
216+
</gridset>`;
217+
218+
const content = Buffer.from(gridsetWithoutWordlists);
219+
const result = await new GridsetValidator().validate(content, 'test.gridset', content.length);
220+
221+
expect(result).toBeDefined();
222+
expect(result.format).toBe('gridset');
223+
// Should NOT have warning about missing wordlists
224+
const hasWordlistsWarning = result.results.some(
225+
(r) => r.type === 'wordlists' && r.warnings && r.warnings.length > 0
226+
);
227+
expect(hasWordlistsWarning).toBe(false);
228+
});
186229
});
187230

188231
describe('SnapValidator', () => {

0 commit comments

Comments
 (0)