Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Graphic pack parser incorrectly parses commas in strings #1200

Closed
splatoon1enjoyer opened this issue May 11, 2024 · 1 comment
Closed

Graphic pack parser incorrectly parses commas in strings #1200

splatoon1enjoyer opened this issue May 11, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@splatoon1enjoyer
Copy link
Contributor

Current Behavior

In graphic pack patches, when defining a string:

.string "Foo ,"

Cemu's parser fails to accept commas as part of the string, which causes this error at runtime:

[20:09:22.680] Line X: Error in assembler: String constants must end with a quotation mark. Example: "text"

This is a problem when writing patches for games such as Splatoon, which have enums hard coded as string literals that get parsed at runtime, requiring the user to use commas as part of the string.

Expected Behavior

The string should be sanitized properly and consider the comma or any other reasonable character as part of the string.

Steps to Reproduce

Define a string with a comma.

System Info (Optional)

No response

Emulation Settings (Optional)

No response

Logs (Optional)

No response

@splatoon1enjoyer splatoon1enjoyer added the bug Something isn't working label May 11, 2024
@goeiecool9999
Copy link
Contributor

goeiecool9999 commented May 11, 2024

I've looked at the code.
From the perspective of cemu's PPC assember it looks like it's a data directive with two arguments: "Foo and ". "Foo doesn't end in a " so it treats it as invalid.

// parse operands
internalInfo.listOperandStr.clear();
while (currentPtr < endPtr)
{
currentPtr++;
startPtr = currentPtr;
// find end of operand
while (currentPtr < endPtr)
{
if (*currentPtr == ',')
break;
currentPtr++;
}
// trim whitespaces at the beginning and end
const char* operandStartPtr = startPtr;
const char* operandEndPtr = currentPtr;
while (operandStartPtr < endPtr)
{
if (*operandStartPtr != ' ' && *operandStartPtr != '\t')
break;
operandStartPtr++;
}
while (operandEndPtr > operandStartPtr)
{
if (operandEndPtr[-1] != ' ' && operandEndPtr[-1] != '\t')
break;
operandEndPtr--;
}
internalInfo.listOperandStr.emplace_back(operandStartPtr, operandEndPtr);
}
// check for data directives
ASM_DATA_DIRECTIVE dataDirective = ASM_DATA_DIRECTIVE::NONE;
if (instructionName.compare(".FLOAT") == 0)
dataDirective = ASM_DATA_DIRECTIVE::FLOAT;
else if (instructionName.compare(".DOUBLE") == 0)
dataDirective = ASM_DATA_DIRECTIVE::DOUBLE;
else if (instructionName.compare(".INT") == 0 || instructionName.compare(".UINT") == 0 || instructionName.compare(".PTR") == 0 || instructionName.compare(".U32") == 0 || instructionName.compare(".LONG") == 0)
dataDirective = ASM_DATA_DIRECTIVE::U32;
else if (instructionName.compare(".WORD") == 0 || instructionName.compare(".U16") == 0 || instructionName.compare(".SHORT") == 0)
dataDirective = ASM_DATA_DIRECTIVE::U16;
else if (instructionName.compare(".BYTE") == 0 || instructionName.compare(".STRING") == 0 || instructionName.compare(".U8") == 0 || instructionName.compare(".CHAR") == 0)
dataDirective = ASM_DATA_DIRECTIVE::U8;
if (dataDirective != ASM_DATA_DIRECTIVE::NONE)
{
if (internalInfo.listOperandStr.size() < 1)
{
ppcAssembler_setError(ctx, fmt::format("Value expected after data directive {}", instructionName.c_str()));
return false;
}
return _ppcAssembler_emitDataDirective(internalInfo, dataDirective);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants