Skip to content

Commit

Permalink
refactor: improve timecode handling and error reporting in cue file p…
Browse files Browse the repository at this point in the history
…arsing
  • Loading branch information
N4gtan committed Dec 31, 2024
1 parent f07eb24 commit 2ce3cea
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 28 deletions.
9 changes: 6 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ jobs:
submodules: recursive

- name: Build and package mkpsxiso
run: cmake --workflow ci
run: |
cmake --workflow ci
- name: Upload build artifacts
uses: actions/upload-artifact@v4
Expand All @@ -37,7 +38,8 @@ jobs:
submodules: recursive

- name: Build and package mkpsxiso
run: cmake --workflow ci
run: |
cmake --workflow ci
- name: Upload build artifacts
uses: actions/upload-artifact@v4
Expand All @@ -58,7 +60,8 @@ jobs:
submodules: recursive

- name: Build and package mkpsxiso
run: cmake --workflow ci
run: |
cmake --workflow ci
- name: Upload build artifacts
uses: actions/upload-artifact@v4
Expand Down
2 changes: 1 addition & 1 deletion flac
Submodule flac updated 1 files
+9 −0 src/flac/decode.c
2 changes: 1 addition & 1 deletion src/dumpsxiso/cdreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -409,4 +409,4 @@ void cd::IsoDirEntries::ReadRootDir(cd::IsoReader* reader, int lba)
{
dirEntryList.emplace(std::move(entry.value()));
}
}
}
26 changes: 21 additions & 5 deletions src/dumpsxiso/cue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ CueFile parseCueFile(fs::path& inputFile) {
std::string line, fileType;
fs::ifstream file(inputFile);
fs::path filePath = inputFile;
unsigned int pauseStartSector = 1;
unsigned int previousStartSector = 0;
int lineNumber = 1;
int pauseStartSector = 1;
int previousStartSector = 0;

while (std::getline(file, line)) {
if (line.find("FILE") != std::string::npos) {
Expand Down Expand Up @@ -75,7 +76,12 @@ CueFile parseCueFile(fs::path& inputFile) {
}
else if (line.find("INDEX 00") != std::string::npos) {
size_t timeStart = line.find("INDEX 00") + 9;
pauseStartSector = TimecodeToSectors(line.substr(timeStart, 8));
std::string startTime = line.substr(timeStart, line.find("\r") - timeStart);
pauseStartSector = TimecodeToSectors(startTime);
if (pauseStartSector < 0) {
printf("Error: Invalid cue file timecode \"%s\" on line %d\n", startTime.c_str(), lineNumber);
exit(EXIT_FAILURE);
}

if (pauseStartSector) {
cueFile.tracks[cueFile.tracks.size() - 2].sizeInSectors = pauseStartSector - previousStartSector;
Expand All @@ -84,8 +90,12 @@ CueFile parseCueFile(fs::path& inputFile) {
}
else if (line.find("INDEX 01") != std::string::npos) {
size_t timeStart = line.find("INDEX 01") + 9;
std::string startTime = line.substr(timeStart, 8);
unsigned int startSector = TimecodeToSectors(startTime);
std::string startTime = line.substr(timeStart, line.find("\r") - timeStart);
int startSector = TimecodeToSectors(startTime);
if (startSector < 0) {
printf("Error: Invalid cue file timecode \"%s\" on line %d\n", startTime.c_str(), lineNumber);
exit(EXIT_FAILURE);
}

if (!pauseStartSector) {
startSector = cueFile.tracks[cueFile.tracks.size() - 2].endSector + startSector;
Expand All @@ -96,6 +106,12 @@ CueFile parseCueFile(fs::path& inputFile) {
cueFile.tracks.back().startSector = startSector;
previousStartSector = startSector;
}
else {
printf("Error: Unsupported cue file syntax on line %d\n", lineNumber);
exit(EXIT_FAILURE);
}

lineNumber++;
}

if (!cueFile.tracks.empty()) {
Expand Down
19 changes: 14 additions & 5 deletions src/mkpsxiso/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,10 +601,11 @@ int Main(int argc, char* argv[])
const char *duration = pregapElement->Attribute(xml::attrib::PREGAP_DURATION);
if(duration != nullptr)
{
if((pregapSectors = TimecodeToSectors(duration)) == EXIT_FAILURE)
pregapSectors = TimecodeToSectors(duration);
if(pregapSectors < 0)
{
printf( "ERROR: %s duration is invalid MM:SS:FF"
"for track on line %d.\n", xml::attrib::TRACK_SOURCE, pregapElement->GetLineNum() );
printf( "ERROR: %s duration has invalid MM:SS:FF "
"for track on line %d.\n", xml::elem::TRACK_PREGAP, pregapElement->GetLineNum() );
return EXIT_FAILURE;
}

Expand Down Expand Up @@ -1184,15 +1185,23 @@ int ParseISOfileSystem(const tinyxml2::XMLElement* trackElement, const fs::path&
if ( !gotDateFromXML )
{
// Use local time
const tm imageTime = *gmtime( &global::BuildTime );
const tm imageTime = *localtime( &global::BuildTime );

volumeDate.year = imageTime.tm_year;
volumeDate.month = imageTime.tm_mon + 1;
volumeDate.day = imageTime.tm_mday;
volumeDate.hour = imageTime.tm_hour;
volumeDate.minute = imageTime.tm_min;
volumeDate.second = imageTime.tm_sec;
volumeDate.GMToffs = static_cast<signed char>(-SYSTEM_TIMEZONE / 60.0 / 15.0); // Seconds to 15-minute units
volumeDate.GMToffs = static_cast<signed char>(-SYSTEM_TIMEZONE / 60 / 15); // Seconds to 15-minute units

// Convert volumeDate to const char*
static char dateBuffer[20] {};
snprintf(dateBuffer, sizeof(dateBuffer), "%04hu%02hhu%02hhu%02hhu%02hhu%02hhu00%hhd",
volumeDate.year + 1900, volumeDate.month, volumeDate.day,
volumeDate.hour, volumeDate.minute, volumeDate.second, volumeDate.GMToffs);

isoIdentifiers.CreationDate = dateBuffer;
}

// Parse directory entries in the directory_tree element
Expand Down
24 changes: 12 additions & 12 deletions src/shared/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ ISO_DATESTAMP GetDateFromString(const char* str, bool* success)

ISO_DATESTAMP result {};

short int year;
const int argsRead = sscanf( str, "%04hd%02hhu%02hhu%02hhu%02hhu%02hhu%*02u%hhd",
unsigned short year;
const int argsRead = sscanf( str, "%04hu%02hhu%02hhu%02hhu%02hhu%02hhu%*02hhu%hhd",
&year, &result.month, &result.day,
&result.hour, &result.minute, &result.second, &result.GMToffs );
if (argsRead >= 6)
{
result.year = year != 0 ? year - 1900 : 0;
result.year = year >= 1900 ? year - 1900 : 0;
if (argsRead < 7)
{
// Consider GMToffs optional
Expand Down Expand Up @@ -109,22 +109,22 @@ uint32_t GetSizeInSectors(uint64_t size, uint32_t sectorSize)
return size > 0 ? static_cast<uint32_t>((size + (sectorSize - 1)) / sectorSize) : 1;
}

int32_t TimecodeToSectors(const std::string timecode)
{
unsigned int minutes, seconds, frames;
if (sscanf(timecode.c_str(), "%u:%u:%u", &minutes, &seconds, &frames) != 3 || (minutes > INT_MAX) || (seconds > 59) || (frames > 74)) {
return -1;
}
return (minutes * 60 + seconds) * 75 + frames;
}

std::string SectorsToTimecode(const unsigned sectors)
{
char timecode[16];
snprintf( timecode, sizeof(timecode), "%02u:%02u:%02u", (sectors/75)/60, (sectors/75)%60, sectors%75);
return std::string(timecode);
}

const unsigned int TimecodeToSectors(const std::string timecode)
{
unsigned int minutes, seconds, frames;
if (sscanf(timecode.c_str(), "%u:%u:%u", &minutes, &seconds, &frames) != 3 || (seconds > 59) || (frames > 74)) {
return EXIT_FAILURE;
}
return (minutes * 60 + seconds) * 75 + frames;
}

unsigned short SwapBytes16(unsigned short val)
{
return ((val & 0xFF) << 8) |
Expand Down
2 changes: 1 addition & 1 deletion src/shared/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ std::string LongDateToString(const cd::ISO_LONG_DATESTAMP& src);

// Helper functions for sector conversion
uint32_t GetSizeInSectors(uint64_t size, uint32_t sectorSize = 2048);
int32_t TimecodeToSectors(const std::string timecode);
std::string SectorsToTimecode(const unsigned sectors);
const unsigned int TimecodeToSectors(const std::string timecode);

// Endianness swap
unsigned short SwapBytes16(unsigned short val);
Expand Down

0 comments on commit 2ce3cea

Please sign in to comment.