mirror of
https://github.com/opencv/opencv.git
synced 2026-07-21 19:33:03 +04:00
Merge pull request #28923 from Kumataro:safeHandlingCompressedFileStorage
core: safe handling of compressed file level extension (.gz[0-9])
This commit is contained in:
@@ -306,8 +306,12 @@ public:
|
||||
before opening the file.
|
||||
@param filename Name of the file to open or the text string to read the data from.
|
||||
Extension of the file (.xml, .yml/.yaml or .json) determines its format (XML, YAML or JSON
|
||||
respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz. If both
|
||||
FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
|
||||
respectively). Also you can append .gz to work with compressed files, for example myHugeMatrix.xml.gz.
|
||||
You can also specify a compression level from 0 to 9 by appending it to the extension
|
||||
(e.g. ".gz0" for no compression, ".gz9" for high compression).
|
||||
The last digit will be truncated internally to write/read.
|
||||
(e.g. If "a.xml.gz9" is specified, "a.xml.gz" is used for the actual file name.)
|
||||
If both FileStorage::WRITE and FileStorage::MEMORY flags are specified, source is used just to specify
|
||||
the output file format (e.g. mydata.xml, .yml etc.). A file name can also contain parameters.
|
||||
You can use this format, "*?base64" (e.g. "file.json?base64" (case sensitive)), as an alternative to
|
||||
FileStorage::BASE64 flag.
|
||||
|
||||
@@ -544,18 +544,30 @@ bool FileStorage::Impl::open(const char *filename_or_buf, int _flags, const char
|
||||
flags = _flags;
|
||||
|
||||
if (!mem_mode) {
|
||||
char *dot_pos = strrchr((char *) filename.c_str(), '.');
|
||||
size_t dot_idx = filename.find_last_of('.');
|
||||
char compression = '\0';
|
||||
|
||||
if (dot_pos && dot_pos[1] == 'g' && dot_pos[2] == 'z' &&
|
||||
(dot_pos[3] == '\0' || (cv_isdigit(dot_pos[3]) && dot_pos[4] == '\0'))) {
|
||||
if (append) {
|
||||
CV_Error(cv::Error::StsNotImplemented, "Appending data to compressed file is not implemented");
|
||||
if (dot_idx != std::string::npos)
|
||||
{
|
||||
std::string ext = filename.substr(dot_idx);
|
||||
|
||||
// Instead of `ext.starts_with(".gz")
|
||||
if (ext.size() >= 3 && (ext[1] == 'g') && (ext[2] == 'z') )
|
||||
{
|
||||
if (ext.size() == 3)
|
||||
{
|
||||
// ".gz"
|
||||
isGZ = true;
|
||||
}
|
||||
|
||||
else if(ext.size() == 4 && cv_isdigit(ext[3]))
|
||||
{
|
||||
// ".gz[0-9]"
|
||||
isGZ = true;
|
||||
compression = ext[3];
|
||||
filename.pop_back(); // Replace `gz[0-9]' to 'gz'.
|
||||
}
|
||||
}
|
||||
isGZ = true;
|
||||
compression = dot_pos[3];
|
||||
if (compression)
|
||||
dot_pos[3] = '\0';
|
||||
}
|
||||
|
||||
if (!isGZ) {
|
||||
@@ -567,6 +579,9 @@ bool FileStorage::Impl::open(const char *filename_or_buf, int _flags, const char
|
||||
}
|
||||
} else {
|
||||
#if USE_ZLIB
|
||||
if (append) {
|
||||
CV_Error(cv::Error::StsNotImplemented, "Appending data to compressed file is not implemented");
|
||||
}
|
||||
char mode[] = {write_mode ? 'w' : 'r', 'b', compression ? compression : '3', '\0'};
|
||||
gzfile = gzopen(filename.c_str(), mode);
|
||||
if (!gzfile)
|
||||
|
||||
@@ -2108,9 +2108,19 @@ T fsWriteRead(const T& expectedValue, const char* ext)
|
||||
fs_w.release();
|
||||
|
||||
FileStorage fs_r(fname, FileStorage::READ);
|
||||
|
||||
T value;
|
||||
fs_r["value"] >> value;
|
||||
fs_r.release();
|
||||
|
||||
// If ext is `.gz[0-9]`, fname on storage will end with `.gz`.
|
||||
// FileStorage::Impl::open() truncates the last digit internally.
|
||||
if (isdigit(fname.back()))
|
||||
{
|
||||
fname.pop_back();
|
||||
}
|
||||
|
||||
remove(fname.c_str());
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -2143,7 +2153,7 @@ TEST_P(FileStorage_exact_type, long_int)
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(Core_InputOutput,
|
||||
FileStorage_exact_type, Values(".yml", ".xml", ".json")
|
||||
FileStorage_exact_type, Values(".yml", ".xml", ".json", ".xml.gz", ".xml.gz0", ".xml.gz9")
|
||||
);
|
||||
|
||||
}} // namespace
|
||||
|
||||
Reference in New Issue
Block a user