2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 * @author Bartlomiej Grzelewski (b.grzelewski@samsung.com)
18 * @file ReferenceValidator.cpp
20 * @brief Compare signature reference list and list of widget file.
22 #include <vcore/ReferenceValidator.h>
31 #include <dpl/log/log.h>
35 const char *SPECIAL_SYMBOL_CURRENT_DIR = ".";
36 const char *SPECIAL_SYMBOL_UPPER_DIR = "..";
37 const char *SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE = "author-signature.xml";
38 const char *REGEXP_DISTRIBUTOR_SIGNATURE = "^signature[1-9][0-9]*\\.xml";
40 const char MARK_ENCODED_CHAR = '%';
42 } // namespace anonymous
44 namespace ValidationCore {
46 class ReferenceValidator::Impl
49 Impl(const std::string &dirpath)
51 , m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
56 Result checkReferences(const SignatureData &signatureData){
57 const ReferenceSet &refSet = signatureData.getReferenceSet();
58 ReferenceSet refDecoded;
61 for (auto it = refSet.begin(); it != refSet.end(); ++it) {
62 if (std::string::npos != it->find(MARK_ENCODED_CHAR))
63 refDecoded.insert(decodeProcent(*it));
65 refDecoded.insert(*it);
68 return ERROR_DECODING_URL;
70 return dfsCheckDirectories(
73 signatureData.isAuthorSignature());
77 int hexToInt(char hex);
78 std::string decodeProcent(const std::string &path);
80 Result dfsCheckDirectories(
81 const ReferenceSet &referenceSet,
82 const std::string &directory,
83 bool isAuthorSignature);
85 inline bool isDistributorSignature(const char *cstring) const
87 return m_signatureRegexp.FullMatch(cstring);
90 std::string m_dirpath;
91 pcrecpp::RE m_signatureRegexp;
94 int ReferenceValidator::Impl::hexToInt(char a) {
95 if (a >= '0' && a <= '9') return a-'0';
96 if (a >= 'A' && a <= 'F') return a-'A' + 10;
97 if (a >= 'a' && a <= 'f') return a-'a' + 10;
98 LogError("Symbol '" << a << "' is out of scope.");
99 throw ERROR_DECODING_URL;
102 std::string ReferenceValidator::Impl::decodeProcent(const std::string &path) {
103 std::vector<int> input(path.begin(), path.end());
104 std::vector<char> output;
107 while(i<input.size()) {
108 if (MARK_ENCODED_CHAR == input[i]) {
109 if (i+2 >= input.size())
110 throw ERROR_DECODING_URL;
112 int result = hexToInt(input[i+1])*16 + hexToInt(input[i+2]);
114 // RFC 1738 - octets 80 to FF are not allowed
116 throw ERROR_DECODING_URL;
118 output.push_back(static_cast<char>(result));
121 output.push_back(static_cast<char>(input[i]));
126 LogError("Error while decoding url path : " << path);
127 throw ERROR_DECODING_URL;
129 return std::string(output.begin(), output.end());
132 ReferenceValidator::Result ReferenceValidator::Impl::dfsCheckDirectories(
133 const ReferenceSet &referenceSet,
134 const std::string &directory,
135 bool isAuthorSignature)
139 std::string currentDir = m_dirpath;
140 if (!directory.empty()) {
142 currentDir += directory;
145 if ((dp = opendir(currentDir.c_str())) == NULL) {
146 LogError("Error opening directory : " << currentDir);
147 return ERROR_OPENING_DIR;
150 for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
151 if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_CURRENT_DIR)) {
155 if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_UPPER_DIR)) {
159 if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
160 !strcmp(dirp->d_name, SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE) &&
166 if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
167 isDistributorSignature(dirp->d_name)) {
171 if (dirp->d_type == DT_DIR) {
172 LogDebug("Open directory : " << (directory + dirp->d_name));
173 std::string tmp_directory = directory + dirp->d_name + "/";
174 Result result = dfsCheckDirectories(referenceSet,
177 if (result != NO_ERROR) {
181 } else if (dirp->d_type == DT_REG) {
182 if (referenceSet.end() ==
183 referenceSet.find(directory + dirp->d_name))
185 LogDebug("Found file : " << (directory + dirp->d_name));
186 LogError("Unknown ERROR_REFERENCE_NOT_FOUND.");
188 return ERROR_REFERENCE_NOT_FOUND;
191 LogError("Unknown file type.");
193 return ERROR_UNSUPPORTED_FILE_TYPE;
199 return ERROR_READING_DIR;
207 ReferenceValidator::ReferenceValidator(const std::string &dirpath)
208 : m_impl(new Impl(dirpath))
211 ReferenceValidator::~ReferenceValidator(){
215 ReferenceValidator::Result ReferenceValidator::checkReferences(
216 const SignatureData &signatureData)
218 return m_impl->checkReferences(signatureData);