c++gccscanfwstringunnamed-namespace

Strange behavior (unnamed namespace with swscanf)


I have the next experimental code. That code fail with segmentation fault on the labeled line.

If I take out the str2MxfKey function from anonymous namespace or give a some name to namespace, code will run without any problem.

That strange behavior reproduced only on the release build. Could someone explain me root cause of that problem?

Ubuntu 22.04, cmake 3.22.1, gcc 11.3.0

struct mxfKey
{
    uint8_t octet0;
    uint8_t octet1;
    uint8_t octet2;
    uint8_t octet3;
    uint8_t octet4;
    uint8_t octet5;
    uint8_t octet6;
    uint8_t octet7;
    uint8_t octet8;
    uint8_t octet9;
    uint8_t octet10;
    uint8_t octet11;
    uint8_t octet12;
    uint8_t octet13;
    uint8_t octet14;
    uint8_t octet15;
};

namespace {
    mxfKey str2MxfKey(const std::wstring &str) {
        mxfKey k;

        int rc = swscanf(str.c_str(),
                         L"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", // mxfkey
                         &k.octet0, &k.octet1, &k.octet2, &k.octet3,
                         &k.octet4, &k.octet5, &k.octet6, &k.octet7,
                         &k.octet8, &k.octet9, &k.octet10, &k.octet11,
                         &k.octet12, &k.octet13, &k.octet14, &k.octet15);
        if (rc != 16) {
            throw std::runtime_error("Error in str2MxfKey");
        }
        return k;
    }
}

void someExperiments() {
    std::wstring wstr = L"8c2197ad00e9476b8213b367123e506e";

    std::wcout << "Start" << std::endl;
    str2MxfKey(wstr);
    std::wcout << wstr << std::endl; // <----  Segmentation fault (core dumped)
    std::wcout << "End" << std::endl;
}

int main(int argc, char* argv[]) {
    someExperiments();
    ...
}

Solution

  • The swscanf format string is wrong. %02x expects an unsigned int and not uint8_t.

    Try this instead:

        int rc = swscanf(str.c_str(),
            L"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", // mxfkey
            &k.octet0, &k.octet1, &k.octet2, &k.octet3,
            &k.octet4, &k.octet5, &k.octet6, &k.octet7,
            &k.octet8, &k.octet9, &k.octet10, &k.octet11,
            &k.octet12, &k.octet13, &k.octet14, &k.octet15);