1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 /*
17  * The goal of s2n_result is to provide a strongly-typed error
18  * signal value, which provides the compiler with enough information
19  * to catch bugs.
20  *
21  * Historically, s2n has used int to signal errors. This has caused a few issues:
22  *
23  * ## GUARD in a function returning integer types
24  *
25  * There is no compiler error if `GUARD(nested_call());` is used in a function
26  * that is meant to return integer type - not a error signal.
27  *
28  * ```c
29  * uint8_t s2n_answer_to_the_ultimate_question() {
30  *   POSIX_GUARD(s2n_sleep_for_years(7500000));
31  *   return 42;
32  * }
33  * ```
34  *
35  * In this function we intended to return a `uint8_t` but used a
36  * `GUARD` which will return -1 if the call fails. This can lead to
37  * very subtle bugs.
38  *
39  * ## `GUARD`ing a function returning any integer type
40  *
41  * There is no compiler error if `GUARD(nested_call());` is used
42  * on a function that doesn't actually return an error signal
43  *
44  * ```c
45  * int s2n_deep_thought() {
46  *   POSIX_GUARD(s2n_answer_to_the_ultimate_question());
47  *   return 0;
48  * }
49  * ```
50  *
51  * In this function we intended guard against a failure of
52  * `s2n_answer_to_the_ultimate_question` but that function doesn't
53  * actually return an error signal. Again, this can lead to sublte
54  * bugs.
55  *
56  * ## Ignored error signals
57  *
58  * Without the `warn_unused_result` function attribute, the compiler
59  * provides no warning when forgetting to `GUARD` a function. Missing
60  * a `GUARD` can lead to subtle bugs.
61  *
62  * ```c
63  * int s2n_answer_to_the_ultimate_question() {
64  *   s2n_sleep_for_years(7500000); // <- THIS SHOULD BE GUARDED!!!
65  *   return 42;
66  * }
67  * ```
68  *
69  * # Solution
70  *
71  * s2n_result provides a newtype declaration, which is popular in
72  * languages like [Haskell](https://wiki.haskell.org/Newtype) and
73  * [Rust](https://doc.rust-lang.org/rust-by-example/generics/new_types.html).
74  *
75  * Functions that return S2N_RESULT are automatically marked with the
76  * `warn_unused_result` attribute, which ensures they are GUARDed.
77  */
78 
79 #include <s2n.h>
80 #include <stdbool.h>
81 #include "utils/s2n_result.h"
82 
83 /* returns true when the result is S2N_RESULT_OK */
s2n_result_is_ok(s2n_result result)84 inline bool s2n_result_is_ok(s2n_result result)
85 {
86     return result.__error_signal == S2N_SUCCESS;
87 }
88 
89 /* returns true when the result is S2N_RESULT_ERROR */
s2n_result_is_error(s2n_result result)90 inline bool s2n_result_is_error(s2n_result result)
91 {
92     return result.__error_signal == S2N_FAILURE;
93 }
94 
95 /* ignores the returned result of a function */
s2n_result_ignore(s2n_result result)96 inline void s2n_result_ignore(s2n_result result)
97 {
98     /* noop */
99 }
100