fix(#469): broker blank-field GET leaked the echoed key line

extractScalarValue required ' = ' (space-equals-space) and trimRight()'d first,
so a blank field's reply 'key =' (no space after =) failed the match and the
whole 'mqtt.broker.N.field =' line leaked in as the value. Split on the first
'=' and trim instead: blank -> empty, values with '=' preserved. Regression
tests added.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
pull/560/head
Strycher 2 months ago
parent d04bfa82a4
commit 3d6392f39f

@ -241,12 +241,17 @@ class ObserverConfigClient {
} }
} }
/// Extract the value from a scalar reply ("key = value\n" → "value"). /// Extract the value from a scalar reply (`key = value` -> `value`).
/// Falls back to the trimmed whole string if there's no " = ". ///
/// Splits on the FIRST `=` (config keys never contain `=`; values may). A
/// blank field replies `key =` with nothing after the `=`, so the old
/// ` = ` (space-equals-space) match failed and leaked the whole `key =` line
/// as the value (#469). Splitting on `=` and trimming handles blank values
/// (-> empty) and values containing `=` correctly.
static String extractScalarValue(String reply) { static String extractScalarValue(String reply) {
final trimmed = reply.replaceAll('\n', '').trimRight(); final line = reply.replaceAll('\n', '');
final i = trimmed.indexOf(' = '); final i = line.indexOf('=');
return i < 0 ? trimmed : trimmed.substring(i + 3); return i < 0 ? line.trim() : line.substring(i + 1).trim();
} }
/// Read a NUL-terminated UTF-8 string from [f] starting at [start]. /// Read a NUL-terminated UTF-8 string from [f] starting at [start].

@ -208,4 +208,32 @@ void main() {
expect(list, isNull); expect(list, isNull);
}); });
}); });
group('extractScalarValue (#469)', () {
String v(String reply) => ObserverConfigClient.extractScalarValue(reply);
test('blank field returns empty, not the echoed key line', () {
// The bug: a blank field replies "key =" (no space after =); the old
// " = " match failed and leaked the whole line.
expect(v('mqtt.broker.1.iata_override ='), '');
expect(v('mqtt.broker.1.iata_override =\n'), '');
expect(v('mqtt.broker.1.iata_override = '), '');
});
test('normal value extracted', () {
expect(
v('mqtt.broker.0.url = mqtt://mqtt1.okimesh.org:1883\n'),
'mqtt://mqtt1.okimesh.org:1883',
);
expect(v('mqtt.broker.0.enabled = 1'), '1');
});
test('value containing = is preserved (split on first =)', () {
expect(v('mqtt.broker.0.jwt_token = a=b=c'), 'a=b=c');
});
test('no = falls back to the trimmed line', () {
expect(v(' bareword '), 'bareword');
});
});
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.