Browse Source

[base16] Add buffer size parameter to base16_encode() and base16_decode()

The current API for Base16 (and Base64) encoding requires the caller
to always provide sufficient buffer space.  This prevents the use of
the generic encoding/decoding functionality in some situations, such
as in formatting the hex setting types.

Implement a generic hex_encode() (based on the existing
format_hex_setting()), implement base16_encode() and base16_decode()
in terms of the more generic hex_encode() and hex_decode(), and update
all callers to provide the additional buffer length parameter.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
9aa8090d06

+ 24
- 57
src/core/base16.c View File

28
 #include <errno.h>
28
 #include <errno.h>
29
 #include <assert.h>
29
 #include <assert.h>
30
 #include <ipxe/string.h>
30
 #include <ipxe/string.h>
31
+#include <ipxe/vsprintf.h>
31
 #include <ipxe/base16.h>
32
 #include <ipxe/base16.h>
32
 
33
 
33
 /** @file
34
 /** @file
37
  */
38
  */
38
 
39
 
39
 /**
40
 /**
40
- * Base16-encode data
41
+ * Encode hexadecimal string (with optional byte separator character)
41
  *
42
  *
43
+ * @v separator		Byte separator character, or 0 for no separator
42
  * @v raw		Raw data
44
  * @v raw		Raw data
43
- * @v len		Length of raw data
44
- * @v encoded		Buffer for encoded string
45
- *
46
- * The buffer must be the correct length for the encoded string.  Use
47
- * something like
48
- *
49
- *     char buf[ base16_encoded_len ( len ) + 1 ];
50
- *
51
- * (the +1 is for the terminating NUL) to provide a buffer of the
52
- * correct size.
45
+ * @v raw_len		Length of raw data
46
+ * @v data		Buffer
47
+ * @v len		Length of buffer
48
+ * @ret len		Encoded length
53
  */
49
  */
54
-void base16_encode ( const uint8_t *raw, size_t len, char *encoded ) {
55
-	const uint8_t *raw_bytes = raw;
56
-	char *encoded_bytes = encoded;
57
-	size_t remaining = len;
58
-
59
-	/* Encode each byte */
60
-	for ( ; remaining-- ; encoded_bytes += 2 ) {
61
-		sprintf ( encoded_bytes, "%02x", *(raw_bytes++) );
50
+size_t hex_encode ( char separator, const void *raw, size_t raw_len,
51
+		    char *data, size_t len ) {
52
+	const uint8_t *bytes = raw;
53
+	const char delimiter[2] = { separator, '\0' };
54
+	size_t used = 0;
55
+	unsigned int i;
56
+
57
+	if ( len )
58
+		data[0] = 0; /* Ensure that a terminating NUL exists */
59
+	for ( i = 0 ; i < raw_len ; i++ ) {
60
+		used += ssnprintf ( ( data + used ), ( len - used ),
61
+				    "%s%02x", ( used ? delimiter : "" ),
62
+				    bytes[i] );
62
 	}
63
 	}
63
-
64
-	/* Ensure terminating NUL exists even if length was zero */
65
-	*encoded_bytes = '\0';
66
-
67
-	DBG ( "Base16-encoded to \"%s\":\n", encoded );
68
-	DBG_HDA ( 0, raw, len );
69
-	assert ( strlen ( encoded ) == base16_encoded_len ( len ) );
64
+	return used;
70
 }
65
 }
71
 
66
 
72
 /**
67
 /**
73
- * Decode hexadecimal string
68
+ * Decode hexadecimal string (with optional byte separator character)
74
  *
69
  *
75
- * @v encoded		Encoded string
76
  * @v separator		Byte separator character, or 0 for no separator
70
  * @v separator		Byte separator character, or 0 for no separator
71
+ * @v encoded		Encoded string
77
  * @v data		Buffer
72
  * @v data		Buffer
78
  * @v len		Length of buffer
73
  * @v len		Length of buffer
79
  * @ret len		Length of data, or negative error
74
  * @ret len		Length of data, or negative error
80
  */
75
  */
81
-int hex_decode ( const char *encoded, char separator, void *data, size_t len ) {
76
+int hex_decode ( char separator, const char *encoded, void *data, size_t len ) {
82
 	uint8_t *out = data;
77
 	uint8_t *out = data;
83
 	unsigned int count = 0;
78
 	unsigned int count = 0;
84
 	unsigned int sixteens;
79
 	unsigned int sixteens;
110
 	}
105
 	}
111
 	return count;
106
 	return count;
112
 }
107
 }
113
-
114
-/**
115
- * Base16-decode data
116
- *
117
- * @v encoded		Encoded string
118
- * @v raw		Raw data
119
- * @ret len		Length of raw data, or negative error
120
- *
121
- * The buffer must be large enough to contain the decoded data.  Use
122
- * something like
123
- *
124
- *     char buf[ base16_decoded_max_len ( encoded ) ];
125
- *
126
- * to provide a buffer of the correct size.
127
- */
128
-int base16_decode ( const char *encoded, uint8_t *raw ) {
129
-	int len;
130
-
131
-	len = hex_decode ( encoded, 0, raw, -1UL );
132
-	if ( len < 0 )
133
-		return len;
134
-
135
-	DBG ( "Base16-decoded \"%s\" to:\n", encoded );
136
-	DBG_HDA ( 0, raw, len );
137
-	assert ( len <= ( int ) base16_decoded_max_len ( encoded ) );
138
-
139
-	return len;
140
-}

+ 6
- 32
src/core/settings.c View File

2005
 const struct setting_type setting_type_uint32 __setting_type =
2005
 const struct setting_type setting_type_uint32 __setting_type =
2006
 	SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
2006
 	SETTING_TYPE_UINT ( SETTING_TYPE_INT32 );
2007
 
2007
 
2008
-/**
2009
- * Format hex string setting value
2010
- *
2011
- * @v delimiter		Byte delimiter
2012
- * @v raw		Raw setting value
2013
- * @v raw_len		Length of raw setting value
2014
- * @v buf		Buffer to contain formatted value
2015
- * @v len		Length of buffer
2016
- * @ret len		Length of formatted value, or negative error
2017
- */
2018
-static int format_hex_setting ( const char *delimiter, const void *raw,
2019
-				size_t raw_len, char *buf, size_t len ) {
2020
-	const uint8_t *bytes = raw;
2021
-	int used = 0;
2022
-	unsigned int i;
2023
-
2024
-	if ( len )
2025
-		buf[0] = 0; /* Ensure that a terminating NUL exists */
2026
-	for ( i = 0 ; i < raw_len ; i++ ) {
2027
-		used += ssnprintf ( ( buf + used ), ( len - used ),
2028
-				    "%s%02x", ( used ? delimiter : "" ),
2029
-				    bytes[i] );
2030
-	}
2031
-	return used;
2032
-}
2033
-
2034
 /**
2008
 /**
2035
  * Parse hex string setting value (using colon delimiter)
2009
  * Parse hex string setting value (using colon delimiter)
2036
  *
2010
  *
2043
  */
2017
  */
2044
 static int parse_hex_setting ( const struct setting_type *type __unused,
2018
 static int parse_hex_setting ( const struct setting_type *type __unused,
2045
 			       const char *value, void *buf, size_t len ) {
2019
 			       const char *value, void *buf, size_t len ) {
2046
-	return hex_decode ( value, ':', buf, len );
2020
+	return hex_decode ( ':', value, buf, len );
2047
 }
2021
 }
2048
 
2022
 
2049
 /**
2023
 /**
2059
 static int format_hex_colon_setting ( const struct setting_type *type __unused,
2033
 static int format_hex_colon_setting ( const struct setting_type *type __unused,
2060
 				      const void *raw, size_t raw_len,
2034
 				      const void *raw, size_t raw_len,
2061
 				      char *buf, size_t len ) {
2035
 				      char *buf, size_t len ) {
2062
-	return format_hex_setting ( ":", raw, raw_len, buf, len );
2036
+	return hex_encode ( ':', raw, raw_len, buf, len );
2063
 }
2037
 }
2064
 
2038
 
2065
 /**
2039
 /**
2075
 static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
2049
 static int parse_hex_hyphen_setting ( const struct setting_type *type __unused,
2076
 				      const char *value, void *buf,
2050
 				      const char *value, void *buf,
2077
 				      size_t len ) {
2051
 				      size_t len ) {
2078
-	return hex_decode ( value, '-', buf, len );
2052
+	return hex_decode ( '-', value, buf, len );
2079
 }
2053
 }
2080
 
2054
 
2081
 /**
2055
 /**
2091
 static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
2065
 static int format_hex_hyphen_setting ( const struct setting_type *type __unused,
2092
 				       const void *raw, size_t raw_len,
2066
 				       const void *raw, size_t raw_len,
2093
 				       char *buf, size_t len ) {
2067
 				       char *buf, size_t len ) {
2094
-	return format_hex_setting ( "-", raw, raw_len, buf, len );
2068
+	return hex_encode ( '-', raw, raw_len, buf, len );
2095
 }
2069
 }
2096
 
2070
 
2097
 /**
2071
 /**
2106
  */
2080
  */
2107
 static int parse_hex_raw_setting ( const struct setting_type *type __unused,
2081
 static int parse_hex_raw_setting ( const struct setting_type *type __unused,
2108
 				   const char *value, void *buf, size_t len ) {
2082
 				   const char *value, void *buf, size_t len ) {
2109
-	return hex_decode ( value, 0, buf, len );
2083
+	return hex_decode ( 0, value, buf, len );
2110
 }
2084
 }
2111
 
2085
 
2112
 /**
2086
 /**
2122
 static int format_hex_raw_setting ( const struct setting_type *type __unused,
2096
 static int format_hex_raw_setting ( const struct setting_type *type __unused,
2123
 				    const void *raw, size_t raw_len,
2097
 				    const void *raw, size_t raw_len,
2124
 				    char *buf, size_t len ) {
2098
 				    char *buf, size_t len ) {
2125
-	return format_hex_setting ( "", raw, raw_len, buf, len );
2099
+	return hex_encode ( 0, raw, raw_len, buf, len );
2126
 }
2100
 }
2127
 
2101
 
2128
 /** A hex-string setting (colon-delimited) */
2102
 /** A hex-string setting (colon-delimited) */

+ 2
- 1
src/crypto/x509.c View File

143
 	} else {
143
 	} else {
144
 		/* Certificate has no commonName: use SHA-1 fingerprint */
144
 		/* Certificate has no commonName: use SHA-1 fingerprint */
145
 		x509_fingerprint ( cert, digest, fingerprint );
145
 		x509_fingerprint ( cert, digest, fingerprint );
146
-		base16_encode ( fingerprint, sizeof ( fingerprint ), buf );
146
+		base16_encode ( fingerprint, sizeof ( fingerprint ),
147
+				buf, sizeof ( buf ) );
147
 	}
148
 	}
148
 	return buf;
149
 	return buf;
149
 }
150
 }

+ 1
- 1
src/drivers/net/ecm.c View File

105
 		return -EINVAL;
105
 		return -EINVAL;
106
 
106
 
107
 	/* Decode MAC address */
107
 	/* Decode MAC address */
108
-	len = base16_decode ( buf, hw_addr );
108
+	len = base16_decode ( buf, hw_addr, ETH_ALEN );
109
 	if ( len < 0 ) {
109
 	if ( len < 0 ) {
110
 		rc = len;
110
 		rc = len;
111
 		return rc;
111
 		return rc;

+ 1
- 1
src/drivers/net/netfront.c View File

139
 		xendev->key, mac );
139
 		xendev->key, mac );
140
 
140
 
141
 	/* Decode MAC address */
141
 	/* Decode MAC address */
142
-	len = hex_decode ( mac, ':', hw_addr, ETH_ALEN );
142
+	len = hex_decode ( ':', mac, hw_addr, ETH_ALEN );
143
 	if ( len < 0 ) {
143
 	if ( len < 0 ) {
144
 		rc = len;
144
 		rc = len;
145
 		DBGC ( netfront, "NETFRONT %s could not decode MAC address "
145
 		DBGC ( netfront, "NETFRONT %s could not decode MAC address "

+ 30
- 3
src/include/ipxe/base16.h View File

32
 	return ( ( strlen ( encoded ) + 1 ) / 2 );
32
 	return ( ( strlen ( encoded ) + 1 ) / 2 );
33
 }
33
 }
34
 
34
 
35
-extern void base16_encode ( const uint8_t *raw, size_t len, char *encoded );
36
-extern int hex_decode ( const char *string, char separator, void *data,
35
+extern size_t hex_encode ( char separator, const void *raw, size_t raw_len,
36
+			   char *data, size_t len );
37
+extern int hex_decode ( char separator, const char *encoded, void *data,
37
 			size_t len );
38
 			size_t len );
38
-extern int base16_decode ( const char *encoded, uint8_t *raw );
39
+
40
+/**
41
+ * Base16-encode data
42
+ *
43
+ * @v raw		Raw data
44
+ * @v raw_len		Length of raw data
45
+ * @v data		Buffer
46
+ * @v len		Length of buffer
47
+ * @ret len		Encoded length
48
+ */
49
+static inline __attribute__ (( always_inline )) size_t
50
+base16_encode ( const void *raw, size_t raw_len, char *data, size_t len ) {
51
+	return hex_encode ( 0, raw, raw_len, data, len );
52
+}
53
+
54
+/**
55
+ * Base16-decode data
56
+ *
57
+ * @v encoded		Encoded string
58
+ * @v data		Buffer
59
+ * @v len		Length of buffer
60
+ * @ret len		Length of data, or negative error
61
+ */
62
+static inline __attribute__ (( always_inline )) int
63
+base16_decode ( const char *encoded, void *data, size_t len ) {
64
+	return hex_decode ( 0, encoded, data, len );
65
+}
39
 
66
 
40
 #endif /* _IPXE_BASE16_H */
67
 #endif /* _IPXE_BASE16_H */

+ 1
- 1
src/interface/efi/efi_debug.c View File

330
 		max_len = ( ( sizeof ( text ) - 1 /* NUL */ ) / 2 /* "xx" */ );
330
 		max_len = ( ( sizeof ( text ) - 1 /* NUL */ ) / 2 /* "xx" */ );
331
 		if ( len > max_len )
331
 		if ( len > max_len )
332
 			len = max_len;
332
 			len = max_len;
333
-		base16_encode ( start, len, text );
333
+		base16_encode ( start, len, text, sizeof ( text ) );
334
 		return text;
334
 		return text;
335
 	}
335
 	}
336
 
336
 

+ 1
- 1
src/net/infiniband/ib_srp.c View File

291
 		return -EINVAL_BYTE_STRING_LEN;
291
 		return -EINVAL_BYTE_STRING_LEN;
292
 
292
 
293
 	/* Parse byte string */
293
 	/* Parse byte string */
294
-	decoded_size = base16_decode ( rp_comp, bytes );
294
+	decoded_size = base16_decode ( rp_comp, bytes, size );
295
 	if ( decoded_size < 0 )
295
 	if ( decoded_size < 0 )
296
 		return decoded_size;
296
 		return decoded_size;
297
 
297
 

+ 1
- 1
src/net/pccrc.c View File

63
 	assert ( base16_encoded_len ( digestsize ) < sizeof ( buf ) );
63
 	assert ( base16_encoded_len ( digestsize ) < sizeof ( buf ) );
64
 
64
 
65
 	/* Transcribe hash value */
65
 	/* Transcribe hash value */
66
-	base16_encode ( hash, digestsize, buf );
66
+	base16_encode ( hash, digestsize, buf, sizeof ( buf ) );
67
 	return buf;
67
 	return buf;
68
 }
68
 }
69
 
69
 

+ 8
- 6
src/net/tcp/httpcore.c View File

1122
  *
1122
  *
1123
  * @v ctx		Digest context
1123
  * @v ctx		Digest context
1124
  * @v out		Buffer for digest output
1124
  * @v out		Buffer for digest output
1125
+ * @v len		Buffer length
1125
  */
1126
  */
1126
-static void http_digest_final ( struct md5_context *ctx, char *out ) {
1127
+static void http_digest_final ( struct md5_context *ctx, char *out,
1128
+				size_t len ) {
1127
 	uint8_t digest[MD5_DIGEST_SIZE];
1129
 	uint8_t digest[MD5_DIGEST_SIZE];
1128
 
1130
 
1129
 	digest_final ( &md5_algorithm, ctx, digest );
1131
 	digest_final ( &md5_algorithm, ctx, digest );
1130
-	base16_encode ( digest, sizeof ( digest ), out );
1132
+	base16_encode ( digest, sizeof ( digest ), out, len );
1131
 }
1133
 }
1132
 
1134
 
1133
 /**
1135
 /**
1172
 	http_digest_update ( &ctx, user );
1174
 	http_digest_update ( &ctx, user );
1173
 	http_digest_update ( &ctx, realm );
1175
 	http_digest_update ( &ctx, realm );
1174
 	http_digest_update ( &ctx, password );
1176
 	http_digest_update ( &ctx, password );
1175
-	http_digest_final ( &ctx, ha1 );
1177
+	http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
1176
 	if ( md5sess ) {
1178
 	if ( md5sess ) {
1177
 		http_digest_init ( &ctx );
1179
 		http_digest_init ( &ctx );
1178
 		http_digest_update ( &ctx, ha1 );
1180
 		http_digest_update ( &ctx, ha1 );
1179
 		http_digest_update ( &ctx, nonce );
1181
 		http_digest_update ( &ctx, nonce );
1180
 		http_digest_update ( &ctx, cnonce );
1182
 		http_digest_update ( &ctx, cnonce );
1181
-		http_digest_final ( &ctx, ha1 );
1183
+		http_digest_final ( &ctx, ha1, sizeof ( ha1 ) );
1182
 	}
1184
 	}
1183
 
1185
 
1184
 	/* Generate HA2 */
1186
 	/* Generate HA2 */
1185
 	http_digest_init ( &ctx );
1187
 	http_digest_init ( &ctx );
1186
 	http_digest_update ( &ctx, method );
1188
 	http_digest_update ( &ctx, method );
1187
 	http_digest_update ( &ctx, uri );
1189
 	http_digest_update ( &ctx, uri );
1188
-	http_digest_final ( &ctx, ha2 );
1190
+	http_digest_final ( &ctx, ha2, sizeof ( ha2 ) );
1189
 
1191
 
1190
 	/* Generate response */
1192
 	/* Generate response */
1191
 	http_digest_init ( &ctx );
1193
 	http_digest_init ( &ctx );
1197
 		http_digest_update ( &ctx, "auth" /* qop */ );
1199
 		http_digest_update ( &ctx, "auth" /* qop */ );
1198
 	}
1200
 	}
1199
 	http_digest_update ( &ctx, ha2 );
1201
 	http_digest_update ( &ctx, ha2 );
1200
-	http_digest_final ( &ctx, response );
1202
+	http_digest_final ( &ctx, response, sizeof ( response ) );
1201
 
1203
 
1202
 	/* Generate the authorisation string */
1204
 	/* Generate the authorisation string */
1203
 	len = asprintf ( &auth, "Authorization: Digest username=\"%s\", "
1205
 	len = asprintf ( &auth, "Authorization: Digest username=\"%s\", "

+ 8
- 6
src/net/tcp/iscsi.c View File

709
 		char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
709
 		char buf[ base16_encoded_len ( iscsi->chap.response_len ) + 1 ];
710
 		assert ( iscsi->initiator_username != NULL );
710
 		assert ( iscsi->initiator_username != NULL );
711
 		base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
711
 		base16_encode ( iscsi->chap.response, iscsi->chap.response_len,
712
-				buf );
712
+				buf, sizeof ( buf ) );
713
 		used += ssnprintf ( data + used, len - used,
713
 		used += ssnprintf ( data + used, len - used,
714
 				    "CHAP_N=%s%cCHAP_R=0x%s%c",
714
 				    "CHAP_N=%s%cCHAP_R=0x%s%c",
715
 				    iscsi->initiator_username, 0, buf, 0 );
715
 				    iscsi->initiator_username, 0, buf, 0 );
719
 		size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
719
 		size_t challenge_len = ( sizeof ( iscsi->chap_challenge ) - 1 );
720
 		char buf[ base16_encoded_len ( challenge_len ) + 1 ];
720
 		char buf[ base16_encoded_len ( challenge_len ) + 1 ];
721
 		base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
721
 		base16_encode ( ( iscsi->chap_challenge + 1 ), challenge_len,
722
-				buf );
722
+				buf, sizeof ( buf ) );
723
 		used += ssnprintf ( data + used, len - used,
723
 		used += ssnprintf ( data + used, len - used,
724
 				    "CHAP_I=%d%cCHAP_C=0x%s%c",
724
 				    "CHAP_I=%d%cCHAP_C=0x%s%c",
725
 				    iscsi->chap_challenge[0], 0, buf, 0 );
725
 				    iscsi->chap_challenge[0], 0, buf, 0 );
833
  *
833
  *
834
  * @v encoded		Encoded large binary value
834
  * @v encoded		Encoded large binary value
835
  * @v raw		Raw data
835
  * @v raw		Raw data
836
+ * @v len		Length of data buffer
836
  * @ret len		Length of raw data, or negative error
837
  * @ret len		Length of raw data, or negative error
837
  */
838
  */
838
-static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw ) {
839
+static int iscsi_large_binary_decode ( const char *encoded, uint8_t *raw,
840
+				       size_t len ) {
839
 
841
 
840
 	/* Check for initial '0x' or '0b' and decode as appropriate */
842
 	/* Check for initial '0x' or '0b' and decode as appropriate */
841
 	if ( *(encoded++) == '0' ) {
843
 	if ( *(encoded++) == '0' ) {
842
 		switch ( tolower ( *(encoded++) ) ) {
844
 		switch ( tolower ( *(encoded++) ) ) {
843
 		case 'x' :
845
 		case 'x' :
844
-			return base16_decode ( encoded, raw );
846
+			return base16_decode ( encoded, raw, len );
845
 		case 'b' :
847
 		case 'b' :
846
 			return base64_decode ( encoded, raw );
848
 			return base64_decode ( encoded, raw );
847
 		}
849
 		}
980
 	int rc;
982
 	int rc;
981
 
983
 
982
 	/* Process challenge */
984
 	/* Process challenge */
983
-	len = iscsi_large_binary_decode ( value, buf );
985
+	len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) );
984
 	if ( len < 0 ) {
986
 	if ( len < 0 ) {
985
 		rc = len;
987
 		rc = len;
986
 		DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
988
 		DBGC ( iscsi, "iSCSI %p invalid CHAP challenge \"%s\": %s\n",
1065
 	chap_respond ( &iscsi->chap );
1067
 	chap_respond ( &iscsi->chap );
1066
 
1068
 
1067
 	/* Process response */
1069
 	/* Process response */
1068
-	len = iscsi_large_binary_decode ( value, buf );
1070
+	len = iscsi_large_binary_decode ( value, buf, sizeof ( buf ) );
1069
 	if ( len < 0 ) {
1071
 	if ( len < 0 ) {
1070
 		rc = len;
1072
 		rc = len;
1071
 		DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",
1073
 		DBGC ( iscsi, "iSCSI %p invalid CHAP response \"%s\": %s\n",

+ 29
- 17
src/tests/base16_test.c View File

77
  * Report a base16 encoding test result
77
  * Report a base16 encoding test result
78
  *
78
  *
79
  * @v test		Base16 test
79
  * @v test		Base16 test
80
+ * @v file		Test code file
81
+ * @v line		Test code line
80
  */
82
  */
81
-#define base16_encode_ok( test ) do {					\
82
-	size_t len = base16_encoded_len ( (test)->len );		\
83
-	char buf[ len + 1 /* NUL */ ];					\
84
-	ok ( len == strlen ( (test)->encoded ) );			\
85
-	base16_encode ( (test)->data, (test)->len, buf );		\
86
-	ok ( strcmp ( (test)->encoded, buf ) == 0 );			\
87
-	} while ( 0 )
83
+static void base16_encode_okx ( struct base16_test *test, const char *file,
84
+				unsigned int line ) {
85
+	size_t len = base16_encoded_len ( test->len );
86
+	char buf[ len + 1 /* NUL */ ];
87
+	size_t check_len;
88
+
89
+	okx ( len == strlen ( test->encoded ), file, line );
90
+	check_len = base16_encode ( test->data, test->len, buf, sizeof ( buf ));
91
+	okx ( check_len == len, file, line );
92
+	okx ( strcmp ( test->encoded, buf ) == 0, file, line );
93
+}
94
+#define base16_encode_ok( test ) base16_encode_okx ( test, __FILE__, __LINE__ )
88
 
95
 
89
 /**
96
 /**
90
  * Report a base16 decoding test result
97
  * Report a base16 decoding test result
91
  *
98
  *
92
  * @v test		Base16 test
99
  * @v test		Base16 test
100
+ * @v file		Test code file
101
+ * @v line		Test code line
93
  */
102
  */
94
-#define base16_decode_ok( test ) do {					\
95
-	size_t max_len = base16_decoded_max_len ( (test)->encoded );	\
96
-	uint8_t buf[max_len];						\
97
-	int len;							\
98
-	len = base16_decode ( (test)->encoded, buf );			\
99
-	ok ( len >= 0 );						\
100
-	ok ( ( size_t ) len <= max_len );				\
101
-	ok ( ( size_t ) len == (test)->len );				\
102
-	ok ( memcmp ( (test)->data, buf, len ) == 0 );			\
103
-	} while ( 0 )
103
+static void base16_decode_okx ( struct base16_test *test, const char *file,
104
+				unsigned int line ) {
105
+	size_t max_len = base16_decoded_max_len ( test->encoded );
106
+	uint8_t buf[max_len];
107
+	int len;
108
+
109
+	len = base16_decode ( test->encoded, buf, sizeof ( buf ) );
110
+	okx ( len >= 0, file, line );
111
+	okx ( ( size_t ) len <= max_len, file, line );
112
+	okx ( ( size_t ) len == test->len, file, line );
113
+	okx ( memcmp ( test->data, buf, len ) == 0, file, line );
114
+}
115
+#define base16_decode_ok( test ) base16_decode_okx ( test, __FILE__, __LINE__ )
104
 
116
 
105
 /**
117
 /**
106
  * Perform Base16 self-tests
118
  * Perform Base16 self-tests

Loading…
Cancel
Save