• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9 
10 #include "base/file_version_info_win.h"
11 
12 #include <windows.h>
13 
14 #include <stddef.h>
15 
16 #include <memory>
17 
18 #include "base/file_version_info.h"
19 #include "base/files/file_path.h"
20 #include "base/path_service.h"
21 #include "base/scoped_native_library.h"
22 #include "base/strings/string_util.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 
25 using base::FilePath;
26 
27 namespace {
28 
GetTestDataPath()29 FilePath GetTestDataPath() {
30   FilePath path;
31   base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &path);
32   path = path.AppendASCII("base");
33   path = path.AppendASCII("test");
34   path = path.AppendASCII("data");
35   path = path.AppendASCII("file_version_info_unittest");
36   return path;
37 }
38 
39 class FileVersionInfoFactory {
40  public:
FileVersionInfoFactory(const FilePath & path)41   explicit FileVersionInfoFactory(const FilePath& path) : path_(path) {}
42   FileVersionInfoFactory(const FileVersionInfoFactory&) = delete;
43   FileVersionInfoFactory& operator=(const FileVersionInfoFactory&) = delete;
44 
Create() const45   std::unique_ptr<FileVersionInfo> Create() const {
46     return FileVersionInfo::CreateFileVersionInfo(path_);
47   }
48 
49  private:
50   const FilePath path_;
51 };
52 
53 class FileVersionInfoForModuleFactory {
54  public:
FileVersionInfoForModuleFactory(const FilePath & path)55   explicit FileVersionInfoForModuleFactory(const FilePath& path)
56       // Load the library with LOAD_LIBRARY_AS_IMAGE_RESOURCE since it shouldn't
57       // be executed.
58       : library_(::LoadLibraryEx(path.value().c_str(),
59                                  nullptr,
60                                  LOAD_LIBRARY_AS_IMAGE_RESOURCE)) {
61     EXPECT_TRUE(library_.is_valid());
62   }
63   FileVersionInfoForModuleFactory(const FileVersionInfoForModuleFactory&) =
64       delete;
65   FileVersionInfoForModuleFactory& operator=(
66       const FileVersionInfoForModuleFactory&) = delete;
67 
Create() const68   std::unique_ptr<FileVersionInfo> Create() const {
69     return FileVersionInfo::CreateFileVersionInfoForModule(library_.get());
70   }
71 
72  private:
73   const base::ScopedNativeLibrary library_;
74 };
75 
76 template <typename T>
77 class FileVersionInfoTest : public testing::Test {};
78 
79 using FileVersionInfoFactories =
80     ::testing::Types<FileVersionInfoFactory, FileVersionInfoForModuleFactory>;
81 
82 }  // namespace
83 
84 TYPED_TEST_SUITE(FileVersionInfoTest, FileVersionInfoFactories);
85 
TYPED_TEST(FileVersionInfoTest,HardCodedProperties)86 TYPED_TEST(FileVersionInfoTest, HardCodedProperties) {
87   const base::FilePath::CharType kDLLName[] =
88       FILE_PATH_LITERAL("FileVersionInfoTest1.dll");
89 
90   const wchar_t* const kExpectedValues[15] = {
91       // FileVersionInfoTest.dll
92       L"Goooooogle",                      // company_name
93       L"Google",                          // company_short_name
94       L"This is the product name",        // product_name
95       L"This is the product short name",  // product_short_name
96       L"The Internal Name",               // internal_name
97       L"4.3.2.1",                         // product_version
98       L"Special build property",          // special_build
99       L"This is the original filename",   // original_filename
100       L"This is my file description",     // file_description
101       L"1.2.3.4",                         // file_version
102   };
103 
104   FilePath dll_path = GetTestDataPath();
105   dll_path = dll_path.Append(kDLLName);
106 
107   TypeParam factory(dll_path);
108   std::unique_ptr<FileVersionInfo> version_info(factory.Create());
109   ASSERT_TRUE(version_info);
110 
111   int j = 0;
112   EXPECT_EQ(kExpectedValues[j++],
113             base::AsWStringView(version_info->company_name()));
114   EXPECT_EQ(kExpectedValues[j++],
115             base::AsWStringView(version_info->company_short_name()));
116   EXPECT_EQ(kExpectedValues[j++],
117             base::AsWStringView(version_info->product_name()));
118   EXPECT_EQ(kExpectedValues[j++],
119             base::AsWStringView(version_info->product_short_name()));
120   EXPECT_EQ(kExpectedValues[j++],
121             base::AsWStringView(version_info->internal_name()));
122   EXPECT_EQ(kExpectedValues[j++],
123             base::AsWStringView(version_info->product_version()));
124   EXPECT_EQ(kExpectedValues[j++],
125             base::AsWStringView(version_info->special_build()));
126   EXPECT_EQ(kExpectedValues[j++],
127             base::AsWStringView(version_info->original_filename()));
128   EXPECT_EQ(kExpectedValues[j++],
129             base::AsWStringView(version_info->file_description()));
130   EXPECT_EQ(kExpectedValues[j++],
131             base::AsWStringView(version_info->file_version()));
132 }
133 
TYPED_TEST(FileVersionInfoTest,CustomProperties)134 TYPED_TEST(FileVersionInfoTest, CustomProperties) {
135   FilePath dll_path = GetTestDataPath();
136   dll_path = dll_path.AppendASCII("FileVersionInfoTest1.dll");
137 
138   TypeParam factory(dll_path);
139   std::unique_ptr<FileVersionInfo> version_info(factory.Create());
140   ASSERT_TRUE(version_info);
141 
142   // Test few existing properties.
143   std::u16string str;
144   FileVersionInfoWin* version_info_win =
145       static_cast<FileVersionInfoWin*>(version_info.get());
146   EXPECT_TRUE(version_info_win->GetValue(u"Custom prop 1", &str));
147   EXPECT_EQ(u"Un", str);
148   EXPECT_EQ(u"Un", version_info_win->GetStringValue(u"Custom prop 1"));
149 
150   EXPECT_TRUE(version_info_win->GetValue(u"Custom prop 2", &str));
151   EXPECT_EQ(u"Deux", str);
152   EXPECT_EQ(u"Deux", version_info_win->GetStringValue(u"Custom prop 2"));
153 
154   EXPECT_TRUE(version_info_win->GetValue(u"Custom prop 3", &str));
155   EXPECT_EQ(u"1600 Amphitheatre Parkway Mountain View, CA 94043", str);
156   EXPECT_EQ(u"1600 Amphitheatre Parkway Mountain View, CA 94043",
157             version_info_win->GetStringValue(u"Custom prop 3"));
158 
159   // Test an non-existing property.
160   EXPECT_FALSE(version_info_win->GetValue(u"Unknown property", &str));
161   EXPECT_EQ(std::u16string(),
162             version_info_win->GetStringValue(u"Unknown property"));
163 
164   EXPECT_EQ(base::Version(std::vector<uint32_t>{1, 0, 0, 1}),
165             version_info_win->GetFileVersion());
166 }
167 
TYPED_TEST(FileVersionInfoTest,NoVersionInfo)168 TYPED_TEST(FileVersionInfoTest, NoVersionInfo) {
169   FilePath dll_path = GetTestDataPath();
170   dll_path = dll_path.AppendASCII("no_version_info.dll");
171 
172   TypeParam factory(dll_path);
173   ASSERT_FALSE(factory.Create());
174 }
175