mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-11 11:07:04 +10:00
Multibyte: some path fixes
- Validate encoded path hop counts before saving or sending custom paths - Fix multi-byte path reversal by reversing hops instead of raw bytes - Decode raw log path lengths using packed path_len format - Localize path hash mode options and optimize map anchor lookup
This commit is contained in:
+23
-14
@@ -700,6 +700,16 @@ class _MapScreenState extends State<MapScreen> {
|
||||
int pathHashByteWidth,
|
||||
) {
|
||||
final result = <_GuessedLocation>[];
|
||||
final hopWidth = pathHashByteWidth.clamp(1, 4).toInt();
|
||||
final anchorsByPrefix = <String, List<Contact>>{};
|
||||
for (final repeater in withLocation) {
|
||||
if (repeater.type != advTypeRepeater) continue;
|
||||
if (repeater.publicKey.length < hopWidth) continue;
|
||||
final prefix = PathHelper.formatHopHex(
|
||||
repeater.publicKey.sublist(0, hopWidth),
|
||||
);
|
||||
anchorsByPrefix.putIfAbsent(prefix, () => []).add(repeater);
|
||||
}
|
||||
|
||||
for (final contact in allContacts) {
|
||||
if (contact.hasLocation) continue;
|
||||
@@ -722,21 +732,13 @@ class _MapScreenState extends State<MapScreen> {
|
||||
];
|
||||
for (final pathBytes in pathSets) {
|
||||
if (pathBytes.isEmpty) continue;
|
||||
final hopWidth = pathHashByteWidth.clamp(1, 4);
|
||||
final lastHop = pathBytes.sublist(max(0, pathBytes.length - hopWidth));
|
||||
if (lastHop.isEmpty) continue;
|
||||
|
||||
for (final repeater in withLocation) {
|
||||
if (repeater.type != advTypeRepeater) continue;
|
||||
if (repeater.publicKey.length < lastHop.length) continue;
|
||||
if (!listEquals(
|
||||
repeater.publicKey.sublist(0, lastHop.length),
|
||||
lastHop,
|
||||
)) {
|
||||
continue;
|
||||
}
|
||||
final repeaters = anchorsByPrefix[PathHelper.formatHopHex(lastHop)];
|
||||
if (repeaters != null && repeaters.isNotEmpty) {
|
||||
final repeater = repeaters.first;
|
||||
anchorSet.add(LatLng(repeater.latitude!, repeater.longitude!));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2304,10 +2306,17 @@ class _MapScreenState extends State<MapScreen> {
|
||||
connector.pathHashByteWidth.clamp(1, pubKeySize),
|
||||
contact.publicKey.length,
|
||||
).toInt();
|
||||
final hopPrefix = contact.publicKey.sublist(0, hopWidth);
|
||||
for (final existingHop in PathHelper.splitPathBytes(
|
||||
_pathTrace,
|
||||
connector.pathHashByteWidth,
|
||||
)) {
|
||||
if (listEquals(existingHop, hopPrefix)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
setState(() {
|
||||
_pathTrace.addAll(
|
||||
contact.publicKey.sublist(0, hopWidth),
|
||||
); // Add the hop-width prefix of the public key to the trace
|
||||
_pathTrace.addAll(hopPrefix); // Add the hop-width pubkey prefix.
|
||||
_pathTraceHopWidths.add(hopWidth);
|
||||
_pathTraceContacts.add(
|
||||
contact.copyWith(
|
||||
|
||||
@@ -580,11 +580,23 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
labelText: l10n.repeater_pathHashMode,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
items: const [
|
||||
DropdownMenuItem(value: 0, child: Text('0 - 1 byte')),
|
||||
DropdownMenuItem(value: 1, child: Text('1 - 2 bytes')),
|
||||
DropdownMenuItem(value: 2, child: Text('2 - 3 bytes')),
|
||||
DropdownMenuItem(value: 3, child: Text('3 - 4 bytes')),
|
||||
items: [
|
||||
DropdownMenuItem(
|
||||
value: 0,
|
||||
child: Text(l10n.repeater_pathHashModeOption0),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 1,
|
||||
child: Text(l10n.repeater_pathHashModeOption1),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 2,
|
||||
child: Text(l10n.repeater_pathHashModeOption2),
|
||||
),
|
||||
DropdownMenuItem(
|
||||
value: 3,
|
||||
child: Text(l10n.repeater_pathHashModeOption3),
|
||||
),
|
||||
],
|
||||
onChanged: (value) {
|
||||
if (value == null) return;
|
||||
|
||||
Reference in New Issue
Block a user