Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-55381

StringData find and rfind incorrect results

    • Type: Icon: Bug Bug
    • Resolution: Fixed
    • Priority: Icon: Major - P3 Major - P3
    • 5.0.0-rc0
    • Affects Version/s: None
    • Component/s: Internal Code
    • None
    • Fully Compatible
    • ALL
    • Service Arch 2021-03-22, Service Arch 2021-04-05

      std::string and std::string_view have a precise definition for find which specifies what should happen when searching for an empty substring.

      http://eel.is/c++draft/string.find
      http://eel.is/c++draft/string.view#find
      https://en.cppreference.com/w/cpp/string/basic_string/find

      This confusion is the reason SERVER-55180 was reverted.
      https://github.com/mongodb/mongo/blob/388ce132e9edd64cbfdf677a87ac5044ca3a79ed/src/mongo/db/exec/sbe/vm/vm.cpp#L1978
      Changing a value's type from std::string_view to StringData changed the meaning of find.

      If a StringData member function has the same name as a std::string or std::string_view member function, it should do exactly the same thing.

      StringData::find:
      https://github.com/mongodb/mongo/blob/master/src/mongo/base/string_data.h#L283

      if (needleSize == 0)
              return 0;
      

      Even if the needleSize is 0, we started looking at position pos so returning zero is incorrect. An empty string is considered found at the leftmost valid position in the search range.

      Although StringData::find(substr,pos) takes 2 arguments, none of the tests for StringData ever specify the pos argument, and this function was essentially untested.

      Fortunately this bug has no effect unless the pos is given, and very few callers give the pos argument.

      There appear to be only two call sites that give the pos argument:

      src/mongo/util/net/ssl_util.cpp|44 col 34| size_t headerPosition = blob.find(header, position);
      src/mongo/util/net/ssl_util.cpp|54 col 35| size_t trailerPosition = blob.find(trailer, headerPosition);
      

      And these two callers are assured that the header and trailer substrings are not empty because they were constructed locally.

            Assignee:
            billy.donahue@mongodb.com Billy Donahue
            Reporter:
            billy.donahue@mongodb.com Billy Donahue
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: