эквивалент strncpy для std::string?

Есть ли точный эквивалент strncpy в стандартной библиотеке C++? Я имею в виду функцию, которая копирует строку из одного буфера в другой до тех пор, пока она не достигнет конечного 0? Например, когда мне нужно разобрать строки из небезопасного источника, такого как TCP-пакеты, чтобы я мог выполнить проверку длины при копировании данных.

Я уже много искал на эту тему и нашел несколько интересных тем, но все эти люди были довольны std::string::assign, которая также может принимать размер символов для копирования в качестве параметра. Моя проблема с этой функцией заключается в том, что она не делает никаких проверок, не был ли уже достигнут завершающий нуль - она принимает серьезный заданный размер и копирует данные так же, как memcpy делает это в буфер строки. Таким образом выделяется и копируется гораздо больше памяти, чем нужно было бы сделать, если бы при копировании была такая проверка. 

Именно так я сейчас решаю эту проблему, но есть некоторые накладные расходы, которых я хотел бы избежать:

    // Get RVA of export name
    const ExportDirectory_t *pED = (const ExportDirectory_t*)rva2ptr(exportRVA);
    sSRA nameSra = rva2sra(pED->Name);

    // Copy it into my buffer
    char *szExportName = new char[nameSra.numBytesToSectionsEnd];
    strncpy(szExportName, 
            nameSra.pSection->pRawData->constPtr<char>(nameSra.offset),
            nameSra.numBytesToSectionsEnd);
    szExportName[nameSra.numBytesToSectionsEnd - 1] = 0;

    m_exportName = szExportName;
    delete [] szExportName;

Этот кусок кода является частью моего парсера для PE-бинаров (точнее, подпрограммы, разбирающей таблицу экспорта). rva2sra преобразует относительный виртуальный адрес в относительный адрес PE-секции. Структура ExportDirectory_t содержит RVA к экспортному имени двоичного файла, которое должно быть строкой с нулевым окончанием. Но это не всегда должно быть так - если кто-то захочет, он сможет опустить завершающий ноль, который заставит мою программу забежать в память, не принадлежащую секции, где она в конце концов завершится (в лучшем случае...).

Реализовать такую функцию самостоятельно не составит большого труда, но я бы предпочел, чтобы такое решение было реализовано в стандартной библиотеке C++.

7
задан Adrian 25 May 2013 в 00:53
поделиться