• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 PDFium 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 <memory>
6 #include <vector>
7 
8 #include "core/fpdfapi/parser/cpdf_dictionary.h"
9 #include "core/fpdfapi/parser/cpdf_name.h"
10 #include "core/fpdfapi/parser/cpdf_string.h"
11 #include "core/fpdfdoc/cpdf_filespec.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "testing/test_support.h"
14 
TEST(cpdf_filespec,EncodeDecodeFileName)15 TEST(cpdf_filespec, EncodeDecodeFileName) {
16   std::vector<pdfium::NullTermWstrFuncTestData> test_data = {
17     // Empty src string.
18     {L"", L""},
19     // only file name.
20     {L"test.pdf", L"test.pdf"},
21 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
22     // With drive identifier.
23     {L"r:\\pdfdocs\\spec.pdf", L"/r/pdfdocs/spec.pdf"},
24     // Relative path.
25     {L"My Document\\test.pdf", L"My Document/test.pdf"},
26     // Absolute path without drive identifier.
27     {L"\\pdfdocs\\spec.pdf", L"//pdfdocs/spec.pdf"},
28     // Absolute path with double backslashes.
29     {L"\\\\pdfdocs\\spec.pdf", L"/pdfdocs/spec.pdf"},
30 // Network resource name. It is not supported yet.
31 // {L"pclib/eng:\\pdfdocs\\spec.pdf", L"/pclib/eng/pdfdocs/spec.pdf"},
32 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
33     // Absolute path with colon separator.
34     {L"Mac HD:PDFDocs:spec.pdf", L"/Mac HD/PDFDocs/spec.pdf"},
35     // Relative path with colon separator.
36     {L"PDFDocs:spec.pdf", L"PDFDocs/spec.pdf"},
37 #else
38     // Relative path.
39     {L"./docs/test.pdf", L"./docs/test.pdf"},
40     // Relative path with parent dir.
41     {L"../test_docs/test.pdf", L"../test_docs/test.pdf"},
42     // Absolute path.
43     {L"/usr/local/home/test.pdf", L"/usr/local/home/test.pdf"},
44 #endif
45   };
46   for (const auto& data : test_data) {
47     CFX_WideString encoded_str = CPDF_FileSpec::EncodeFileName(data.input);
48     EXPECT_TRUE(encoded_str == data.expected);
49     // DecodeFileName is the reverse procedure of EncodeFileName.
50     CFX_WideString decoded_str = CPDF_FileSpec::DecodeFileName(data.expected);
51     EXPECT_TRUE(decoded_str == data.input);
52   }
53 }
54 
TEST(cpdf_filespec,GetFileName)55 TEST(cpdf_filespec, GetFileName) {
56   {
57     // String object.
58     pdfium::NullTermWstrFuncTestData test_data = {
59 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
60       L"/C/docs/test.pdf",
61       L"C:\\docs\\test.pdf"
62 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
63       L"/Mac HD/docs/test.pdf",
64       L"Mac HD:docs:test.pdf"
65 #else
66       L"/docs/test.pdf",
67       L"/docs/test.pdf"
68 #endif
69     };
70     std::unique_ptr<CPDF_Object> str_obj(
71         new CPDF_String(nullptr, test_data.input));
72     CPDF_FileSpec file_spec(str_obj.get());
73     CFX_WideString file_name;
74     EXPECT_TRUE(file_spec.GetFileName(&file_name));
75     EXPECT_TRUE(file_name == test_data.expected);
76   }
77   {
78     // Dictionary object.
79     pdfium::NullTermWstrFuncTestData test_data[5] = {
80 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
81       {L"/C/docs/test.pdf", L"C:\\docs\\test.pdf"},
82       {L"/D/docs/test.pdf", L"D:\\docs\\test.pdf"},
83       {L"/E/docs/test.pdf", L"E:\\docs\\test.pdf"},
84       {L"/F/docs/test.pdf", L"F:\\docs\\test.pdf"},
85       {L"/G/docs/test.pdf", L"G:\\docs\\test.pdf"},
86 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
87       {L"/Mac HD/docs1/test.pdf", L"Mac HD:docs1:test.pdf"},
88       {L"/Mac HD/docs2/test.pdf", L"Mac HD:docs2:test.pdf"},
89       {L"/Mac HD/docs3/test.pdf", L"Mac HD:docs3:test.pdf"},
90       {L"/Mac HD/docs4/test.pdf", L"Mac HD:docs4:test.pdf"},
91       {L"/Mac HD/docs5/test.pdf", L"Mac HD:docs5:test.pdf"},
92 #else
93       {L"/docs/a/test.pdf", L"/docs/a/test.pdf"},
94       {L"/docs/b/test.pdf", L"/docs/b/test.pdf"},
95       {L"/docs/c/test.pdf", L"/docs/c/test.pdf"},
96       {L"/docs/d/test.pdf", L"/docs/d/test.pdf"},
97       {L"/docs/e/test.pdf", L"/docs/e/test.pdf"},
98 #endif
99     };
100     // Keyword fields in reverse order of precedence to retrieve the file name.
101     const char* const keywords[5] = {"Unix", "Mac", "DOS", "F", "UF"};
102     std::unique_ptr<CPDF_Dictionary> dict_obj(new CPDF_Dictionary());
103     CPDF_FileSpec file_spec(dict_obj.get());
104     CFX_WideString file_name;
105     for (int i = 0; i < 5; ++i) {
106       dict_obj->SetNewFor<CPDF_String>(keywords[i], test_data[i].input);
107       EXPECT_TRUE(file_spec.GetFileName(&file_name));
108       EXPECT_TRUE(file_name == test_data[i].expected);
109     }
110 
111     // With all the former fields and 'FS' field suggests 'URL' type.
112     dict_obj->SetNewFor<CPDF_String>("FS", "URL", false);
113     EXPECT_TRUE(file_spec.GetFileName(&file_name));
114     // Url string is not decoded.
115     EXPECT_TRUE(file_name == test_data[4].input);
116   }
117   {
118     // Invalid object.
119     std::unique_ptr<CPDF_Object> name_obj(new CPDF_Name(nullptr, "test.pdf"));
120     CPDF_FileSpec file_spec(name_obj.get());
121     CFX_WideString file_name;
122     EXPECT_FALSE(file_spec.GetFileName(&file_name));
123   }
124 }
125 
TEST(cpdf_filespec,SetFileName)126 TEST(cpdf_filespec, SetFileName) {
127   pdfium::NullTermWstrFuncTestData test_data = {
128 #if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
129     L"C:\\docs\\test.pdf",
130     L"/C/docs/test.pdf"
131 #elif _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_
132     L"Mac HD:docs:test.pdf",
133     L"/Mac HD/docs/test.pdf"
134 #else
135     L"/docs/test.pdf",
136     L"/docs/test.pdf"
137 #endif
138   };
139   // String object.
140   std::unique_ptr<CPDF_Object> str_obj(new CPDF_String(nullptr, L"babababa"));
141   CPDF_FileSpec file_spec1(str_obj.get());
142   file_spec1.SetFileName(test_data.input);
143   // Check internal object value.
144   CFX_ByteString str = CFX_ByteString::FromUnicode(test_data.expected);
145   EXPECT_TRUE(str == str_obj->GetString());
146   // Check we can get the file name back.
147   CFX_WideString file_name;
148   EXPECT_TRUE(file_spec1.GetFileName(&file_name));
149   EXPECT_TRUE(file_name == test_data.input);
150 
151   // Dictionary object.
152   std::unique_ptr<CPDF_Dictionary> dict_obj(new CPDF_Dictionary());
153   CPDF_FileSpec file_spec2(dict_obj.get());
154   file_spec2.SetFileName(test_data.input);
155   // Check internal object value.
156   file_name = dict_obj->GetUnicodeTextFor("F");
157   EXPECT_TRUE(file_name == test_data.expected);
158   file_name = dict_obj->GetUnicodeTextFor("UF");
159   EXPECT_TRUE(file_name == test_data.expected);
160   // Check we can get the file name back.
161   EXPECT_TRUE(file_spec2.GetFileName(&file_name));
162   EXPECT_TRUE(file_name == test_data.input);
163 }
164