33
33
namespace aws {
34
34
namespace lambda_runtime {
35
35
36
- static char const LOG_TAG[] = " LAMBDA_RUNTIME" ;
37
- static char const REQUEST_ID_HEADER[] = " lambda-runtime-aws-request-id" ;
38
- static char const TRACE_ID_HEADER[] = " lambda-runtime-trace-id" ;
39
- static char const CLIENT_CONTEXT_HEADER[] = " lambda-runtime-client-context" ;
40
- static char const COGNITO_IDENTITY_HEADER[] = " lambda-runtime-cognito-identity" ;
41
- static char const DEADLINE_MS_HEADER[] = " lambda-runtime-deadline-ms" ;
42
- static char const FUNCTION_ARN_HEADER[] = " lambda-runtime-invoked-function-arn" ;
36
+ static constexpr auto LOG_TAG = " LAMBDA_RUNTIME" ;
37
+ static constexpr auto REQUEST_ID_HEADER = " lambda-runtime-aws-request-id" ;
38
+ static constexpr auto TRACE_ID_HEADER = " lambda-runtime-trace-id" ;
39
+ static constexpr auto CLIENT_CONTEXT_HEADER = " lambda-runtime-client-context" ;
40
+ static constexpr auto COGNITO_IDENTITY_HEADER = " lambda-runtime-cognito-identity" ;
41
+ static constexpr auto DEADLINE_MS_HEADER = " lambda-runtime-deadline-ms" ;
42
+ static constexpr auto FUNCTION_ARN_HEADER = " lambda-runtime-invoked-function-arn" ;
43
43
44
44
enum Endpoints {
45
45
INIT,
@@ -49,8 +49,10 @@ enum Endpoints {
49
49
50
50
static bool is_success (aws::http::response_code httpcode)
51
51
{
52
+ constexpr auto http_first_success_error_code = 200 ;
53
+ constexpr auto http_last_success_error_code = 299 ;
52
54
auto const code = static_cast <int >(httpcode);
53
- return code >= 200 && code <= 299 ;
55
+ return code >= http_first_success_error_code && code <= http_last_success_error_code ;
54
56
}
55
57
56
58
static size_t write_data (char * ptr, size_t size, size_t nmemb, void * userdata)
@@ -67,13 +69,28 @@ static size_t write_data(char* ptr, size_t size, size_t nmemb, void* userdata)
67
69
return nmemb;
68
70
}
69
71
72
+ // std::isspace has a few edge cases that would trigger UB. In particular, the documentation says:
73
+ // "The behavior is undefined if the value of the input is not representable as unsigned char and is not equal to EOF."
74
+ // So, this function does the simple obvious thing instead.
70
75
static inline bool IsSpace (int ch)
71
76
{
72
- if (ch < -1 || ch > 255 ) {
73
- return false ;
77
+ constexpr int space = 0x20 ; // space (0x20, ' ')
78
+ constexpr int form_feed = 0x0c ; // form feed (0x0c, '\f')
79
+ constexpr int line_feed = 0x0a ; // line feed (0x0a, '\n')
80
+ constexpr int carriage_return = 0x0d ; // carriage return (0x0d, '\r')
81
+ constexpr int horizontal_tab = 0x09 ; // horizontal tab (0x09, '\t')
82
+ constexpr int vertical_tab = 0x0b ; // vertical tab (0x0b, '\v')
83
+ switch (ch) {
84
+ case space:
85
+ case form_feed:
86
+ case line_feed:
87
+ case carriage_return:
88
+ case horizontal_tab:
89
+ case vertical_tab:
90
+ return true ;
91
+ default :
92
+ return false ;
74
93
}
75
-
76
- return ::isspace (ch) != 0 ;
77
94
}
78
95
79
96
static inline std::string trim (std::string s)
@@ -276,7 +293,8 @@ runtime::next_outcome runtime::get_next()
276
293
277
294
if (resp.has_header (DEADLINE_MS_HEADER)) {
278
295
auto const & deadline_string = resp.get_header (DEADLINE_MS_HEADER);
279
- unsigned long ms = strtoul (deadline_string.c_str (), nullptr , 10 );
296
+ constexpr int base = 10 ;
297
+ unsigned long ms = strtoul (deadline_string.c_str (), nullptr , base);
280
298
assert (ms > 0 );
281
299
assert (ms < ULONG_MAX);
282
300
req.deadline += std::chrono::milliseconds (ms);
@@ -437,10 +455,11 @@ void run_handler(std::function<invocation_response(invocation_request const&)> c
437
455
438
456
static std::string json_escape (std::string const & in)
439
457
{
458
+ constexpr char last_non_printable_character = 31 ;
440
459
std::string out;
441
460
out.reserve (in.length ()); // most strings will end up identical
442
461
for (char ch : in) {
443
- if (ch > 31 && ch != ' \" ' && ch != ' \\ ' ) {
462
+ if (ch > last_non_printable_character && ch != ' \" ' && ch != ' \\ ' ) {
444
463
out.append (1 , ch);
445
464
}
446
465
else {
@@ -469,9 +488,10 @@ static std::string json_escape(std::string const& in)
469
488
break ;
470
489
default :
471
490
// escape and print as unicode codepoint
472
- char buf[6 ]; // 4 hex + letter 'u' + \0
473
- sprintf (buf, " u%04x" , ch);
474
- out.append (buf, 5 ); // add only five, discarding the null terminator.
491
+ constexpr int printed_unicode_length = 6 ; // 4 hex + letter 'u' + \0
492
+ std::array<char , printed_unicode_length> buf;
493
+ sprintf (buf.data (), " u%04x" , ch);
494
+ out.append (buf.data (), buf.size () - 1 ); // add only five, discarding the null terminator.
475
495
break ;
476
496
}
477
497
}
0 commit comments