• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "extensions/browser/computed_hashes.h"
6 
7 #include "base/base64.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path.h"
10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h"
12 
13 namespace {
14 const char kPathKey[] = "path";
15 const char kBlockSizeKey[] = "block_size";
16 const char kBlockHashesKey[] = "block_hashes";
17 }
18 
19 namespace extensions {
20 
Reader()21 ComputedHashes::Reader::Reader() {
22 }
~Reader()23 ComputedHashes::Reader::~Reader() {
24 }
25 
InitFromFile(const base::FilePath & path)26 bool ComputedHashes::Reader::InitFromFile(const base::FilePath& path) {
27   std::string contents;
28   if (!base::ReadFileToString(path, &contents))
29     return false;
30 
31   base::ListValue* all_hashes = NULL;
32   scoped_ptr<base::Value> value(base::JSONReader::Read(contents));
33   if (!value.get() || !value->GetAsList(&all_hashes))
34     return false;
35 
36   for (size_t i = 0; i < all_hashes->GetSize(); i++) {
37     base::DictionaryValue* dictionary = NULL;
38     if (!all_hashes->GetDictionary(i, &dictionary))
39       return false;
40 
41     std::string relative_path_utf8;
42     if (!dictionary->GetString(kPathKey, &relative_path_utf8))
43       return false;
44 
45     int block_size;
46     if (!dictionary->GetInteger(kBlockSizeKey, &block_size))
47       return false;
48     if (block_size <= 0 || ((block_size % 1024) != 0)) {
49       LOG(ERROR) << "Invalid block size: " << block_size;
50       block_size = 0;
51       return false;
52     }
53 
54     base::ListValue* hashes_list = NULL;
55     if (!dictionary->GetList(kBlockHashesKey, &hashes_list))
56       return false;
57 
58     base::FilePath relative_path =
59         base::FilePath::FromUTF8Unsafe(relative_path_utf8);
60 
61     data_[relative_path] = HashInfo(block_size, std::vector<std::string>());
62     std::vector<std::string>* hashes = &(data_[relative_path].second);
63 
64     for (size_t j = 0; j < hashes_list->GetSize(); j++) {
65       std::string encoded;
66       if (!hashes_list->GetString(j, &encoded))
67         return false;
68 
69       hashes->push_back(std::string());
70       std::string* decoded = &hashes->back();
71       if (!base::Base64Decode(encoded, decoded)) {
72         hashes->clear();
73         return false;
74       }
75     }
76   }
77   return true;
78 }
79 
GetHashes(const base::FilePath & relative_path,int * block_size,std::vector<std::string> * hashes)80 bool ComputedHashes::Reader::GetHashes(const base::FilePath& relative_path,
81                                        int* block_size,
82                                        std::vector<std::string>* hashes) {
83   std::map<base::FilePath, HashInfo>::iterator i = data_.find(relative_path);
84   if (i == data_.end())
85     return false;
86   HashInfo& info = i->second;
87   *block_size = info.first;
88   *hashes = info.second;
89   return true;
90 }
91 
Writer()92 ComputedHashes::Writer::Writer() {
93 }
~Writer()94 ComputedHashes::Writer::~Writer() {
95 }
96 
AddHashes(const base::FilePath & relative_path,int block_size,const std::vector<std::string> & hashes)97 void ComputedHashes::Writer::AddHashes(const base::FilePath& relative_path,
98                                        int block_size,
99                                        const std::vector<std::string>& hashes) {
100   base::DictionaryValue* dict = new base::DictionaryValue();
101   base::ListValue* block_hashes = new base::ListValue();
102   file_list_.Append(dict);
103   dict->SetString(kPathKey, relative_path.AsUTF8Unsafe());
104   dict->SetInteger(kBlockSizeKey, block_size);
105   dict->Set(kBlockHashesKey, block_hashes);
106 
107   for (std::vector<std::string>::const_iterator i = hashes.begin();
108        i != hashes.end();
109        ++i) {
110     std::string encoded;
111     base::Base64Encode(*i, &encoded);
112     block_hashes->AppendString(encoded);
113   }
114 }
115 
WriteToFile(const base::FilePath & path)116 bool ComputedHashes::Writer::WriteToFile(const base::FilePath& path) {
117   std::string json;
118   if (!base::JSONWriter::Write(&file_list_, &json))
119     return false;
120   int written = base::WriteFile(path, json.data(), json.size());
121   if (static_cast<unsigned>(written) != json.size()) {
122     LOG(ERROR) << "Error writing " << path.MaybeAsASCII()
123                << " ; write result:" << written << " expected:" << json.size();
124     return false;
125   }
126   return true;
127 }
128 
129 }  // namespace extensions
130