Simplify IS-CAD footer scanning code

This commit is contained in:
Garhoogin 2025-06-02 20:04:52 -05:00 committed by GitHub
parent 43554ae349
commit befbe9eb06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 61 additions and 85 deletions

View File

@ -87,49 +87,21 @@ int ChrIsValidNcg(const unsigned char *buffer, unsigned int size) {
} }
static int ChriIsCommonScanFooter(const unsigned char *buffer, unsigned int size, int type) { static int ChriIsCommonScanFooter(const unsigned char *buffer, unsigned int size, int type) {
if (size < 8) return -1; //scan for footer with these required blocks
const char *const requiredBlocks[] = { "LINK", "CMNT", "MODE", "SIZE", "VER ", "END " };
int offs = IscadScanFooter(buffer, size, requiredBlocks, sizeof(requiredBlocks) / sizeof(requiredBlocks[0]));
if (offs == -1) return -1;
//scan for possible locations of the footer unsigned int footerSize = size - (unsigned int) offs;
for (unsigned int i = 0; i < size - 8; i++) { const unsigned char *footer = buffer + offs;
if (buffer[i] != 'L') continue;
if (memcmp(buffer + i, "LINK", 4) != 0) continue;
//candidate location
int hasLink = 0, hasCmnt = 0, hasMode = 0, hasSize = 0, hasVer = 0, hasEnd = 0;
//scan sections //check blocks
unsigned int offset = i; unsigned int verSize;
while (1) { const unsigned char *verBlock = IscadFindBlockBySignature(footer, footerSize, "VER ", &verSize);
const unsigned char *section = buffer + offset;
unsigned int length = *(uint32_t *) (buffer + offset + 4);
offset += 8;
if (memcmp(section, "LINK", 4) == 0) hasLink = 1; if (type == NCGR_TYPE_AC && (verSize < 8 || memcmp(verBlock, "IS-ACG", 6))) return -1; // ASC must have version IS-ACGxx
else if (memcmp(section, "CMNT", 4) == 0) hasCmnt = 1; if (type == NCGR_TYPE_IC && (verSize < 8 || memcmp(verBlock, "IS-ICG", 6))) return -1; // ISC must have version IS-ICGxx
else if (memcmp(section, "MODE", 4) == 0) hasMode = 1; return offs;
else if (memcmp(section, "SIZE", 4) == 0) hasSize = 1;
else if (memcmp(section, "VER ", 4) == 0) hasVer = 1;
else if (memcmp(section, "END ", 4) == 0) hasEnd = 1;
if (memcmp(section, "VER ", 4) == 0) {
//ACG: ver = "IS-ACG0x" (1-3)
//ICG: ver = "IS-ICG01"
const char *ver = section + 8;
if (type == NCGR_TYPE_AC && (length < 8 || memcmp(ver, "IS-ACG", 6))) return -1;
if (type == NCGR_TYPE_IC && (length < 8 || memcmp(ver, "IS-ICG", 6))) return -1;
}
offset += length;
if (offset >= size) break;
if (hasEnd) break;
}
if (hasLink && hasCmnt && hasMode && hasSize && hasVer && hasEnd && offset <= size) {
//candidate found
return i;
}
}
return -1;
} }
int ChrIsValidAcg(const unsigned char *buffer, unsigned int size) { int ChrIsValidAcg(const unsigned char *buffer, unsigned int size) {

View File

@ -709,6 +709,9 @@ int IscadIsValidFooter(const unsigned char *footer, unsigned int size) {
if ((size - pos) < blockSize) return 0; if ((size - pos) < blockSize) return 0;
pos += blockSize; pos += blockSize;
//check for 'END ' signature
if (memcmp(hdr, "END ", 4) == 0) break;
} }
return 1; return 1;
} }
@ -728,10 +731,40 @@ unsigned char *IscadFindBlockBySignature(const unsigned char *buffer, unsigned i
pos += 8; pos += 8;
unsigned int blockSize = *(const uint32_t *) (hdr + 4); unsigned int blockSize = *(const uint32_t *) (hdr + 4);
pos += blockSize; pos += blockSize;
//check for 'END ' signature
if (memcmp(hdr, "END ", 4) == 0) break;
} }
return NULL; return NULL;
} }
int IscadScanFooter(const unsigned char *buffer, unsigned int size, const char *const *requiredBlocks, unsigned int nRequiredBlocks) {
//scan for locations, check for required blocks.
for (unsigned int i = 0; i < size; i++) {
//check valid footer data
if (!IscadIsValidFooter(buffer + i, size - i)) continue;
//check required blocks
int foundAll = 1;
for (unsigned int j = 0; j < nRequiredBlocks; j++) {
unsigned int blockSize;
const unsigned char *block = IscadFindBlockBySignature(buffer + i, size - i, requiredBlocks[j], &blockSize);
if (block == NULL) {
foundAll = 0;
break;
}
}
//buffer here
if (foundAll) {
return (int) i;
}
}
//not found
return -1;
}
void IscadStreamCreate(IscadStream *stream) { void IscadStreamCreate(IscadStream *stream) {
stream->inFooter = 0; stream->inFooter = 0;
@ -747,7 +780,7 @@ void IscadStreamStartBlock(IscadStream *stream, const char *signature) {
stream->blockStart = stream->stream.pos; stream->blockStart = stream->stream.pos;
uint32_t tmpSize = 0; uint32_t tmpSize = 0;
bstreamWrite(&stream->stream, signature, 4); bstreamWrite(&stream->stream, (void *) signature, 4);
bstreamWrite(&stream->stream, &tmpSize, sizeof(tmpSize)); bstreamWrite(&stream->stream, &tmpSize, sizeof(tmpSize));
} }

View File

@ -74,6 +74,7 @@ void NnsStreamFree(NnsStream *stream);
// ----- ISCAD stream functions // ----- ISCAD stream functions
int IscadScanFooter(const unsigned char *buffer, unsigned int size, const char *const *requiredBlocks, unsigned int nRequiredBlocks);
int IscadIsValidFooter(const unsigned char *footer, unsigned int size); int IscadIsValidFooter(const unsigned char *footer, unsigned int size);
unsigned char *IscadFindBlockBySignature(const unsigned char *buffer, unsigned int size, const char *signature, unsigned int *pSize); unsigned char *IscadFindBlockBySignature(const unsigned char *buffer, unsigned int size, const char *signature, unsigned int *pSize);

View File

@ -210,53 +210,23 @@ int ScrIsValidNsc(const unsigned char *buffer, unsigned int size) {
} }
int ScriIsCommonScanFooter(const unsigned char *buffer, unsigned int size, int type) { int ScriIsCommonScanFooter(const unsigned char *buffer, unsigned int size, int type) {
if (size < 8) return -1; //scan for a footer with the required blocks
const char *requiredBlocks[] = { "CLRF", "LINK", "CMNT", "CLRC", "MODE", "VER ", "END " };
int offs = IscadScanFooter(buffer, size, requiredBlocks, sizeof(requiredBlocks) / sizeof(requiredBlocks[0]));
if (offs == -1) return -1;
//scan for possible locations of the footer unsigned int footerSize = size - (unsigned int) offs;
for (unsigned int i = 0; i < size - 8; i++) { const unsigned char *footer = buffer + offs;
if (buffer[i] != 'C') continue;
if (memcmp(buffer + i, "CLRF", 4) != 0) continue;
//candidate location //check blocks
int hasClrf = 0, hasLink = 0, hasCmnt = 0, hasClrc = 0, hasMode = 0, hasVer = 0, hasEnd = 0, hasSize = 0; unsigned int verSize, sizeSize;
const unsigned char *verBlock = IscadFindBlockBySignature(footer, footerSize, "VER ", &verSize);
const unsigned char *sizeBlock = IscadFindBlockBySignature(footer, footerSize, "SIZE", &sizeSize);
//scan sections if (type == NSCR_TYPE_AC && (verSize < 8 || memcmp(verBlock, "IS-ASC", 6))) return -1; // ASC must have version IS-ASCxx
unsigned int offset = i; if (type == NSCR_TYPE_IC && (verSize < 8 || memcmp(verBlock, "IS-ISC", 6))) return -1; // ISC must have version IS-ISCxx
while (1) { if (type == NSCR_TYPE_IC && sizeBlock == NULL) return -1; // ISC must have a SIZE block
const char *section = buffer + offset; return offs;
unsigned int length = *(unsigned int *) (buffer + offset + 4);
offset += 8;
if (memcmp(section, "CLRF", 4) == 0) hasClrf = 1;
else if (memcmp(section, "LINK", 4) == 0) hasLink = 1;
else if (memcmp(section, "CMNT", 4) == 0) hasCmnt = 1;
else if (memcmp(section, "CLRC", 4) == 0) hasClrc = 1;
else if (memcmp(section, "MODE", 4) == 0) hasMode = 1;
else if (memcmp(section, "SIZE", 4) == 0) hasSize = 1;
else if (memcmp(section, "VER ", 4) == 0) hasVer = 1;
else if (memcmp(section, "END ", 4) == 0) hasEnd = 1;
if (memcmp(section, "VER ", 4) == 0) {
//ACG: ver = "IS-ACG0x" (1-3)
//ICG: ver = "IS-ICG01"
const char *ver = section + 8;
if (type == NSCR_TYPE_AC && (length < 8 || memcmp(ver, "IS-ASC", 6))) return -1;
if (type == NSCR_TYPE_IC && (length < 8 || memcmp(ver, "IS-ISC", 6))) return -1;
}
offset += length;
if (offset >= size) break;
if (hasEnd) break;
}
//ISC files have a SIZE section, but ASC files do not
int sizeSatisfied = (type == NSCR_TYPE_IC && hasSize) || (type != NSCR_TYPE_IC);
if (hasClrf && hasLink && hasCmnt && hasClrc && hasMode && sizeSatisfied && hasVer && hasEnd && offset <= size) {
//candidate found
return i;
}
}
return -1;
} }
int ScrIsValidAsc(const unsigned char *file, unsigned int size) { int ScrIsValidAsc(const unsigned char *file, unsigned int size) {