Skip to content

Commit

Permalink
Fix: protections against self-closing tags in XML DATs (#569)
Browse files Browse the repository at this point in the history
  • Loading branch information
emmercm authored Aug 14, 2023
1 parent 6d4e249 commit f46cf5b
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/modules/datScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ export default class DATScanner extends Scanner {
let xmlObject: DataFile;
try {
xmlObject = await xml2js.parseStringPromise(fileContents, {
emptyTag: undefined,
mergeAttrs: true,
explicitArray: false,
});
Expand Down
19 changes: 14 additions & 5 deletions src/types/logiqx/dat.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'reflect-metadata';

import { Expose, plainToInstance, Type } from 'class-transformer';
import {
Expose, plainToInstance, Transform, Type,
} from 'class-transformer';
import xml2js from 'xml2js';

import Game from './game.js';
Expand All @@ -14,15 +16,18 @@ import Parent from './parent.js';
export default class DAT {
@Expose()
@Type(() => Header)
@Transform(({ value }) => value || undefined)
private readonly header: Header;

@Expose()
@Type(() => Game)
@Transform(({ value }) => value || [])
private readonly game: Game | Game[];

// NOTE(cemmer): this is not Logiqx DTD-compliant, but it's what MAME XML DATs use
@Expose()
@Type(() => Machine)
@Transform(({ value }) => value || [])
private readonly machine: Machine | Machine[];

private readonly gameNamesToParents: Map<string, Parent> = new Map();
Expand Down Expand Up @@ -93,14 +98,18 @@ export default class DAT {

getGames(): Game[] {
if (Array.isArray(this.game)) {
return this.game;
} if (this.game) {
if (this.game.length) {
return this.game;
}
} else if (this.game) {
return [this.game];
}

if (Array.isArray(this.machine)) {
return this.machine;
} if (this.machine) {
if (this.machine) {
return this.machine;
}
} else if (this.machine) {
return [this.machine];
}

Expand Down
4 changes: 3 additions & 1 deletion src/types/logiqx/game.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'reflect-metadata';

import { Expose, Type } from 'class-transformer';
import { Expose, Transform, Type } from 'class-transformer';

import Internationalization from '../internationalization.js';
import Archive from './archive.js';
Expand Down Expand Up @@ -106,10 +106,12 @@ export default class Game implements GameProps {

@Expose()
@Type(() => Release)
@Transform(({ value }) => value || [])
readonly release: Release | Release[];

@Expose()
@Type(() => ROM)
@Transform(({ value }) => value || [])
readonly rom: ROM | ROM[];

constructor(options?: GameProps) {
Expand Down
3 changes: 2 additions & 1 deletion src/types/logiqx/header.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'reflect-metadata';

import { Expose, Type } from 'class-transformer';
import { Expose, Transform, Type } from 'class-transformer';

import ClrMamePro from './clrMamePro.js';

Expand Down Expand Up @@ -72,6 +72,7 @@ export default class Header implements HeaderOptions {

@Type(() => ClrMamePro)
@Expose({ name: 'clrmamepro' })
@Transform(({ value }) => value || undefined)
readonly clrMamePro?: ClrMamePro;

readonly romNamesContainDirectories: boolean = true;
Expand Down

0 comments on commit f46cf5b

Please sign in to comment.