@@ -257,7 +257,7 @@ fn encode_value(typ: &MemberType, value: Vec<u8>) -> Result<(Vec<u8>, String), E
257
257
)
258
258
}
259
259
DataType :: String => {
260
- if !util:: ascii:: is_printable_ascii ( & value, util:: ascii:: Charset :: All ) {
260
+ if !util:: ascii:: is_printable_ascii ( & value, util:: ascii:: Charset :: AllNewline ) {
261
261
return Err ( Error :: InvalidInput ) ;
262
262
}
263
263
(
@@ -312,18 +312,30 @@ async fn encode_member<U: sha3::digest::Update>(
312
312
} else {
313
313
let value = get_value_from_host ( root_object, path) . await ?;
314
314
let ( value_encoded, value_formatted) = encode_value ( member_type, value) ?;
315
- confirm:: confirm ( & confirm:: Params {
316
- title : & format ! (
317
- "{}{}" ,
318
- confirm_title( root_object) ,
319
- title_suffix. as_deref( ) . unwrap_or( "" )
320
- ) ,
321
- body : & format ! ( "{}: {}" , formatted_path. join( "." ) , value_formatted) ,
322
- scrollable : true ,
323
- accept_is_nextarrow : true ,
324
- ..Default :: default ( )
325
- } )
326
- . await ?;
315
+ let lines: Vec < & str > = value_formatted. split ( '\n' ) . collect ( ) ;
316
+ for ( i, & line) in lines. iter ( ) . enumerate ( ) {
317
+ confirm:: confirm ( & confirm:: Params {
318
+ title : & format ! (
319
+ "{}{}" ,
320
+ confirm_title( root_object) ,
321
+ title_suffix. as_deref( ) . unwrap_or( "" )
322
+ ) ,
323
+ body : & format ! (
324
+ "{}{}: {}" ,
325
+ formatted_path. join( "." ) ,
326
+ if lines. len( ) > 1 {
327
+ format!( ", line {}/{}" , i + 1 , lines. len( ) )
328
+ } else {
329
+ "" . into( )
330
+ } ,
331
+ line
332
+ ) ,
333
+ scrollable : true ,
334
+ accept_is_nextarrow : true ,
335
+ ..Default :: default ( )
336
+ } )
337
+ . await ?;
338
+ }
327
339
hasher. update ( & value_encoded) ;
328
340
}
329
341
Ok ( ( ) )
@@ -1031,7 +1043,7 @@ mod tests {
1031
1043
/// str: 'str',
1032
1044
/// emptyArray: [],
1033
1045
/// name_address: '0xa21A16EC22a940990922220E4ab5bF4C2310F556',
1034
- /// name_string: ['', 'a', 'aa', '|@#!$', 'long long long long long long long long'],
1046
+ /// name_string: ['', 'a', 'aa', '|@#!$', 'long long long long long long long long', 'multi\n\nline' ],
1035
1047
/// name_bytes: ['', '0xaabbcc'],
1036
1048
/// name_bytes1: '0xaa',
1037
1049
/// name_bytes10: '0x112233445566778899aa',
@@ -1058,6 +1070,109 @@ mod tests {
1058
1070
/// ```
1059
1071
#[ test]
1060
1072
fn test_exhaustive_data ( ) {
1073
+ const EXPECTED_DIALOGS : & [ ( & str , & str ) ] = & [
1074
+ ( "Domain (1/4)" , "name: Ether Mail" ) ,
1075
+ ( "Domain (2/4)" , "version: 1" ) ,
1076
+ ( "Domain (3/4)" , "chainId: 1" ) ,
1077
+ (
1078
+ "Domain (4/4)" ,
1079
+ "verifyingContract: 0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC" ,
1080
+ ) ,
1081
+ ( "Message (1/23)" , "str: str" ) ,
1082
+ ( "Message (2/23)" , "emptyArray: (empty list)" ) ,
1083
+ ( "Message (3/23)" , "name_address: 0xa21A16EC22a940990922220E4ab5bF4C2310F556" ) ,
1084
+ ( "Message (4/23)" , "name_string: list with 6 elements" ) ,
1085
+ ( "Message (4/23)" , "name_string[1/6]: " ) ,
1086
+ ( "Message (4/23)" , "name_string[2/6]: a" ) ,
1087
+ ( "Message (4/23)" , "name_string[3/6]: aa" ) ,
1088
+ ( "Message (4/23)" , "name_string[4/6]: |@#!$" ) ,
1089
+ ( "Message (4/23)" , "name_string[5/6]: long long long long long long long long" ) ,
1090
+ ( "Message (4/23)" , "name_string[6/6], line 1/3: multi" ) ,
1091
+ ( "Message (4/23)" , "name_string[6/6], line 2/3: " ) ,
1092
+ ( "Message (4/23)" , "name_string[6/6], line 3/3: line" ) ,
1093
+ ( "Message (5/23)" , "name_bytes: list with 2 elements" ) ,
1094
+ ( "Message (5/23)" , "name_bytes[1/2]: 0x" ) ,
1095
+ ( "Message (5/23)" , "name_bytes[2/2]: 0xaabbcc" ) ,
1096
+ ( "Message (6/23)" , "name_bytes1: 0xaa" ) ,
1097
+ ( "Message (7/23)" , "name_bytes10: 0x112233445566778899aa" ) ,
1098
+ ( "Message (8/23)" , "name_bytes32: 0xd0f02988fd881565e927c7473c287322db166901bac03bef55d7a52a5c750ab4" ) ,
1099
+ ( "Message (9/23)" , "name_uint8: list with 4 elements" ) ,
1100
+ ( "Message (9/23)" , "name_uint8[1/4]: 0" ) ,
1101
+ ( "Message (9/23)" , "name_uint8[2/4]: 1" ) ,
1102
+ ( "Message (9/23)" , "name_uint8[3/4]: 10" ) ,
1103
+ ( "Message (9/23)" , "name_uint8[4/4]: 255" ) ,
1104
+ ( "Message (10/23)" , "name_uint32: list with 4 elements" ) ,
1105
+ ( "Message (10/23)" , "name_uint32[1/4]: 0" ) ,
1106
+ ( "Message (10/23)" , "name_uint32[2/4]: 256" ) ,
1107
+ ( "Message (10/23)" , "name_uint32[3/4]: 65536" ) ,
1108
+ ( "Message (10/23)" , "name_uint32[4/4]: 4294967295" ) ,
1109
+ ( "Message (11/23)" , "name_uint64: 18446744073709551615" ) ,
1110
+ ( "Message (12/23)" , "name_uint128: 340282366920938463463374607431768211455" ) ,
1111
+ ( "Message (13/23)" , "name_uint256: 115792089237316195423570985008687907853269984665640564039457584007913129639935" ) ,
1112
+ ( "Message (14/23)" , "name_int8: list with 5 elements" ) ,
1113
+ ( "Message (14/23)" , "name_int8[1/5]: 0" ) ,
1114
+ ( "Message (14/23)" , "name_int8[2/5]: 10" ) ,
1115
+ ( "Message (14/23)" , "name_int8[3/5]: -10" ) ,
1116
+ ( "Message (14/23)" , "name_int8[4/5]: 127" ) ,
1117
+ ( "Message (14/23)" , "name_int8[5/5]: -128" ) ,
1118
+ ( "Message (15/23)" , "name_int32: list with 2 elements" ) ,
1119
+ ( "Message (15/23)" , "name_int32[1/2]: 2147483647" ) ,
1120
+ ( "Message (15/23)" , "name_int32[2/2]: -2147483648" ) ,
1121
+ ( "Message (16/23)" , "name_int64: list with 4 elements" ) ,
1122
+ ( "Message (16/23)" , "name_int64[1/4]: 500" ) ,
1123
+ ( "Message (16/23)" , "name_int64[2/4]: -500" ) ,
1124
+ ( "Message (16/23)" , "name_int64[3/4]: 9223372036854775807" ) ,
1125
+ ( "Message (16/23)" , "name_int64[4/4]: -9223372036854775808" ) ,
1126
+ ( "Message (17/23)" , "name_int128: list with 2 elements" ) ,
1127
+ ( "Message (17/23)" , "name_int128[1/2]: 170141183460469231731687303715884105727" ) ,
1128
+ ( "Message (17/23)" , "name_int128[2/2]: -170141183460469231731687303715884105728" ) ,
1129
+ ( "Message (18/23)" , "name_int256: list with 2 elements" ) ,
1130
+ ( "Message (18/23)" , "name_int256[1/2]: 57896044618658097711785492504343953926634992332820282019728792003956564819967" ) ,
1131
+ ( "Message (18/23)" , "name_int256[2/2]: -57896044618658097711785492504343953926634992332820282019728792003956564819968" ) ,
1132
+ ( "Message (19/23)" , "name_bool: list with 2 elements" ) ,
1133
+ ( "Message (19/23)" , "name_bool[1/2]: false" ) ,
1134
+ ( "Message (19/23)" , "name_bool[2/2]: true" ) ,
1135
+ ( "Message (20/23)" , "name_struct.name: struct name" ) ,
1136
+ ( "Message (20/23)" , "name_struct.arr: (empty list)" ) ,
1137
+ ( "Message (21/23)" , "arrayOfStructs: list with 3 elements" ) ,
1138
+ ( "Message (21/23)" , "arrayOfStructs[1/3].name: name 1" ) ,
1139
+ ( "Message (21/23)" , "arrayOfStructs[1/3].arr: (empty list)" ) ,
1140
+ ( "Message (21/23)" , "arrayOfStructs[2/3].name: name 2" ) ,
1141
+ ( "Message (21/23)" , "arrayOfStructs[2/3].arr: list with 1 elements" ) ,
1142
+ ( "Message (21/23)" , "arrayOfStructs[2/3].arr[1/1]: false" ) ,
1143
+ ( "Message (21/23)" , "arrayOfStructs[3/3].name: name 3" ) ,
1144
+ ( "Message (21/23)" , "arrayOfStructs[3/3].arr: list with 2 elements" ) ,
1145
+ ( "Message (21/23)" , "arrayOfStructs[3/3].arr[1/2]: false" ) ,
1146
+ ( "Message (21/23)" , "arrayOfStructs[3/3].arr[2/2]: true" ) ,
1147
+ ( "Message (22/23)" , "fixedArrayOfStructs: list with 2 elements" ) ,
1148
+ ( "Message (22/23)" , "fixedArrayOfStructs[1/2].name: name 1" ) ,
1149
+ ( "Message (22/23)" , "fixedArrayOfStructs[1/2].arr: (empty list)" ) ,
1150
+ ( "Message (22/23)" , "fixedArrayOfStructs[2/2].name: name 2" ) ,
1151
+ ( "Message (22/23)" , "fixedArrayOfStructs[2/2].arr: list with 3 elements" ) ,
1152
+ ( "Message (22/23)" , "fixedArrayOfStructs[2/2].arr[1/3]: false" ) ,
1153
+ ( "Message (22/23)" , "fixedArrayOfStructs[2/2].arr[2/3]: false" ) ,
1154
+ ( "Message (22/23)" , "fixedArrayOfStructs[2/2].arr[3/3]: true" ) ,
1155
+ ( "Message (23/23)" , "nestedArray: list with 3 elements" ) ,
1156
+ ( "Message (23/23)" , "nestedArray[1/3]: list with 2 elements" ) ,
1157
+ ( "Message (23/23)" , "nestedArray[1/3][1/2]: list with 2 elements" ) ,
1158
+ ( "Message (23/23)" , "nestedArray[1/3][1/2][1/2]: 1" ) ,
1159
+ ( "Message (23/23)" , "nestedArray[1/3][1/2][2/2]: 2" ) ,
1160
+ ( "Message (23/23)" , "nestedArray[1/3][2/2]: list with 3 elements" ) ,
1161
+ ( "Message (23/23)" , "nestedArray[1/3][2/2][1/3]: 3" ) ,
1162
+ ( "Message (23/23)" , "nestedArray[1/3][2/2][2/3]: 4" ) ,
1163
+ ( "Message (23/23)" , "nestedArray[1/3][2/2][3/3]: 5" ) ,
1164
+ ( "Message (23/23)" , "nestedArray[2/3]: list with 2 elements" ) ,
1165
+ ( "Message (23/23)" , "nestedArray[2/3][1/2]: list with 2 elements" ) ,
1166
+ ( "Message (23/23)" , "nestedArray[2/3][1/2][1/2]: 6" ) ,
1167
+ ( "Message (23/23)" , "nestedArray[2/3][1/2][2/2]: 7" ) ,
1168
+ ( "Message (23/23)" , "nestedArray[2/3][2/2]: list with 1 elements" ) ,
1169
+ ( "Message (23/23)" , "nestedArray[2/3][2/2][1/1]: 8" ) ,
1170
+ ( "Message (23/23)" , "nestedArray[3/3]: list with 2 elements" ) ,
1171
+ ( "Message (23/23)" , "nestedArray[3/3][1/2]: (empty list)" ) ,
1172
+ ( "Message (23/23)" , "nestedArray[3/3][2/2]: list with 1 elements" ) ,
1173
+ ( "Message (23/23)" , "nestedArray[3/3][2/2][1/1]: 9" ) ,
1174
+ ] ;
1175
+
1061
1176
let bytes32 = b"\xd0 \xf0 \x29 \x88 \xfd \x88 \x15 \x65 \xe9 \x27 \xc7 \x47 \x3c \x28 \x73 \x22 \xdb \x16 \x69 \x01 \xba \xc0 \x3b \xef \x55 \xd7 \xa5 \x2a \x5c \x75 \x0a \xb4 " ;
1062
1177
let bigint256_positive = b"\x7f \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff \xff " ;
1063
1178
let bigint256_negative = b"\x80 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 \x00 " ;
@@ -1152,6 +1267,7 @@ mod tests {
1152
1267
Object :: String ( "aa" ) ,
1153
1268
Object :: String ( "|@#!$" ) ,
1154
1269
Object :: String ( "long long long long long long long long" ) ,
1270
+ Object :: String ( "multi\n \n line" ) ,
1155
1271
] ) ,
1156
1272
// name_bytes
1157
1273
Object :: List ( vec![ Object :: Bytes ( b"" ) , Object :: Bytes ( b"\xaa \xbb \xcc " ) ] ) ,
@@ -1290,16 +1406,23 @@ mod tests {
1290
1406
Ok ( typed_msg. handle_host_response ( & response) . unwrap ( ) )
1291
1407
} ) ) ;
1292
1408
}
1409
+ static mut UI_COUNTER : usize = 0 ;
1293
1410
mock ( Data {
1294
- ui_confirm_create : Some ( Box :: new ( |_params| true ) ) ,
1411
+ ui_confirm_create : Some ( Box :: new ( |params| unsafe {
1412
+ let expected = EXPECTED_DIALOGS [ UI_COUNTER ] ;
1413
+ assert_eq ! ( ( params. title, params. body) , expected) ;
1414
+ UI_COUNTER += 1 ;
1415
+ true
1416
+ } ) ) ,
1295
1417
..Default :: default ( )
1296
1418
} ) ;
1297
1419
let typed_msg = typed_msg. borrow ( ) ;
1298
1420
let sighash = block_on ( eip712_sighash ( & typed_msg. types , typed_msg. primary_type ) ) . unwrap ( ) ;
1299
1421
assert_eq ! (
1300
1422
sighash,
1301
- * b"\xc5 \x4f \xa7 \x87 \x13 \x18 \xb6 \xc2 \xd8 \x71 \x62 \xde \xbe \xff \x4c \xdf \x13 \ xf2\x85 \x45 \x12 \xf3 \x43 \x6a \x04 \xa6 \x0c \xd1 \xa7 \xcf \x47 \xc5 " ,
1423
+ * b"\x0e \xfe \x31 \xa8 \x81 \x9b \x6c \x38 \x1c \x9e \x97 \xcf \xd2 \x99 \x5a \xa6 \ xf2\x1e \x4a \x72 \x87 \x9a \xc1 \x31 \xb2 \xf6 \x48 \xd0 \x83 \x28 \x1c \x83 " ,
1302
1424
) ;
1425
+ assert_eq ! ( unsafe { UI_COUNTER } , EXPECTED_DIALOGS . len( ) ) ;
1303
1426
}
1304
1427
1305
1428
/// Test case whree primaryType=='EIP712Domain'.
0 commit comments