compiler bug: comma inside string as a macro parameter throws an error
Let's say we have a plugin like this:
#include <sourcemod>
enum struct ConVarInfo {
ConVar cvar;
char values[32];
char type[10];
}
enum struct ModeInfo {
ConVarInfo cvarInfo[10];
}
#define DECLARE_FM_CVAR(%1,%2,%3,%4,%5,%6,%7) \
%1[%2].cvar = CreateConVar(%3, %4, %5); \
%1[%2].values = %6; \
%1[%2].type = %7
public void OnPluginStart()
{
ModeInfo info;
DECLARE_FM_CVAR(
info.cvarInfo, 0,
"sm_beacon_timer", "20.0", "The time that will start picking random players at round start",
"20.0,30.0,40.0,60.0", "float"
);
}
Throws the errors:
TestPlugin.sp(20) : error 001: expected token: ")", but found ","
20 | DECLARE_FM_CVAR(
------------------------------^
TestPlugin.sp(20) : error 037: invalid string (possibly non-terminated string)
20 | DECLARE_FM_CVAR(
-----------------^
TestPlugin.sp(20) : error 010: invalid function or declaration
20 | DECLARE_FM_CVAR(
Wrapping the string "20.0,30.0,40.0,60.0" in parentheses or declaring a variable solves the problem
My compiler version: SourcePawn Compiler 1.12.0.7210 Copyright (c) 1997-2006 ITB CompuPhase Copyright (c) 2004-2024 AlliedModders LLC
On master, just this recurses till it crashes as long as the comma is there:
#define test(%1) foo(%1)
public void main() {
test("a,b");
}
Starting from here in parse_call: https://github.com/alliedmodders/sourcepawn/blob/3fbc68a7e967b0f2a6c7befbde8f384b1a5c0028/compiler/parser.cpp#L1081
It flows all the way down to primary here: https://github.com/alliedmodders/sourcepawn/blob/3fbc68a7e967b0f2a6c7befbde8f384b1a5c0028/compiler/parser.cpp#L987
And it keeps repeating, taking the match('(') path.
Another example of how the bug occurs: Passing a string with unclosed bracket to a macro breaks the code For example:
DECLARE_FM_CVAR(
THIS_MODE_INFO.cvarInfo, RLGL_CONVAR_TIME_BETWEEN_REDLIGHTS_MAX,
"sm_rlgl_time_between_redlights_max", "30.0", "After how many seconds to keep repeating the redlights (MAX VALUE, SET TO 0 to disable min/max",
("25.0,35.0,45.0,65.0"), "float"
);
Throws the errors:
Fun_Modes\RedLightGreenLight.sp(62) : error 030: compound statement not closed at the end of file (started at line 38)
62 | );
-----------------^
Fun_Modes\RedLightGreenLight.sp(62) : error 036: empty statement
62 | );
------------------^
Fun_Modes\RedLightGreenLight.sp(440) : error 001: expected token: ",", but found ""
440 | }
----------^
The description string has an unclosed (, the code breaks at this point, the fix would be to close it.
There would not be any need to wrap the string in parentheses or making a variable for it because it would not complain about the errors in the issue's first comment.