Skip to content

Fix string overflow in configstrings, replace most info_string usages with std::string#1932

Open
VReaperV wants to merge 17 commits intofor-0.56.0/syncfrom
net-string
Open

Fix string overflow in configstrings, replace most info_string usages with std::string#1932
VReaperV wants to merge 17 commits intofor-0.56.0/syncfrom
net-string

Conversation

@VReaperV
Copy link
Contributor

@VReaperV VReaperV commented Mar 16, 2026

Cgame-side pr: Unvanquished/Unvanquished#3492

The configstring issue can be observed when e. g. the server sets a lot of entries in g_disabledEquipment and g_disabledClasses etc.

MAX_INFO_STRING/BIG_INFO_STRING is now almost entirely unused, and should be fixable without requiring compat-breaking changes after this pr.

@VReaperV VReaperV added T-Bug T-Improvement Improvement for an existing feature labels Mar 16, 2026
@VReaperV VReaperV changed the base branch from master to for-0.56.0/sync March 16, 2026 08:39
@slipher
Copy link
Member

slipher commented Mar 16, 2026

As discussed #1215, the issue with cvars like g_disabledEquipment is not a limitation with configstrings in general (which can be up to 8k), but of the serverinfo string in particular (max 1k). The server info string is received by server browser applications doing "serverstatus" requests, and ideally should have the cvars that are most relevant for someone deciding what server to join. Less relevant cvars can be moved to other info strings. Making the serverinfo string arbitrarily large seems undesirable due to its use in server browsers. We already have a lot of server list issues with server info/status requests not being reliably returned; including huge strings that force the packet to be fragmented could make it worse.

Is there any particular motivation for making reliable commands arbitrarily large as well? The configstrings have a splitting mechanism using bcs commands, which break them into 1k-sized chunks. So large reliable commands shouldn't be required to send configstrings.

@VReaperV
Copy link
Contributor Author

VReaperV commented Mar 16, 2026

As discussed #1215, the issue with cvars like g_disabledEquipment is not a limitation with configstrings in general (which can be up to 8k), but of the serverinfo string in particular (max 1k). The server info string is received by server browser applications doing "serverstatus" requests, and ideally should have the cvars that are most relevant for someone deciding what server to join. Less relevant cvars can be moved to other info strings. Making the serverinfo string arbitrarily large seems undesirable due to its use in server browsers. We already have a lot of server list issues with server info/status requests not being reliably returned; including huge strings that force the packet to be fragmented could make it worse.

Where do you see cvars in the server list?

Is there any particular motivation for making reliable commands arbitrarily large as well? The configstrings have a splitting mechanism using bcs commands, which break them into 1k-sized chunks. So large reliable commands shouldn't be required to send configstrings.

To suggest that fixing an overflow is not a motivation is atrocious.

The configstrings have a splitting mechanism using bcs commands, which break them into 1k-sized chunks. So large reliable commands shouldn't be required to send configstrings.

Clearly it doesn't work. Unlike this pr.

@slipher
Copy link
Member

slipher commented Mar 16, 2026

I don't see any bugs with the current config string code. There is just a deliberately placed restriction on the serverinfo string of maximum length 1k, unlike the other configstrings which have max length 8k. The long configstring transmission code works. You can verify by executing these commands on a server:

set zero1000 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
set timescale 1.$zero1000$$zero1000$

Then run /configstrings (or just /timescale) on the client and you will see that the 2002-byte timescale cvar was transmitted in the systeminfo string.

One can "fix" the server info string, as far as transmitting large data from the server to the client, by changing false to true on

SV_SetConfigstring( CS_SERVERINFO, Cvar_InfoString( CVAR_SERVERINFO, false ) );
. Though additional changes would be needed to handle the larger strings in serverstatus.

Where do you see cvars in the server list?

The detailed server info in the in-game browser is broken or unimplemented currently, but you can see it on some older versions. For example with Unvanquished 0.17 you can click "Server Info" on the server list screen and see the list of cvars.

@illwieckz
Copy link
Member

illwieckz commented Mar 16, 2026

One can inspect the server informations by querying servers using the third-party qstat tool:

$ qstat -json -carets -P -R -unvanquisheds unvanquished.net
[
	{
		"protocol": "unvanquisheds",
		"address": "unvanquished.net",
		"status": "online",
		"hostname": "unvanquished.net",
		"name": "^7[US] ^Dunvanquished.net ^20.55.5 ^9",
		"gametype": "base",
		"map": "perseus",
		"numplayers": 10,
		"maxplayers": 24,
		"numspectators": 0,
		"maxspectators": 0,
		"ping": 126,
		"retries": 0,
		"rules": {
			"B": "-3333333333-------------",
			"P": "-1212121212-------------",
			"contact": "illwieckz",
			"g_BPBudgetPerMiner": "50",
			"g_BPInitialBudget": "80",
			"g_BPInitialBudgetAliens": "-1",
			"g_BPInitialBudgetHumans": "-1",
			"g_BPRecoveryInitialRate": "16",
			"g_BPRecoveryRateHalfLife": "10",
			"g_devolveMaxBaseDistance": "1000",
			"g_maxGameClients": "0",
			"g_momentumHalfLife": "5",
			"g_needpass": "0",
			"g_unlagged": "1",
			"g_unlockableMinTime": "30",
			"gamename": "base",
			"pakname": "map-perseus",
			"protocol": "86",
			"sv_maxRate": "0",
			"sv_privateClients": "0",
			"timelimit": "0",
			"version": "Unvanquished 0.55.5 Linux amd64 Sep 28 2025",
			"version.daemon.abi": "0.55"
		},
		"players": [
			{
				"name": "^9[bot]^1 Morgan",
				"score": 43,
				"ping": 0
			},
			{
				"name": "^9[bot]^4 Adelin",
				"score": 164,
				"ping": 0
			},
			{
				"name": "^9[bot]^1 Uriel",
				"score": 60,
				"ping": 0
			},
			{
				"name": "^9[bot]^4 Alaric",
				"score": 184,
				"ping": 0
			},
			{
				"name": "^9[bot]^1 Belem",
				"score": 100,
				"ping": 0
			},
			{
				"name": "^9[bot]^4 Ferdinand",
				"score": 165,
				"ping": 0
			},
			{
				"name": "^9[bot]^1 Soizic",
				"score": 68,
				"ping": 0
			},
			{
				"name": "^9[bot]^4 Alistair",
				"score": 154,
				"ping": 0
			},
			{
				"name": "^9[bot]^1 Itsaso",
				"score": 61,
				"ping": 0
			},
			{
				"name": "^9[bot]^4 Renan",
				"score": 193,
				"ping": 0
			}
		]
	}
]

The -R switch is what displays what qstats calls the “rules”, so things like g_BPBudgetPerMiner which are cvars as far as I know.

Unvanquished's built-in server browser may be limited, but third-party browser tools like XQF can list those cvars as well.

@sweet235
Copy link
Contributor

Where do you see cvars in the server list?

https://acidtu.be/servers/servers.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

T-Bug T-Improvement Improvement for an existing feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants