Skip to content

Commit

Permalink
patched issue 209: #209
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpreynolds committed Apr 6, 2020
1 parent 848179f commit f8e14ed
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 13 deletions.
17 changes: 4 additions & 13 deletions applications/bed/starch/src/unstarch.c
Expand Up @@ -268,22 +268,13 @@ main(int argc, char **argv)
else if (resultValue == UNSTARCH_IS_STARCH_ARCHIVE_ERROR)
{
/* we suppress warnings from STARCH_readJSONMetadata() */
if (STARCH_readJSONMetadata( &metadataJSON,
&inFilePtr,
if (STARCH_JSONMetadataExists( &inFilePtr,
#ifdef __cplusplus
reinterpret_cast<const char *>( inFile ),
reinterpret_cast<const char *>( inFile )
#else
(const char *) inFile,
(const char *) inFile
#endif
&records,
&type,
&archiveVersion,
&archiveTimestamp,
&note,
&metadataOffset,
&headerFlag,
kStarchTrue,
kStarchTrue) != STARCH_EXIT_SUCCESS) {
) != STARCH_EXIT_SUCCESS) {
fprintf(stdout, "0\n"); /* false -- no valid metadata, therefore not a starch archive */
return EXIT_SUCCESS;
}
Expand Down
4 changes: 4 additions & 0 deletions docs/content/revision-history.rst
Expand Up @@ -21,6 +21,10 @@ Released: **April 6, 2020**

* Patched :code:`--unique` to report output identical to :code:`sort -u`, in order to resolve `Issue 236 <https://github.com/bedops/bedops/issues/236>`_.

* :ref:`unstarch <unstarch>`

* Patched :code:`--is-starch` test option to read only up to, at most, 8kb to check for v2 or v1 (legacy) Starch archive data, to resolve `Issue 209 <https://github.com/bedops/bedops/issues/209>`_.

* General

* Updated main :code:`Makefile` to use `Homebrew <https://brew.sh/>`_ GNU :code:`coreutils` and :code:`findutils` tools on the OS X target. If you build BEDOPS on OS X, you can add these tools with :code:`brew install coreutils findutils`.
Expand Down
Expand Up @@ -244,6 +244,9 @@ char * STARCH_generateJSONMetadata(const Metadata *md,
const char *note,
const Boolean headerFlag);

int STARCH_JSONMetadataExists(FILE **fp,
const char *fn);

int STARCH_readJSONMetadata(json_t **metadataJSON,
FILE **fp,
const char *fn,
Expand Down
91 changes: 91 additions & 0 deletions interfaces/src/data/starch/starchMetadataHelpers.c
Expand Up @@ -1025,6 +1025,97 @@ STARCH_writeJSONMetadata(const Metadata *md,
return STARCH_EXIT_SUCCESS;
}

int
STARCH_JSONMetadataExists(FILE **fp,
const char *fn)
{
#ifdef DEBUG
fprintf(stderr, "\n--- STARCH_JSONMetadataExists() ---\n");
#endif
size_t nReadBytes;
size_t idxBytes;
unsigned char starchRevision2HeaderTestBytes[sizeof(starchRevision2HeaderBytes)] = {0};
char testMagicBuffer[STARCH_TEST_BYTE_COUNT] = {0};
char currC = '\0';
char prevC = '\0';
char legacyBuffer[STARCH_LEGACY_METADATA_SIZE] = {0};
json_error_t jsonParseError;
json_t *metadataJSON = NULL;

if (! *fp) {
*fp = STARCH_fopen(fn, "rbR");
}
if (! *fp) {
return STARCH_EXIT_FAILURE;
}
/*
Read first four bytes to test if it has v2 Starch
file magic bytes
*/
nReadBytes = fread(starchRevision2HeaderTestBytes, sizeof(unsigned char), sizeof(starchRevision2HeaderBytes), *fp);
if (nReadBytes != (sizeof(unsigned char) * sizeof(starchRevision2HeaderBytes))) {
fprintf(stderr, "ERROR: Total amount of bytes read not equal to Starch magic byte header length. Check file length.\n");
return STARCH_EXIT_FAILURE;
}
if (memcmp(starchRevision2HeaderTestBytes, starchRevision2HeaderBytes, sizeof(starchRevision2HeaderBytes)) == 0) {
return STARCH_EXIT_SUCCESS;
}
/*
If four bytes are not v2 Starch magic bytes, test if a
JSON entity is found in first STARCH_LEGACY_METADATA_SIZE
bytes (8k) or until we reach EOF (possibly early, for a
short file).
*/
STARCH_fseeko(*fp, 0, SEEK_SET);
nReadBytes = 0;
do {
#ifdef __cplusplus
currC = static_cast<char>( fgetc(*fp) );
#else
currC = (char) fgetc(*fp);
#endif
fprintf(stderr, "currC [%zu] [%c]\n", nReadBytes, currC);
if ((prevC == currC) && (currC == '\n')) {
break;
}
else {
legacyBuffer[nReadBytes++] = currC;
prevC = currC;
}
if ((nReadBytes >= STARCH_TEST_BYTE_COUNT) && (nReadBytes < (STARCH_LEGACY_METADATA_SIZE - STARCH_TEST_BYTE_COUNT))) {
for (idxBytes = 0; idxBytes < STARCH_TEST_BYTE_COUNT; idxBytes++) {
testMagicBuffer[idxBytes] = legacyBuffer[nReadBytes - STARCH_TEST_BYTE_COUNT + idxBytes];
}
if ((memcmp(testMagicBuffer, bzip2MagicBytes, sizeof(bzip2MagicBytes) - 1) == 0) || (memcmp(testMagicBuffer, gzipMagicBytes, sizeof(gzipMagicBytes) - 1) == 0)) {
break;
}
}
if (nReadBytes == STARCH_LEGACY_METADATA_SIZE) {
break;
}
} while (currC != EOF);
if ((nReadBytes == STARCH_LEGACY_METADATA_SIZE) || (currC == EOF)) {
return STARCH_EXIT_FAILURE;
}
legacyBuffer[nReadBytes - STARCH_TEST_BYTE_COUNT] = '\0'; /* trim string */

/*
Attempt to turn legacy buffer into JSON entity.
*/
metadataJSON = json_loads(legacyBuffer, JSON_DISABLE_EOF_CHECK, &jsonParseError);
if (!metadataJSON) {
fprintf(stderr, "ERROR: JSON parsing error on line %d: %s\n", jsonParseError.line, jsonParseError.text);
return STARCH_EXIT_FAILURE;
}
/*
If we got this far, we have a JSON entity in the
file, so it could be a v1 Starch archive. We don't
check too stringently, because these types of
archives are no longer supported.
*/
return STARCH_EXIT_SUCCESS;
}

int
STARCH_readJSONMetadata(json_t **metadataJSON,
FILE **fp,
Expand Down

0 comments on commit f8e14ed

Please sign in to comment.