From 38483fe7a7933049ec353744a3aa961fb608b214 Mon Sep 17 00:00:00 2001 From: Vladislav Sovrasov Date: Tue, 1 Nov 2016 12:24:30 +0300 Subject: [PATCH 1/2] Skip UTF-8 BOM in FileStorage --- modules/core/src/persistence.cpp | 17 +++++++++++++++-- modules/core/test/test_io.cpp | 22 ++++++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index a1c843dc52..8cb7ec2aba 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -96,6 +96,15 @@ static inline bool cv_isspace(char c) return (9 <= c && c <= 13) || c == ' '; } +static inline char* cv_skip_BOM(char* ptr) +{ + if((uchar)ptr[0] == 0xef && (uchar)ptr[1] == 0xbb && (uchar)ptr[2] == 0xbf) //UTF-8 BOM + { + return ptr + 3; + } + return ptr; +} + static char* icv_itoa( int _val, char* buffer, int /*radix*/ ) { const int radix = 10; @@ -4399,10 +4408,13 @@ cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const const char* json_signature = "{"; char buf[16]; icvGets( fs, buf, sizeof(buf)-2 ); + char* bufPtr = cv_skip_BOM(buf); + size_t bufOffset = bufPtr - buf; + fs->fmt - = strncmp( buf, yaml_signature, strlen(yaml_signature) ) == 0 + = strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0 ? CV_STORAGE_FORMAT_YAML - : strncmp( buf, json_signature, strlen(json_signature) ) == 0 + : strncmp( bufPtr, json_signature, strlen(json_signature) ) == 0 ? CV_STORAGE_FORMAT_JSON : CV_STORAGE_FORMAT_XML ; @@ -4420,6 +4432,7 @@ cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const buf_size = MAX( buf_size, (size_t)(CV_FS_MAX_LEN*2 + 1024) ); } icvRewind(fs); + fs->strbufpos = bufOffset; fs->str_hash = cvCreateMap( 0, sizeof(CvStringHash), sizeof(CvStringHashNode), fs->memstorage, 256 ); diff --git a/modules/core/test/test_io.cpp b/modules/core/test/test_io.cpp index 75953e10ac..34915cc6ef 100644 --- a/modules/core/test/test_io.cpp +++ b/modules/core/test/test_io.cpp @@ -928,3 +928,25 @@ TEST(Core_InputOutput, filestorage_json_comment) EXPECT_EQ(str, String("value")); } + +TEST(Core_InputOutput, filestorage_utf8_bom) +{ + EXPECT_NO_THROW( + { + String content ="\xEF\xBB\xBF\n\n\n"; + cv::FileStorage fs(content, cv::FileStorage::READ | cv::FileStorage::MEMORY); + fs.release(); + }); + EXPECT_NO_THROW( + { + String content ="\xEF\xBB\xBF%YAML:1.0\n"; + cv::FileStorage fs(content, cv::FileStorage::READ | cv::FileStorage::MEMORY); + fs.release(); + }); + EXPECT_NO_THROW( + { + String content ="\xEF\xBB\xBF{\n}\n"; + cv::FileStorage fs(content, cv::FileStorage::READ | cv::FileStorage::MEMORY); + fs.release(); + }); +} From e955d17c51b0b7375739e57fcf83b90f2f400d4f Mon Sep 17 00:00:00 2001 From: Vladislav Sovrasov Date: Wed, 2 Nov 2016 14:53:04 +0300 Subject: [PATCH 2/2] Add new error messages --- modules/core/src/persistence.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/core/src/persistence.cpp b/modules/core/src/persistence.cpp index 8cb7ec2aba..eacdcc5ef5 100644 --- a/modules/core/src/persistence.cpp +++ b/modules/core/src/persistence.cpp @@ -4406,18 +4406,22 @@ cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const size_t buf_size = 1 << 20; const char* yaml_signature = "%YAML"; const char* json_signature = "{"; + const char* xml_signature = "fmt - = strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0 - ? CV_STORAGE_FORMAT_YAML - : strncmp( bufPtr, json_signature, strlen(json_signature) ) == 0 - ? CV_STORAGE_FORMAT_JSON - : CV_STORAGE_FORMAT_XML - ; + if(strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0) + fs->fmt = CV_STORAGE_FORMAT_YAML; + else if(strncmp( bufPtr, json_signature, strlen(json_signature) ) == 0) + fs->fmt = CV_STORAGE_FORMAT_JSON; + else if(strncmp( bufPtr, xml_signature, strlen(xml_signature) ) == 0) + fs->fmt = CV_STORAGE_FORMAT_XML; + else if(fs->strbufsize == bufOffset) + CV_Error(CV_BADARG_ERR, "Input file is empty"); + else + CV_Error(CV_BADARG_ERR, "Unsupported file storage format"); if( !isGZ ) {