# Commonly recurring errors in bmcweb

What follows is a list of common errors that new users to bmcweb tend to make
when operating within its bounds for the first time. If this is your first time
developing in bmcweb, the maintainers highly recommend reading and understanding
_all_ of common traps before continuing with any development. Every single one
of the examples below compile without warnings, but are incorrect in
not-always-obvious ways, or impose a pattern that tends to cause hard to find
bugs, or bugs that appear later. Every one has been submitted to code review
multiple times.

## 1. Directly dereferencing a pointer without checking for validity first

```cpp
int myBadMethod(const nlohmann::json& j){
    const int* myPtr = j.get_if<int>();
    return *myPtr;
}
```

This pointer is not guaranteed to be filled, and could be a null dereference.

## 2. String views aren't null terminated

```cpp
int getIntFromString(std::string_view s){
    return std::atoi(s.data());
}
```

This will give the right answer much of the time, but has the possibility to
fail when `string_view` is not null terminated. Use `from_chars` instead, which
takes both a pointer and a length

## 3. Not handling input errors

```cpp
int getIntFromString(const std::string& s){
    return std::atoi(s.c_str());
}
```

In the case where the string is not representable as an int, this will trigger
undefined behavior at system level. Code needs to check for validity of the
string, ideally with something like `from_chars`, and return the appropriate
error code.

## 4. Walking off the end of a string

```cpp
std::string getFilenameFromPath(const std::string& path){
    size_t index = path.find("/");
    if (index != std::string::npos){
        // If the string ends with "/", this will walk off the end of the string.
        return path.substr(pos + 1);
    }
    return "";
}
```

## 5. Using methods that throw (or not handling bad inputs)

```cpp
int myBadMethod(nlohmann::json& j){
    return j.get<int>();
}
```

This method throws, and bad inputs will not be handled

Commonly used methods that fall into this pattern:

- std::variant::get
- std::vector::at
- std::map::at
- std::set::at
- std::\<generic container type\>::at
- nlohmann::json::operator!=
- nlohmann::json::operator+=
- nlohmann::json::at
- nlohmann::json::get
- nlohmann::json::get_ref
- nlohmann::json::get_to
- nlohmann::json::operator\<\<
- nlohmann::json::operator\>\>
- std::filesystem::create_directory
- std::filesystem::rename
- std::filesystem::file_size
- std::stoi
- std::stol
- std::stoll

### Special note: JSON

`nlohmann::json::parse` by default
[throws](https://json.nlohmann.me/api/basic_json/parse/) on failure, but also
accepts an optional argument that causes it to not throw: set the 3rd argument
to `false`.

`nlohmann::json::dump` by default
[throws](https://json.nlohmann.me/api/basic_json/dump/) on failure, but also
accepts an optional argument that causes it to not throw: set the 4th argument
to `replace`. Although `ignore` preserves content 1:1, `replace` is preferred
from a security point of view.

### Special note: Boost

there is a whole class of boost asio functions that provide both a method that
throws on failure, and a method that accepts and returns an error code. This is
not a complete list, but users should verify in the boost docs when calling into
asio methods, and prefer the one that returns an error code instead of throwing.

- boost::asio::ip::tcp::acceptor::bind();
- boost::asio::ip::tcp::acceptor::cancel();
- boost::asio::ip::tcp::acceptor::close();
- boost::asio::ip::tcp::acceptor::listen();
- boost::asio::ip::address::make_address();

## 6. Blocking functions

bmcweb uses a single reactor for all operations. Blocking that reactor for any
amount of time causes all other operations to stop. The common blocking
functions that tend to be called incorrectly are:

- sleep()
- boost::asio::ip::tcp::socket::read()
- boost::asio::ip::tcp::socket::read_some()
- boost::asio::ip::tcp::socket::write()
- boost::asio::ip::tcp::socket::write_some()
- boost::asio::ip::tcp::socket::connect()
- boost::asio::ip::tcp::socket::send()
- boost::asio::ip::tcp::socket::wait()
- boost::asio::steady_timer::wait()

Note: an exception is made for filesystem/disk IO read and write. This is mostly
due to not having great abstractions for it that mate well with the async
system, the fact that most filesystem accesses are into tmpfs (and therefore
should be "fast" most of the time) and in general how little the filesystem is
used in practice.

## 7. Lack of locking between subsequent calls

While global data structures are discouraged, they are sometimes required to
store temporary state for operations that require it. Given the single threaded
nature of bmcweb, they are not required to be explicitly threadsafe, but they
must be always left in a valid state, and checked for other uses before
occupying.

```cpp
std::optional<std::string> currentOperation;
void firstCallbackInFlow(){
    currentOperation = "Foo";
}
void secondCallbackInFlow(){
    currentOperation.reset();
}
```

In the above case, the first callback needs a check to ensure that
currentOperation is not already being used.

## 8. Wildcard reference captures in lambdas

```cpp
std::string x; auto mylambda = [&](){
    x = "foo";
}
do_async_read(mylambda)
```

Numerous times, lifetime issues of const references have been injected into
async bmcweb code. While capturing by reference can be useful, given how
difficult these types of bugs are to triage, bmcweb explicitly requires that all
code captures variables by name explicitly, and calls out each variable being
captured by value or by reference. The above prototypes would change to
`[&x]()...` Which makes clear that x is captured, and its lifetime needs
tracked.

## 9. URLs should end in "/"

```cpp
BMCWEB("/foo/bar");
```

Unless you explicitly have a reason not to (as there is one known exception
where the behavior must differ) all URL handlers should end in "/". The bmcweb
route handler will detect routes ending in slash and generate routes for both
the route ending in slash and the one without. This allows both URLs to be used
by users. While many specifications do not require this, it resolves a whole
class of bug that we've seen in the past.

## 10. URLs constructed in aggregate

```cpp
std::string routeStart = "/redfish/v1";

BMCWEB_ROUTE(routestart + "/SessionService/")
```

Very commonly, bmcweb maintainers and contributors alike have to do audits of
all routes that are available, to verify things like security and documentation
accuracy. While these processes are largely manual, they can mostly be conducted
by a simple grep statement to search for urls in question. Doing the above makes
the route handlers no longer greppable, and complicates bmcweb patchsets as a
whole.

## 11. Not responding to 404

```cpp
BMCWEB_ROUTE("/myendpoint/<str>",
    [](Request& req, Response& res, const std::string& id){
     managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
          [asyncResp](const boost::system::error_code& ec,
                      const std::string& myProperty) {
              if (ec)
              {
                  messages::internalError(asyncResp->res);
                  return;
              }
              ... handle code
          },
          "xyz.openbmc_project.Logging",
          "/xyz/openbmc_project/mypath/" + id,
          "xyz.MyInterface", "GetAll", "");
});
```

All bmcweb routes should handle 404 (not found) properly, and return it where
appropriate. 500 internal error is not a substitute for this, and should be only
used if there isn't a more appropriate error code that can be returned. This is
important, because a number of vulnerability scanners attempt injection attacks
in the form of `/myendpoint/foobar`, or `/myendpoint/#$*(%)&#%$)(\*&` in an
attempt to circumvent security. If the server returns 500 to any of these
requests, the security scanner logs it as an error for followup. While in
general these errors are benign, and not actually a real security threat, having
a clean security run allows maintainers to minimize the amount of time spent
triaging issues reported from these scanning tools.

An implementation of the above that handles 404 would look like:

```cpp
BMCWEB_ROUTE("/myendpoint/<str>",
    [](Request& req, Response& res, const std::string& id){
     managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
          [asyncResp](const boost::system::error_code& ec,
                      const std::string& myProperty) {
              if (ec == <error code that gets returned by not found>){
                  messages::resourceNotFound(res);
                  return;
              }
              if (ec)
              {
                  messages::internalError(asyncResp->res);
                  return;
              }
              ... handle code
          },
          "xyz.openbmc_project.Logging",
          "/xyz/openbmc_project/mypath/" + id,
          "xyz.MyInterface", "GetAll", "");
});
```

Note: A more general form of this rule is that no handler should ever return 500
on a working system, and any cases where 500 is found, can immediately be
assumed to be
[a bug in either the system, or bmcweb.](https://github.com/openbmc/bmcweb/blob/master/DEVELOPING.md#error-handling)

## 12. Imprecise matching

```cpp
void isInventoryPath(const std::string& path){
    if (path.find("inventory")){
        return true;
    }
    return false;
}
```

When matching dbus paths, HTTP fields, interface names, care should be taken to
avoid doing direct string containment matching. Doing so can lead to errors
where fan1 and fan11 both report to the same object, and cause behavior breaks
in subtle ways.

When using dbus paths, rely on the methods on `sdbusplus::message::object_path`.
When parsing HTTP field and lists, use the RFC7230 implementations from
boost::beast.

Other commonly misused methods are: boost::iequals. Unless the standard you're
implementing (as is the case in some HTTP fields) requires case insensitive
comparisons, casing should be obeyed, especially when relying on user-driven
data.

- boost::starts_with
- boost::ends_with
- std::string::starts_with
- std::string::ends_with
- std::string::rfind

The above methods tend to be misused to accept user data and parse various
fields from it. In practice, there tends to be better, purpose built methods for
removing just the field you need.

## 13. Complete replacement of the response object

```cpp
void getMembers(crow::Response& res){
  res.jsonValue = {{"Value", 2}};
}
```

In many cases, bmcweb is doing multiple async actions in parallel, and
orthogonal keys within the Response object might be filled in from another task.
Completely replacing the json object can lead to convoluted situations where the
output of the response is dependent on the _order_ of the asynchronous actions
completing, which cannot be guaranteed, and has many time caused bugs.

```cpp
void getMembers(crow::Response& res){
  res.jsonValue["Value"] = 2;
}
```

As an added benefit, this code is also more efficient, as it avoids the
intermediate object construction and the move, and as a result, produces smaller
binaries.

Note, another form of this error involves calling nlohmann::json::reset(), to
clear an object that's already been filled in. This has the potential to clear
correct data that was already filled in from other sources.
