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/errno_string.h>
32 #include <dpl/log/log.h>
36 const char *SPECIAL_SYMBOL_CURRENT_DIR = ".";
37 const char *SPECIAL_SYMBOL_UPPER_DIR = "..";
38 const char *SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE = "author-signature.xml";
39 const char *REGEXP_DISTRIBUTOR_SIGNATURE = "^signature[1-9][0-9]*\\.xml";
41 const char MARK_ENCODED_CHAR = '%';
43 } // namespace anonymous
45 namespace ValidationCore {
47 class ReferenceValidator::Impl
50 Impl(const std::string &dirpath)
52 , m_signatureRegexp(REGEXP_DISTRIBUTOR_SIGNATURE)
57 Result checkReferences(const SignatureData &signatureData){
58 const ReferenceSet &refSet = signatureData.getReferenceSet();
59 ReferenceSet refDecoded;
62 for (auto it = refSet.begin(); it != refSet.end(); ++it) {
63 if (std::string::npos != it->find(MARK_ENCODED_CHAR))
64 refDecoded.insert(decodeProcent(*it));
66 refDecoded.insert(*it);
69 return ERROR_DECODING_URL;
71 return dfsCheckDirectories(
74 signatureData.isAuthorSignature());
78 int hexToInt(char hex);
79 std::string decodeProcent(const std::string &path);
81 Result dfsCheckDirectories(
82 const ReferenceSet &referenceSet,
83 const std::string &directory,
84 bool isAuthorSignature);
86 inline bool isDistributorSignature(const char *cstring) const
88 return m_signatureRegexp.FullMatch(cstring);
91 std::string m_dirpath;
92 std::string m_errorDescription;
93 pcrecpp::RE m_signatureRegexp;
96 int ReferenceValidator::Impl::hexToInt(char a) {
97 if (a >= '0' && a <= '9') return a-'0';
98 if (a >= 'A' && a <= 'F') return a-'A' + 10;
99 if (a >= 'a' && a <= 'f') return a-'a' + 10;
100 LogError("Symbol '" << a << "' is out of scope.");
101 throw ERROR_DECODING_URL;
104 std::string ReferenceValidator::Impl::decodeProcent(const std::string &path) {
105 std::vector<int> input(path.begin(), path.end());
106 std::vector<char> output;
109 while(i<input.size()) {
110 if (MARK_ENCODED_CHAR == input[i]) {
111 if (i+2 >= input.size())
112 throw ERROR_DECODING_URL;
114 int result = hexToInt(input[i+1])*16 + hexToInt(input[i+2]);
116 // RFC 1738 - octets 80 to FF are not allowed
118 throw ERROR_DECODING_URL;
120 output.push_back(static_cast<char>(result));
123 output.push_back(static_cast<char>(input[i]));
128 LogError("Error while decoding url path : " << path);
129 throw ERROR_DECODING_URL;
131 return std::string(output.begin(), output.end());
134 ReferenceValidator::Result ReferenceValidator::Impl::dfsCheckDirectories(
135 const ReferenceSet &referenceSet,
136 const std::string &directory,
137 bool isAuthorSignature)
141 std::string currentDir = m_dirpath + directory;
143 if ((dp = opendir(currentDir.c_str())) == NULL) {
144 LogError("Error opening directory : " << currentDir);
145 m_errorDescription = currentDir;
146 return ERROR_OPENING_DIR;
149 for (errno = 0; (dirp = readdir(dp)) != NULL; errno = 0) {
150 if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_CURRENT_DIR)) {
154 if (!strcmp(dirp->d_name, SPECIAL_SYMBOL_UPPER_DIR)) {
158 if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
159 !strcmp(dirp->d_name, SPECIAL_SYMBOL_AUTHOR_SIGNATURE_FILE) &&
165 if (currentDir == m_dirpath && dirp->d_type == DT_REG &&
166 isDistributorSignature(dirp->d_name)) {
170 if (dirp->d_type == DT_DIR) {
171 LogDebug("Open directory : " << (directory + dirp->d_name));
172 std::string tmp_directory = directory + dirp->d_name + "/";
173 Result result = dfsCheckDirectories(referenceSet,
176 if (result != NO_ERROR) {
180 } else if (dirp->d_type == DT_REG) {
181 if (referenceSet.end() ==
182 referenceSet.find(directory + dirp->d_name))
184 LogDebug("Found file : " << (directory + dirp->d_name));
185 LogError("Unknown ERROR_REFERENCE_NOT_FOUND.");
187 m_errorDescription = directory + dirp->d_name;
188 return ERROR_REFERENCE_NOT_FOUND;
191 LogError("Unknown file type.");
193 m_errorDescription = directory + dirp->d_name;
194 return ERROR_UNSUPPORTED_FILE_TYPE;
199 m_errorDescription = VcoreDPL::GetErrnoString();
200 LogError("readdir failed. Errno code : " << errno << ", Description : " << m_errorDescription);
202 return ERROR_READING_DIR;
210 ReferenceValidator::ReferenceValidator(const std::string &dirpath)
211 : m_impl(new Impl(dirpath))
214 ReferenceValidator::~ReferenceValidator(){
218 ReferenceValidator::Result ReferenceValidator::checkReferences(
219 const SignatureData &signatureData)
221 return m_impl->checkReferences(signatureData);