| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (C) 2014 Google Inc. | 
 |    2 // | 
 |    3 // Licensed under the Apache License, Version 2.0 (the "License"); | 
 |    4 // you may not use this file except in compliance with the License. | 
 |    5 // You may obtain a copy of the License at | 
 |    6 // | 
 |    7 // http://www.apache.org/licenses/LICENSE-2.0 | 
 |    8 // | 
 |    9 // Unless required by applicable law or agreed to in writing, software | 
 |   10 // distributed under the License is distributed on an "AS IS" BASIS, | 
 |   11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 
 |   12 // See the License for the specific language governing permissions and | 
 |   13 // limitations under the License. | 
 |   14 // | 
 |   15 // Wrapper prepends timestamp and checksum to data. Format: | 
 |   16 // | 
 |   17 //    timestamp=<timestamp> | 
 |   18 //    checksum=<checksum> | 
 |   19 //    <data> | 
 |   20 // | 
 |   21 // The timestamp is the time_t that was returned from time(NULL) function. The | 
 |   22 // timestamp does not need to be portable because it is written and read only by | 
 |   23 // Wrapper. The value is somewhat human-readable: it is the number of seconds | 
 |   24 // since the epoch. | 
 |   25 // | 
 |   26 // The checksum is the 32-character hexadecimal MD5 checksum of <data>. It is | 
 |   27 // meant to protect from random file changes on disk. | 
 |   28  | 
 |   29 #include "wrapper.h" | 
 |   30  | 
 |   31 #include <cassert> | 
 |   32 #include <cstddef> | 
 |   33 #include <cstdlib> | 
 |   34 #include <ctime> | 
 |   35 #include <string> | 
 |   36  | 
 |   37 #include "time_to_string.h" | 
 |   38 #include "util/md5.h" | 
 |   39  | 
 |   40 namespace i18n { | 
 |   41 namespace addressinput { | 
 |   42  | 
 |   43 namespace { | 
 |   44  | 
 |   45 const char kTimestampPrefix[] = "timestamp="; | 
 |   46 const size_t kTimestampPrefixLength = sizeof kTimestampPrefix - 1; | 
 |   47  | 
 |   48 const char kChecksumPrefix[] = "checksum="; | 
 |   49 const size_t kChecksumPrefixLength = sizeof kChecksumPrefix - 1; | 
 |   50  | 
 |   51 const char kSeparator = '\n'; | 
 |   52  | 
 |   53 // Places the header value into |header_value| parameter and erases the header | 
 |   54 // from |data|. Returns |true| if the header format is valid. | 
 |   55 bool UnwrapHeader(const char* header_prefix, | 
 |   56                   size_t header_prefix_length, | 
 |   57                   std::string* data, | 
 |   58                   std::string* header_value) { | 
 |   59   assert(header_prefix != NULL); | 
 |   60   assert(data != NULL); | 
 |   61   assert(header_value != NULL); | 
 |   62  | 
 |   63   if (data->compare( | 
 |   64           0, header_prefix_length, header_prefix, header_prefix_length) != 0) { | 
 |   65     return false; | 
 |   66   } | 
 |   67  | 
 |   68   std::string::size_type separator_position = | 
 |   69       data->find(kSeparator, header_prefix_length); | 
 |   70   if (separator_position == std::string::npos) { | 
 |   71     return false; | 
 |   72   } | 
 |   73  | 
 |   74   header_value->assign( | 
 |   75       *data, header_prefix_length, separator_position - header_prefix_length); | 
 |   76   data->erase(0, separator_position + 1); | 
 |   77  | 
 |   78   return true; | 
 |   79 } | 
 |   80  | 
 |   81 }  // namespace | 
 |   82  | 
 |   83 // static | 
 |   84 std::string Wrapper::Wrap(const std::string& data) { | 
 |   85   std::string wrapped; | 
 |   86   wrapped.append(kTimestampPrefix, kTimestampPrefixLength); | 
 |   87   wrapped.append(TimeToString(time(NULL))); | 
 |   88   wrapped.push_back(kSeparator); | 
 |   89  | 
 |   90   wrapped.append(kChecksumPrefix, kChecksumPrefixLength); | 
 |   91   wrapped.append(MD5String(data)); | 
 |   92   wrapped.push_back(kSeparator); | 
 |   93   wrapped.append(data); | 
 |   94  | 
 |   95   return wrapped; | 
 |   96 } | 
 |   97  | 
 |   98 // static | 
 |   99 bool Wrapper::Unwrap(std::string* data, double* age_in_seconds) { | 
 |  100   assert(data != NULL); | 
 |  101   assert(age_in_seconds != NULL); | 
 |  102  | 
 |  103   std::string timestamp_string; | 
 |  104   if (!UnwrapHeader( | 
 |  105            kTimestampPrefix, kTimestampPrefixLength, data, ×tamp_string)) { | 
 |  106     return false; | 
 |  107   } | 
 |  108  | 
 |  109   time_t timestamp = atol(timestamp_string.c_str()); | 
 |  110   if (timestamp < 0) { | 
 |  111     return false; | 
 |  112   } | 
 |  113  | 
 |  114   *age_in_seconds = difftime(time(NULL), timestamp); | 
 |  115   if (*age_in_seconds < 0.0) { | 
 |  116     return false; | 
 |  117   } | 
 |  118  | 
 |  119   std::string checksum; | 
 |  120   if (!UnwrapHeader(kChecksumPrefix, kChecksumPrefixLength, data, &checksum)) { | 
 |  121     return false; | 
 |  122   } | 
 |  123  | 
 |  124   return checksum == MD5String(*data); | 
 |  125 } | 
 |  126  | 
 |  127 }  // namespace addressinput | 
 |  128 }  // namespace i18n | 
| OLD | NEW |