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