1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-01-09 17:38:00 +00:00

testcrypt: introduce and use 'checkenum' protocol query.

This allows the Python side of testcrypt to check in advance if a
given string is a valid element of an enumeration, and if not, cleanly
throw a Python-level exception without terminating the testcrypt
subprocess.

Should be useful in both manual use (when I'm trying something out by
hand and make a typo or misremember a spelling), and automated use (if
I make the same kind of error in cryptsuite.py then the exception dump
will make more sense).

In order to do this, the new handle_checkenum() function has to
recognise all the enumerated types by name and match them up to their
lookup functions - which is just the kind of thing that can now be
done easily be reincluding testcrypt-enum.h with different #defines.
This commit is contained in:
Simon Tatham 2021-11-22 18:39:45 +00:00
parent d4fedfebdc
commit 9ceb2c49ae
2 changed files with 29 additions and 1 deletions

View File

@ -103,6 +103,8 @@ method_prefixes = {
}
method_lists = {t: [] for t in method_prefixes}
checked_enum_values = {}
class Value(object):
def __init__(self, typename, ident):
self._typename = typename
@ -182,7 +184,13 @@ def make_argword(arg, argtype, fnname, argindex, argname, to_preserve):
"argon2flavour", "fptype", "httpdigesthash"}:
arg = coerce_to_bytes(arg)
if isinstance(arg, bytes) and b" " not in arg:
return arg
dictkey = (typename, arg)
if dictkey not in checked_enum_values:
retwords = childprocess.funcall("checkenum", [typename, arg])
assert len(retwords) == 1
checked_enum_values[dictkey] = (retwords[0] == b"ok")
if checked_enum_values[dictkey]:
return arg
if typename == "mpint_list":
sublist = [make_argword(len(arg), ("uint", False),
fnname, argindex, argname, to_preserve)]

View File

@ -623,6 +623,25 @@ static void handle_mp_dump(BinarySource *in, strbuf *out)
put_byte(out, '\n');
}
static void handle_checkenum(BinarySource *in, strbuf *out)
{
ptrlen type = get_word(in);
ptrlen value = get_word(in);
bool ok = false;
#define BEGIN_ENUM_TYPE(name) \
if (ptrlen_eq_string(type, #name)) \
ok = enum_translate_##name(value, NULL);
#define ENUM_VALUE(name, value)
#define END_ENUM_TYPE(name)
#include "testcrypt-enum.h"
#undef BEGIN_ENUM_TYPE
#undef ENUM_VALUE
#undef END_ENUM_TYPE
put_dataz(out, ok ? "ok\n" : "bad\n");
}
static void random_queue(ptrlen pl)
{
bufchain_add(&random_data_queue, pl.ptr, pl.len);
@ -1356,6 +1375,7 @@ static void process_line(BinarySource *in, strbuf *out)
DISPATCH_COMMAND(getstring);
DISPATCH_COMMAND(mp_literal);
DISPATCH_COMMAND(mp_dump);
DISPATCH_COMMAND(checkenum);
#undef DISPATCH_COMMAND
#define FUNC_INNER(outtype, fname, realname, args) \