1

In order to implement a client to some protocol that expects null-byte padding to a specific string, I implemented a functions that pads a string with a specific amount of null bytes:

string padToFill(string s, int fill){
    int len = s.length();
    if (len < fill){
        for (int i = 0; i < fill - len; i++){
            s.append("\0");
        }
    }
    return s;
}

However, in practice, the result I am getting from this function is identical to the string I am getting as argument. So for example padToFill("foo", 5) is foo and not foo\0\0. Even tho c++ strings are expected to handle null bytes as any other character.

How do I achieve the desired null padding?

ring0
  • 33
  • 3
  • 2
    how do you inspect the string ? A `std::string` can have many `\0` at the end, but there are some pitfalls that could lead you to believe that there are none. The code you posted looks ok. What is the code you used to see how many null terminators are in the result? – 463035818_is_not_an_ai Nov 08 '22 at 13:44
  • 2
    `s.push_back('\0');` Note that `std::string` already manages a `\0`-terminator at the end of the string, which is **not** part of the length. If you push back additional `\0`-terminators, those **will be** part of the length (and there will still be the additional not counted `\0`-terminated caboose). – Eljay Nov 08 '22 at 13:44
  • @ring0 As for me then I have understood nothing. – Vlad from Moscow Nov 08 '22 at 13:47
  • sorry I was too fast with saying the code is fine. It isnt. Anyhow, adding how you know that the function doesnt work would be good – 463035818_is_not_an_ai Nov 08 '22 at 13:47
  • You are calling this function: string& append (const char* s); so you are appending a c string... – L.C. Nov 08 '22 at 13:49
  • @463035818_is_not_a_number I also thought that the debugger didn't show the null bytes to me. This is not the case. I am using gdb with CLion and I checked the size of the string and it did not change either. I also tried to convert the string to a vector of chars and there I can explicitly see that there are no null bytes. – ring0 Nov 08 '22 at 13:50
  • @ring0 In `s.append("\0");`, `"\0"` is treated the same as `""`, which is why `s` doesn't change. You could use `s.append("\0", 1);` instead, or `s.append(1, '\0');`, or `s.append({'\0'});` But `s.push_back('\0');` would be clearer, as Eljay suggested. – Remy Lebeau Nov 08 '22 at 19:20

1 Answers1

11

The append overload you're using accepts a C string, which is null-terminated (that is: the first null-byte marks its end).

The easiest way here is probably to use a different overload of append:

  s.append(fill - len, '\0');

Note that this requires C++20. For older C++ standards, there's

   s.resize(fill, '\0');

or just

   s.resize(fill);

Come to think of it, this may be a clearer way to describe what you're doing, anyway. I like the second option here for clarity.

Wintermute
  • 42,983
  • 5
  • 77
  • 80