Skip to content

Commit ead40c5

Browse files
authored
refactor: make s2n_array_len constant (#4801)
1 parent 0983bee commit ead40c5

7 files changed

+50
-7
lines changed

codebuild/bin/grep_simple_mistakes.sh

+2-3
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,10 @@ done
9393
#############################################
9494
S2N_FILES_ARRAY_SIZING_RETURN=$(find "$PWD" -type f -name "s2n*.c" -path "*")
9595
for file in $S2N_FILES_ARRAY_SIZING_RETURN; do
96-
RESULT_ARR_DIV=`grep -Ern 'sizeof\((.*)\) \/ sizeof\(\1\[0\]\)' $file`
97-
96+
RESULT_ARR_DIV=`grep -Ern 'sizeof\(.*?\) / sizeof\(' $file`
9897
if [ "${#RESULT_ARR_DIV}" != "0" ]; then
9998
FAILED=1
100-
printf "\e[1;34mUsage of 'sizeof(array) / sizeof(array[0])' check failed. Use s2n_array_len(array) instead in $file:\e[0m\n$RESULT_ARR_DIV\n\n"
99+
printf "\e[1;34mUsage of 'sizeof(array) / sizeof(T)' check failed. Use s2n_array_len instead in $file:\e[0m\n$RESULT_ARR_DIV\n\n"
101100
fi
102101
done
103102

tests/unit/s2n_certificate_parsing_test.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ int main(int argc, char **argv)
7777
CERTIFICATE_2,
7878
CERTIFICATE_3,
7979
};
80-
struct s2n_blob expected_certs[sizeof(expected_cert_strs) / sizeof(char *)] = { 0 };
80+
struct s2n_blob expected_certs[s2n_array_len(expected_cert_strs)] = { 0 };
8181
EXPECT_EQUAL(s2n_array_len(expected_certs), s2n_array_len(expected_cert_strs));
8282

8383
for (size_t i = 0; i < s2n_array_len(expected_certs); i++) {

tests/unit/s2n_safety_test.c

+12
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,18 @@ int main(int argc, char **argv)
445445
}
446446
}
447447

448+
/* Test: s2n_array_len */
449+
{
450+
/* Must return correct length */
451+
uint16_t test_data[10] = { 0 };
452+
EXPECT_EQUAL(s2n_array_len(test_data), 10);
453+
EXPECT_NOT_EQUAL(s2n_array_len(test_data), sizeof(test_data));
454+
455+
/* Must be usable as an array size / constant expression */
456+
uint16_t test_data_dup[s2n_array_len(test_data)] = { 0 };
457+
EXPECT_EQUAL(sizeof(test_data), sizeof(test_data_dup));
458+
}
459+
448460
END_TEST();
449461
return 0;
450462
}

tests/unit/s2n_server_alpn_extension_test.c

+26
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,32 @@ int main(int argc, char **argv)
120120
EXPECT_SUCCESS(s2n_connection_free(server_conn));
121121
};
122122

123+
/* Send and receive maximum-sized alpn */
124+
{
125+
const uint8_t max_size = UINT8_MAX;
126+
127+
DEFER_CLEANUP(struct s2n_connection *client = s2n_connection_new(S2N_CLIENT),
128+
s2n_connection_ptr_free);
129+
EXPECT_NOT_NULL(client);
130+
EXPECT_NULL(s2n_get_application_protocol(client));
131+
132+
DEFER_CLEANUP(struct s2n_connection *server = s2n_connection_new(S2N_SERVER),
133+
s2n_connection_ptr_free);
134+
EXPECT_NOT_NULL(server);
135+
memset(server->application_protocol, 'a', sizeof(server->application_protocol) - 1);
136+
137+
DEFER_CLEANUP(struct s2n_stuffer stuffer = { 0 }, s2n_stuffer_free);
138+
EXPECT_SUCCESS(s2n_stuffer_growable_alloc(&stuffer, 0));
139+
EXPECT_SUCCESS(s2n_server_alpn_extension.send(server, &stuffer));
140+
EXPECT_SUCCESS(s2n_server_alpn_extension.recv(client, &stuffer));
141+
EXPECT_EQUAL(s2n_stuffer_data_available(&stuffer), 0);
142+
143+
const char *client_alpn = s2n_get_application_protocol(client);
144+
EXPECT_NOT_NULL(client_alpn);
145+
EXPECT_EQUAL(strlen(client_alpn), max_size);
146+
EXPECT_STRING_EQUAL(client_alpn, server->application_protocol);
147+
};
148+
123149
END_TEST();
124150
return 0;
125151
}

tls/extensions/s2n_server_alpn.c

-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ static int s2n_alpn_recv(struct s2n_connection *conn, struct s2n_stuffer *extens
6666

6767
uint8_t protocol_len = 0;
6868
POSIX_GUARD(s2n_stuffer_read_uint8(extension, &protocol_len));
69-
POSIX_ENSURE_LT(protocol_len, s2n_array_len(conn->application_protocol));
7069

7170
uint8_t *protocol = s2n_stuffer_raw_read(extension, protocol_len);
7271
POSIX_ENSURE_REF(protocol);

tls/s2n_cipher_suites.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ int s2n_cipher_suites_init(void)
10681068
/* Reset any selected record algorithms */
10691069
S2N_RESULT s2n_cipher_suites_cleanup(void)
10701070
{
1071-
const int num_cipher_suites = sizeof(s2n_all_cipher_suites) / sizeof(struct s2n_cipher_suite *);
1071+
const int num_cipher_suites = s2n_array_len(s2n_all_cipher_suites);
10721072
for (int i = 0; i < num_cipher_suites; i++) {
10731073
struct s2n_cipher_suite *cur_suite = s2n_all_cipher_suites[i];
10741074
cur_suite->available = 0;

utils/s2n_safety.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,14 @@ S2N_CLEANUP_RESULT s2n_connection_apply_error_blinding(struct s2n_connection** c
9797
} \
9898
struct __useless_struct_to_allow_trailing_semicolon__
9999

100-
#define s2n_array_len(array) ((array != NULL) ? (sizeof(array) / sizeof(array[0])) : 0)
100+
/* This method works for ARRAYS, not for POINTERS.
101+
* Calling sizeof on an array declared in the current function correctly returns
102+
* the total size of the array. But once the array is passed to another function,
103+
* it behaves like a pointer. Calling sizeof on a pointer only returns the size
104+
* of the pointer address itself (so usually 8).
105+
* Newer compilers (gcc >= 8.1, clang >= 8.0) will warn if the argument is a pointer.
106+
*/
107+
#define s2n_array_len(array) (sizeof(array) / sizeof(array[0]))
101108

102109
int s2n_mul_overflow(uint32_t a, uint32_t b, uint32_t* out);
103110

0 commit comments

Comments
 (0)