首页 > 解决方案 > 当字符串包含 %2C 时,C++ 中的 std::string 不完整

问题描述


直接看我的答案,忽略下面的文字...

我正在尝试通过 C++ 使用 openssl CLI 读取 x509 证书。(是的,我知道 OpenSSL 也有一个 C API,但这对我的问题并不重要)。OpenSSL 版本是 1.1.0g,gcc 编译器是 7.4.0

所以,我想执行命令openssl x509 -noout -text -in certFile.cer并获取输出。

我尝试使用三种不同的 C++ 解决方案:

这是我正在使用的一段代码(如您所见,我还尝试添加stdbuf -o 0以避免缓冲)

string execCommandAndGetOutput_withPopen(const char* cmd, int* result)
{
        std::array<char, 1024> buffer;
        std::string output;
        string cmd_unbuf;
        cmd_unbuf.append("stdbuf -o 0 ");
        cmd_unbuf.append(cmd);
        cmd_unbuf.append(" 2>&1");
        FILE* pipe = popen(cmd_unbuf.c_str(), "r");
        if (!pipe) {
              throw std::runtime_error("popen() failed!");
        }
        while (fgets(buffer.data(), buffer.size(), pipe) != nullptr) {
              output += buffer.data();
        }
        *result = pclose(pipe);
        return output;
}

string execCommandAndGetOutput_withSystem(const char* cmd, int* result)
{
        std::string output;
        string cmd_unbuf;
        cmd_unbuf.append("stdbuf -o 0 ");
        cmd_unbuf.append(cmd);
        cmd_unbuf.append(" > /tmp/temp 2>&1");
        int  cmdResult = system(cmd_unbuf.c_str());
        std::ifstream file("/tmp/temp");
        std::string fileContent((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
        remove("/tmp/temp");
        *result = cmdResult;
        return fileContent;
}

在使用第二个功能时,我尝试不删除临时文件,并检查其内容,内容是完整的。所以在system()通话中不是问题。

在所有情况下,我得到的字符串都不完整。特别是它总是停在同一点,特别是在 URL 的中间,就在%2CO. 但是AFAIK,这不应该是一个问题,%2应该只是一个昏迷,html编码。

我试图检查字符串大小,我得到的字符串有 size 4262,应该远离它的最大值。

我还在两台机器上进行了尝试:我遇到问题的第一台机器是我的所有程序都已安装,以及我得到错误的地方。在第二台机器,我的开发机器上,我只是在开发的时候运行了一些测试,我从来没有注意到这个问题,输入相同。请注意,两台机器都是 Ubuntu 服务器 18.04.3。

所以我的想法是:

我没有想法......有人有什么建议吗?一些特定的 C 库要检查?其他想法?

编辑:

即使我不会发布受影响的证书,我也可以发布受影响的行。这是完整的行:

URI:ldap://directory.swisssign.net/CN=DA32F949F851CC9871660CD9CEB6DB923F094BEF%2CO=SwissSign%2CC=CH?certificateRevocationList?base?objectClass=cRLDistributionPoint

但我只得到:

URI:ldap://directory.swisssign.net/CN=DA32F949F851CC9871660CD9CEB6DB923F094BEF

我也尝试添加| grep -A 10 'X509v3 CRL Distribution Points:'到命令中(这样我可以排除问题是字符串的长度),并且输出是相同的,字符串被截断。所以似乎问题与角色有关%2C

任何想法?

编辑2:

更改主题

编辑3:

我正在调试一个错误,这就是我打印字符串的原因......不幸的是我曾经syslog()打印过它......我想2%C被解释为format

标签: c++opensslpopenstdstring

解决方案


如果%2C在字符串中出现问题,请确保您没有使用某些使用 的函数format,例如printfsyslog

就我而言,当我调试错误时,我正在打印包含“%2C”的字符串syslog,这造成了混乱......


推荐阅读