Skip to content

Commit aa1aaec

Browse files
Improve error handling once again
1 parent b6d4519 commit aa1aaec

File tree

3 files changed

+131
-101
lines changed

3 files changed

+131
-101
lines changed

rust/rbac-registration/src/cardano/cip509/cip509.rs

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -299,18 +299,28 @@ impl Decode<'_, DecodeContext<'_, '_>> for Cip509 {
299299

300300
match key {
301301
Cip509IntIdentifier::Purpose => {
302-
purpose = decode_purpose(d, context, decode_context.report);
302+
match decode_purpose(d, context, decode_context.report) {
303+
Ok(v) => purpose = v,
304+
Err(()) => break,
305+
}
303306
},
304307
Cip509IntIdentifier::TxInputsHash => {
305-
txn_inputs_hash = decode_input_hash(d, context, decode_context.report);
308+
match decode_input_hash(d, context, decode_context.report) {
309+
Ok(v) => txn_inputs_hash = v,
310+
Err(()) => break,
311+
}
306312
},
307313
Cip509IntIdentifier::PreviousTxId => {
308-
prv_tx_id =
309-
decode_previous_transaction_id(d, context, decode_context.report);
314+
match decode_previous_transaction_id(d, context, decode_context.report) {
315+
Ok(v) => prv_tx_id = v,
316+
Err(()) => break,
317+
}
310318
},
311319
Cip509IntIdentifier::ValidationSignature => {
312-
validation_signature =
313-
decode_validation_signature(d, context, decode_context.report);
320+
match decode_validation_signature(d, context, decode_context.report) {
321+
Ok(v) => validation_signature = v,
322+
Err(()) => break,
323+
}
314324
},
315325
}
316326
} else {
@@ -335,6 +345,7 @@ impl Decode<'_, DecodeContext<'_, '_>> for Cip509 {
335345
&format!("Unable to decode metadata from chunks: {e:?}"),
336346
context,
337347
);
348+
break;
338349
},
339350
};
340351
}
@@ -421,113 +432,115 @@ fn payment_history(
421432
}
422433

423434
/// Decodes purpose.
424-
fn decode_purpose(d: &mut Decoder, context: &str, report: &ProblemReport) -> Option<Uuid> {
435+
fn decode_purpose(
436+
d: &mut Decoder, context: &str, report: &ProblemReport,
437+
) -> Result<Option<Uuid>, ()> {
425438
let bytes = match decode_bytes(d, "Cip509 purpose") {
426439
Ok(v) => v,
427440
Err(e) => {
428441
report.other(&format!("Unable to decode purpose: {e:?}"), context);
429-
return None;
442+
return Err(());
430443
},
431444
};
432445

433446
let len = bytes.len();
434447
if let Ok(v) = Uuid::try_from(bytes) {
435-
Some(v)
448+
Ok(Some(v))
436449
} else {
437450
report.invalid_value(
438451
"purpose",
439452
&format!("{len} bytes"),
440453
"must be 16 bytes long",
441454
context,
442455
);
443-
None
456+
Ok(None)
444457
}
445458
}
446459

447460
/// Decodes input hash.
448461
fn decode_input_hash(
449462
d: &mut Decoder, context: &str, report: &ProblemReport,
450-
) -> Option<TxInputHash> {
463+
) -> Result<Option<TxInputHash>, ()> {
451464
let bytes = match decode_bytes(d, "Cip509 txn inputs hash") {
452465
Ok(v) => v,
453466
Err(e) => {
454467
report.other(
455468
&format!("Unable to decode transaction inputs hash: {e:?}"),
456469
context,
457470
);
458-
return None;
471+
return Err(());
459472
},
460473
};
461474

462475
let len = bytes.len();
463476
if let Ok(v) = TxInputHash::try_from(bytes.as_slice()) {
464-
Some(v)
477+
Ok(Some(v))
465478
} else {
466479
report.invalid_value(
467480
"transaction inputs hash",
468481
&format!("{len} bytes"),
469482
"must be 16 bytes long",
470483
context,
471484
);
472-
None
485+
Ok(None)
473486
}
474487
}
475488

476489
/// Decodes previous transaction id.
477490
fn decode_previous_transaction_id(
478491
d: &mut Decoder, context: &str, report: &ProblemReport,
479-
) -> Option<Blake2b256Hash> {
492+
) -> Result<Option<Blake2b256Hash>, ()> {
480493
let bytes = match decode_bytes(d, "Cip509 previous transaction id") {
481494
Ok(v) => v,
482495
Err(e) => {
483496
report.other(
484497
&format!("Unable to decode previous transaction id: {e:?}"),
485498
context,
486499
);
487-
return None;
500+
return Err(());
488501
},
489502
};
490503

491504
let len = bytes.len();
492505
if let Ok(v) = Blake2b256Hash::try_from(bytes) {
493-
Some(v)
506+
Ok(Some(v))
494507
} else {
495508
report.invalid_value(
496509
"previous transaction hash",
497510
&format!("{len} bytes"),
498511
&format!("must be {BLAKE_2B256_SIZE} bytes long"),
499512
context,
500513
);
501-
None
514+
Ok(None)
502515
}
503516
}
504517

505518
/// Decodes validation signature.
506519
fn decode_validation_signature(
507520
d: &mut Decoder, context: &str, report: &ProblemReport,
508-
) -> Option<ValidationSignature> {
521+
) -> Result<Option<ValidationSignature>, ()> {
509522
let bytes = match decode_bytes(d, "Cip509 validation signature") {
510523
Ok(v) => v,
511524
Err(e) => {
512525
report.other(
513526
&format!("Unable to decode validation signature: {e:?}"),
514527
context,
515528
);
516-
return None;
529+
return Err(());
517530
},
518531
};
519532

520533
let len = bytes.len();
521534
if let Ok(v) = ValidationSignature::try_from(bytes) {
522-
Some(v)
535+
Ok(Some(v))
523536
} else {
524537
report.invalid_value(
525538
"validation signature",
526539
&format!("{len} bytes"),
527540
"must be at least 1 byte and at most 64 bytes long",
528541
context,
529542
);
530-
None
543+
Ok(None)
531544
}
532545
}
533546

rust/rbac-registration/src/cardano/cip509/rbac/metadata.rs

Lines changed: 60 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -101,53 +101,47 @@ impl Decode<'_, DecodeContext<'_, '_>> for Cip509RbacMetadata {
101101

102102
match key {
103103
Cip509RbacMetadataInt::X509Certs => {
104-
x509_certs = decode_array(
104+
match decode_array(
105105
d,
106106
"Cip509RbacMetadata x509 certificates",
107107
decode_context.report,
108-
);
108+
) {
109+
Some(v) => x509_certs = v,
110+
None => break,
111+
}
109112
},
110113
Cip509RbacMetadataInt::C509Certs => {
111-
c509_certs = decode_array(
114+
match decode_array(
112115
d,
113-
"Cip509RbacMetadata c509 certificate",
116+
"Cip509RbacMetadata c509 certificates",
114117
decode_context.report,
115-
);
118+
) {
119+
Some(v) => c509_certs = v,
120+
None => break,
121+
}
116122
},
117123
Cip509RbacMetadataInt::PubKeys => {
118-
pub_keys = decode_array(
124+
match decode_array(
119125
d,
120126
"Cip509RbacMetadata public keys",
121127
decode_context.report,
122-
);
128+
) {
129+
Some(v) => pub_keys = v,
130+
None => break,
131+
}
123132
},
124133
Cip509RbacMetadataInt::RevocationList => {
125-
revocation_list = decode_revocation_list(d, decode_context.report);
134+
match decode_revocation_list(d, decode_context.report) {
135+
Ok(v) => revocation_list = v,
136+
Err(()) => break,
137+
}
126138
},
127139
Cip509RbacMetadataInt::RoleSet => {
128-
let roles = decode_array::<CborRoleData>(
129-
d,
130-
"Cip509RbacMetadata role set",
131-
decode_context.report,
132-
);
133-
report_duplicated_roles(&roles, context, decode_context.report);
134-
role_data = roles
135-
.into_iter()
136-
.filter_map(|data| {
137-
if let Some(number) = data.number {
138-
Some((
139-
number,
140-
RoleData::new(
141-
data,
142-
decode_context.txn,
143-
decode_context.report,
144-
),
145-
))
146-
} else {
147-
None
148-
}
149-
})
150-
.collect();
140+
if let Some(data) = decode_role_data(d, context, decode_context) {
141+
role_data = data;
142+
} else {
143+
break;
144+
}
151145
},
152146
}
153147
} else {
@@ -164,6 +158,7 @@ impl Decode<'_, DecodeContext<'_, '_>> for Cip509RbacMetadata {
164158
decode_context
165159
.report
166160
.other(&format!("Unable to decode purpose value: {e:?}"), context);
161+
break;
167162
},
168163
}
169164
}
@@ -184,20 +179,22 @@ impl Decode<'_, DecodeContext<'_, '_>> for Cip509RbacMetadata {
184179
}
185180

186181
/// Decodes an array of type T.
187-
fn decode_array<'b, T>(d: &mut Decoder<'b>, context: &str, report: &mut ProblemReport) -> Vec<T>
182+
fn decode_array<'b, T>(
183+
d: &mut Decoder<'b>, context: &str, report: &mut ProblemReport,
184+
) -> Option<Vec<T>>
188185
where T: Decode<'b, ProblemReport> {
189186
let len = match decode_array_len(d, context) {
190187
Ok(v) => v,
191188
Err(e) => {
192189
report.other(&format!("Unable to decode array length: {e:?}"), context);
193-
return Vec::new();
190+
return None;
194191
},
195192
};
196193
let len = match usize::try_from(len) {
197194
Ok(v) => v,
198195
Err(e) => {
199196
report.other(&format!("Invalid array length: {e:?}"), context);
200-
return Vec::new();
197+
return Some(Vec::new());
201198
},
202199
};
203200

@@ -207,27 +204,28 @@ where T: Decode<'b, ProblemReport> {
207204
Ok(v) => result.push(v),
208205
Err(e) => {
209206
report.other(&format!("Unable to decode array value: {e:?}"), context);
207+
return None;
210208
},
211209
}
212210
}
213-
result
211+
Some(result)
214212
}
215213

216214
/// Decode an array of revocation list.
217-
fn decode_revocation_list(d: &mut Decoder, report: &ProblemReport) -> Vec<CertKeyHash> {
215+
fn decode_revocation_list(d: &mut Decoder, report: &ProblemReport) -> Result<Vec<CertKeyHash>, ()> {
218216
let context = "Cip509RbacMetadata revocation list";
219217
let len = match decode_array_len(d, context) {
220218
Ok(v) => v,
221219
Err(e) => {
222220
report.other(&format!("Unable to decode array length: {e:?}"), context);
223-
return Vec::new();
221+
return Err(());
224222
},
225223
};
226224
let len = match usize::try_from(len) {
227225
Ok(v) => v,
228226
Err(e) => {
229227
report.other(&format!("Invalid array length: {e:?}"), context);
230-
return Vec::new();
228+
return Ok(Vec::new());
231229
},
232230
};
233231

@@ -240,7 +238,7 @@ fn decode_revocation_list(d: &mut Decoder, report: &ProblemReport) -> Vec<CertKe
240238
&format!("Unable to decode certificate hash bytes: {e:?}"),
241239
context,
242240
);
243-
continue;
241+
return Err(());
244242
},
245243
};
246244
match CertKeyHash::try_from(bytes) {
@@ -253,7 +251,7 @@ fn decode_revocation_list(d: &mut Decoder, report: &ProblemReport) -> Vec<CertKe
253251
},
254252
}
255253
}
256-
result
254+
Ok(result)
257255
}
258256

259257
/// Adds report entries if duplicated roles are found.
@@ -268,3 +266,25 @@ fn report_duplicated_roles(data: &[CborRoleData], context: &str, report: &Proble
268266
}
269267
}
270268
}
269+
270+
/// Decodes and converts a role data.
271+
fn decode_role_data(
272+
d: &mut Decoder, context: &str, decode_context: &mut DecodeContext,
273+
) -> Option<HashMap<RoleNumber, RoleData>> {
274+
let roles = decode_array(d, "Cip509RbacMetadata role set", decode_context.report)?;
275+
report_duplicated_roles(&roles, context, decode_context.report);
276+
let roles = roles
277+
.into_iter()
278+
.filter_map(|data| {
279+
if let Some(number) = data.number {
280+
Some((
281+
number,
282+
RoleData::new(data, decode_context.txn, decode_context.report),
283+
))
284+
} else {
285+
None
286+
}
287+
})
288+
.collect();
289+
Some(roles)
290+
}

0 commit comments

Comments
 (0)