Skip to content

Commit df329c6

Browse files
committed
Better Phantasma Link argument data validation
1 parent d7f50e2 commit df329c6

File tree

2 files changed

+116
-70
lines changed

2 files changed

+116
-70
lines changed

Phantasma.Domain/WalletLink.cs

+88-58
Original file line numberDiff line numberDiff line change
@@ -249,24 +249,31 @@ public void Execute(string cmd, Action<int, DataNode, bool> callback)
249249
{
250250
if (args.Length == 5)
251251
{
252-
var data = Base16.Decode(args[3]);
253-
var signatureKind = (SignatureKind) Enum.Parse(typeof(SignatureKind), args[4], true);
254-
255-
SignData(data, signatureKind, id, (signature, random, txError) => {
256-
if (signature != null)
257-
{
258-
success = true;
259-
answer = APIUtils.FromAPIResult(new Signature() { signature = signature, random = random });
260-
}
261-
else
262-
{
263-
answer = APIUtils.FromAPIResult(new Error() { message = txError });
264-
}
252+
var data = Base16.Decode(args[3], false);
253+
if (data == null)
254+
{
255+
answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid input received" });
256+
}
257+
else
258+
{
259+
var signatureKind = (SignatureKind)Enum.Parse(typeof(SignatureKind), args[4], true);
265260

266-
callback(id, answer, success);
267-
_isPendingRequest = false;
268-
});
261+
SignData(data, signatureKind, id, (signature, random, txError) => {
262+
if (signature != null)
263+
{
264+
success = true;
265+
answer = APIUtils.FromAPIResult(new Signature() { signature = signature, random = random });
266+
}
267+
else
268+
{
269+
answer = APIUtils.FromAPIResult(new Error() { message = txError });
270+
}
269271

272+
callback(id, answer, success);
273+
_isPendingRequest = false;
274+
});
275+
}
276+
270277
return;
271278
}
272279
else
@@ -287,23 +294,31 @@ public void Execute(string cmd, Action<int, DataNode, bool> callback)
287294
{
288295
var nexus = args[1];
289296
var chain = args[2];
290-
var script = Base16.Decode(args[3]);
291-
byte[] payload = args[4].Length > 0 ? Base16.Decode(args[4]): null;
297+
var script = Base16.Decode(args[3], false);
292298

293-
SignTransaction(nexus, chain, script, payload, id, (hash, txError) => {
294-
if (hash != Hash.Null)
295-
{
296-
success = true;
297-
answer = APIUtils.FromAPIResult(new Transaction() { hash = hash.ToString() });
298-
}
299-
else
300-
{
301-
answer = APIUtils.FromAPIResult(new Error() { message = txError });
302-
}
299+
if (script == null)
300+
{
301+
answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid script data" });
302+
}
303+
else
304+
{
305+
byte[] payload = args[4].Length > 0 ? Base16.Decode(args[4], false) : null;
303306

304-
callback(id, answer, success);
305-
_isPendingRequest = false;
306-
});
307+
SignTransaction(nexus, chain, script, payload, id, (hash, txError) => {
308+
if (hash != Hash.Null)
309+
{
310+
success = true;
311+
answer = APIUtils.FromAPIResult(new Transaction() { hash = hash.ToString() });
312+
}
313+
else
314+
{
315+
answer = APIUtils.FromAPIResult(new Error() { message = txError });
316+
}
317+
318+
callback(id, answer, success);
319+
_isPendingRequest = false;
320+
});
321+
}
307322

308323
return;
309324
}
@@ -323,24 +338,31 @@ public void Execute(string cmd, Action<int, DataNode, bool> callback)
323338
{
324339
if (args.Length == 4)
325340
{
326-
var script = Base16.Decode(args[1]);
341+
var script = Base16.Decode(args[1], false);
327342

328-
InvokeScript(script, id, (invokeResult, invokeError) =>
343+
if (script == null)
329344
{
330-
if (invokeResult != null)
331-
{
332-
success = true;
333-
answer = APIUtils.FromAPIResult(new Invocation() { result = Base16.Encode(invokeResult) });
334-
}
335-
else
345+
answer = APIUtils.FromAPIResult(new Error() { message = $"signTx: Invalid script data" });
346+
}
347+
else
348+
{
349+
InvokeScript(script, id, (invokeResult, invokeError) =>
336350
{
337-
answer = APIUtils.FromAPIResult(new Error() { message = invokeError });
338-
}
351+
if (invokeResult != null)
352+
{
353+
success = true;
354+
answer = APIUtils.FromAPIResult(new Invocation() { result = Base16.Encode(invokeResult) });
355+
}
356+
else
357+
{
358+
answer = APIUtils.FromAPIResult(new Error() { message = invokeError });
359+
}
339360

340-
callback(id, answer, success);
341-
_isPendingRequest = false;
342-
});
343-
return;
361+
callback(id, answer, success);
362+
_isPendingRequest = false;
363+
});
364+
return;
365+
}
344366
}
345367
else
346368
{
@@ -360,23 +382,31 @@ public void Execute(string cmd, Action<int, DataNode, bool> callback)
360382
{
361383
var archiveHash = Hash.Parse(args[1]);
362384
var blockIndex = int.Parse(args[2]);
363-
var bytes = Base16.Decode(args[3]);
385+
var bytes = Base16.Decode(args[3], false);
364386

365-
WriteArchive(archiveHash, blockIndex, bytes, (result, error) =>
387+
if (bytes == null)
366388
{
367-
if (result)
368-
{
369-
success = true;
370-
answer = APIUtils.FromAPIResult(new Transaction() { hash = archiveHash.ToString() });
371-
}
372-
else
389+
answer = APIUtils.FromAPIResult(new Error() { message = $"invokeScript: Invalid archive data"});
390+
}
391+
else
392+
{
393+
WriteArchive(archiveHash, blockIndex, bytes, (result, error) =>
373394
{
374-
answer = APIUtils.FromAPIResult(new Error() { message = error });
375-
}
395+
if (result)
396+
{
397+
success = true;
398+
answer = APIUtils.FromAPIResult(new Transaction() { hash = archiveHash.ToString() });
399+
}
400+
else
401+
{
402+
answer = APIUtils.FromAPIResult(new Error() { message = error });
403+
}
376404

377-
callback(id, answer, success);
378-
_isPendingRequest = false;
379-
});
405+
callback(id, answer, success);
406+
_isPendingRequest = false;
407+
});
408+
}
409+
380410
return;
381411
}
382412
else

Phantasma.Numerics/Base16.cs

+28-12
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public static class Base16
66
{
77
private const string hexAlphabet = "0123456789ABCDEF";
88

9-
public static byte[] Decode(this string input)
9+
public static byte[] Decode(this string input, bool allowExceptions = true)
1010
{
1111
if (input == null || input.Length == 0)
1212
{
@@ -15,25 +15,41 @@ public static byte[] Decode(this string input)
1515

1616
if (input.StartsWith("0x"))
1717
{
18-
return input.Substring(2).Decode();
18+
return input.Substring(2).Decode(allowExceptions);
1919
}
2020

21-
Throw.If(input.Length % 2 == 1, "string length must be even");
21+
byte[] result = null;
2222

23-
byte[] result = new byte[input.Length / 2];
24-
25-
for (int i = 0; i < result.Length; i++)
23+
if (input.Length % 2 == 0)
2624
{
27-
var str = input.Substring(i * 2, 2).ToUpper();
28-
int A = hexAlphabet.IndexOf(str[0]);
29-
int B = hexAlphabet.IndexOf(str[1]);
25+
result = new byte[input.Length / 2];
26+
for (int i = 0; i < result.Length; i++)
27+
{
28+
var str = input.Substring(i * 2, 2).ToUpper();
29+
int A = hexAlphabet.IndexOf(str[0]);
30+
int B = hexAlphabet.IndexOf(str[1]);
31+
32+
if (A < 0 || B < 0)
33+
{
34+
result = null;
35+
break;
36+
}
3037

31-
Throw.If(A < 0 || B < 0, "invalid character");
38+
result[i] = (byte)(A * 16 + B);
39+
}
40+
}
3241

33-
result[i] = (byte)(A * 16 + B);
42+
if (result != null)
43+
{
44+
return result;
45+
}
46+
47+
if (allowExceptions)
48+
{
49+
throw new System.Exception("base16.Decode: invalid input");
3450
}
3551

36-
return result;
52+
return null;
3753
}
3854

3955
// constant time hex conversion

0 commit comments

Comments
 (0)