1 /*
2  * Copyright (C) 2009-2010, Pino Toscano <pino@kde.org>
3  * Copyright (C) 2010, Hib Eris <hib@hiberis.nl>
4  * Copyright (C) 2014, 2015 Hans-Peter Deifel <hpdeifel@gmx.de>
5  * Copyright (C) 2015, Tamas Szekeres <szekerest@gmail.com>
6  * Copyright (C) 2016 Jakub Alba <jakubalba@gmail.com>
7  * Copyright (C) 2018, 2020, 2021, Albert Astals Cid <aacid@kde.org>
8  * Copyright (C) 2018 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
9  * Copyright (C) 2018, 2020, Adam Reichold <adam.reichold@t-online.de>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2, or (at your option)
14  * any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
24  */
25 
26 /**
27  \file poppler-global.h
28  */
29 #include "poppler-global.h"
30 
31 #include "poppler-private.h"
32 #include "poppler-document-private.h"
33 
34 #include "DateInfo.h"
35 
36 #include <algorithm>
37 
38 #include <cerrno>
39 #include <cstring>
40 #include <ios>
41 #include <iostream>
42 
43 #include <iconv.h>
44 
45 #include "config.h"
46 
47 namespace {
48 
49 struct MiniIconv
50 {
MiniIconv__anon83ec37750111::MiniIconv51     MiniIconv(const char *to_code, const char *from_code) : i_(iconv_open(to_code, from_code)) { }
~MiniIconv__anon83ec37750111::MiniIconv52     ~MiniIconv()
53     {
54         if (is_valid())
55             iconv_close(i_);
56     }
57     MiniIconv(const MiniIconv &) = delete;
58     MiniIconv &operator=(const MiniIconv &) = delete;
is_valid__anon83ec37750111::MiniIconv59     bool is_valid() const { return i_ != (iconv_t)-1; }
operator iconv_t__anon83ec37750111::MiniIconv60     explicit operator iconv_t() const { return i_; }
61     iconv_t i_;
62 };
63 
64 }
65 
66 using namespace poppler;
67 
68 /**
69  \namespace poppler
70 
71  Single namespace containing all the classes and functions of poppler-cpp.
72  */
73 
74 /**
75  \class poppler::noncopyable
76 
77  A class that cannot be copied.
78  */
79 
80 /**
81  \enum poppler::rotation_enum
82 
83  The case sensitivity.
84 */
85 /**
86  \var poppler::rotation_enum poppler::rotate_0
87 
88  A rotation of 0 degrees clockwise.
89 */
90 /**
91  \var poppler::rotation_enum poppler::rotate_90
92 
93  A rotation of 90 degrees clockwise.
94 */
95 /**
96  \var poppler::rotation_enum poppler::rotate_180
97 
98  A rotation of 180 degrees clockwise.
99 */
100 /**
101  \var poppler::rotation_enum poppler::rotate_270
102 
103  A rotation of 270 degrees clockwise.
104 */
105 
106 /**
107  \enum poppler::page_box_enum
108 
109  A possible box of a page in a PDF %document.
110 */
111 /**
112  \var poppler::page_box_enum poppler::media_box
113 
114  The "media" box.
115 */
116 /**
117  \var poppler::page_box_enum poppler::crop_box
118 
119  The "crop" box.
120 */
121 /**
122  \var poppler::page_box_enum poppler::bleed_box
123 
124  The "bleed" box.
125 */
126 /**
127  \var poppler::page_box_enum poppler::trim_box
128 
129  The "trim" box.
130 */
131 /**
132  \var poppler::page_box_enum poppler::art_box
133 
134  The "art" box.
135 */
136 
137 /**
138  \enum poppler::permission_enum
139 
140  A possible permission in a PDF %document.
141 */
142 /**
143  \var poppler::permission_enum poppler::perm_print
144 
145  The permission to allow the print of a %document.
146 */
147 /**
148  \var poppler::permission_enum poppler::perm_change
149 
150  The permission to change a %document.
151 
152  This is a generic "change" permission, so other permissions could affect
153  some types of changes.
154 */
155 /**
156  \var poppler::permission_enum poppler::perm_copy
157 
158  The permission to allow the copy or extraction of the text in a %document.
159 */
160 /**
161  \var poppler::permission_enum poppler::perm_add_notes
162 
163  The permission to allow the addition or editing of annotations,
164  and the filling of interactive form fields (including signature fields).
165 */
166 /**
167  \var poppler::permission_enum poppler::perm_fill_forms
168 
169  The permission to allow the filling of interactive form fields
170  (including signature fields).
171 
172  \note this permission can be set even when the \ref poppler::perm_add_notes "perm_add_notes"
173        is not: this means that only the filling of forms is allowed.
174 */
175 /**
176  \var poppler::permission_enum poppler::perm_accessibility
177 
178  The permission to allow the extracting of content (for example, text) for
179  accessibility usage (e.g. for a screen reader).
180 */
181 /**
182  \var poppler::permission_enum poppler::perm_assemble
183 
184  The permission to allow to "assemble" a %document.
185 
186  This implies operations such as the insertion, the rotation and the deletion
187  of pages; the creation of bookmarks and thumbnail images.
188 
189  \note this permission can be set even when the \ref poppler::perm_change "perm_change"
190        is not
191 */
192 /**
193  \var poppler::permission_enum poppler::perm_print_high_resolution
194 
195  The permission to allow the high resolution print of a %document.
196 */
197 
198 /**
199  \enum poppler::case_sensitivity_enum
200 
201  The case sensitivity.
202 */
203 
noncopyable()204 noncopyable::noncopyable() { }
205 
~noncopyable()206 noncopyable::~noncopyable() { }
207 
ustring()208 ustring::ustring() { }
209 
ustring(size_type len,value_type ch)210 ustring::ustring(size_type len, value_type ch) : std::basic_string<value_type>(len, ch) { }
211 
~ustring()212 ustring::~ustring() { }
213 
to_utf8() const214 byte_array ustring::to_utf8() const
215 {
216     if (!size()) {
217         return byte_array();
218     }
219 
220 #ifdef WORDS_BIGENDIAN
221     MiniIconv ic("UTF-8", "UTF-16BE");
222 #else
223     MiniIconv ic("UTF-8", "UTF-16LE");
224 #endif
225     if (!ic.is_valid()) {
226         return byte_array();
227     }
228     const value_type *me_data = data();
229     byte_array str(size() * sizeof(value_type));
230     char *str_data = &str[0];
231     size_t me_len_char = size() * sizeof(value_type);
232     size_t str_len_left = str.size();
233     size_t ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&me_data, &me_len_char, &str_data, &str_len_left);
234     if ((ir == (size_t)-1) && (errno == E2BIG)) {
235         const size_t delta = str_data - &str[0];
236         str_len_left += str.size();
237         str.resize(str.size() * 2);
238         str_data = &str[delta];
239         ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&me_data, &me_len_char, &str_data, &str_len_left);
240         if (ir == (size_t)-1) {
241             return byte_array();
242         }
243     }
244     str.resize(str.size() - str_len_left);
245     return str;
246 }
247 
to_latin1() const248 std::string ustring::to_latin1() const
249 {
250     if (!size()) {
251         return std::string();
252     }
253 
254     const size_type mylength = size();
255     std::string ret(mylength, '\0');
256     const value_type *me = data();
257     for (size_type i = 0; i < mylength; ++i) {
258         ret[i] = (char)*me++;
259     }
260     return ret;
261 }
262 
from_utf8(const char * str,int len)263 ustring ustring::from_utf8(const char *str, int len)
264 {
265     if (len <= 0) {
266         len = std::strlen(str);
267         if (len <= 0) {
268             return ustring();
269         }
270     }
271 
272 #ifdef WORDS_BIGENDIAN
273     MiniIconv ic("UTF-16BE", "UTF-8");
274 #else
275     MiniIconv ic("UTF-16LE", "UTF-8");
276 #endif
277     if (!ic.is_valid()) {
278         return ustring();
279     }
280 
281     // +1, because iconv inserts byte order marks
282     ustring ret(len + 1, 0);
283     char *ret_data = reinterpret_cast<char *>(&ret[0]);
284     char *str_data = const_cast<char *>(str);
285     size_t str_len_char = len;
286     size_t ret_len_left = ret.size() * sizeof(ustring::value_type);
287     size_t ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&str_data, &str_len_char, &ret_data, &ret_len_left);
288     if ((ir == (size_t)-1) && (errno == E2BIG)) {
289         const size_t delta = ret_data - reinterpret_cast<char *>(&ret[0]);
290         ret_len_left += ret.size() * sizeof(ustring::value_type);
291         ret.resize(ret.size() * 2);
292         ret_data = reinterpret_cast<char *>(&ret[0]) + delta;
293         ir = iconv(static_cast<iconv_t>(ic), (ICONV_CONST char **)&str_data, &str_len_char, &ret_data, &ret_len_left);
294         if (ir == (size_t)-1) {
295             return ustring();
296         }
297     }
298     ret.resize(ret.size() - ret_len_left / sizeof(ustring::value_type));
299 
300     return ret;
301 }
302 
from_latin1(const std::string & str)303 ustring ustring::from_latin1(const std::string &str)
304 {
305     const size_type l = str.size();
306     if (!l) {
307         return ustring();
308     }
309     const char *c = str.data();
310     ustring ret(l, 0);
311     for (size_type i = 0; i < l; ++i) {
312         ret[i] = static_cast<unsigned char>(*c);
313         c++;
314     }
315     return ret;
316 }
317 
318 /**
319  Converts a string representing a PDF date to a value compatible with time_t.
320  */
convert_date(const std::string & date)321 time_type poppler::convert_date(const std::string &date)
322 {
323     GooString gooDateStr(date.c_str());
324     return dateStringToTime(&gooDateStr);
325 }
326 
operator <<(std::ostream & stream,const byte_array & array)327 std::ostream &poppler::operator<<(std::ostream &stream, const byte_array &array)
328 {
329     stream << "[";
330     const std::ios_base::fmtflags f = stream.flags();
331     std::hex(stream);
332     const char *data = &array[0];
333     const byte_array::size_type out_len = std::min<byte_array::size_type>(array.size(), 50);
334     for (byte_array::size_type i = 0; i < out_len; ++i) {
335         if (i != 0) {
336             stream << " ";
337         }
338         stream << ((data[i] & 0xf0) >> 4) << (data[i] & 0xf);
339     }
340     stream.flags(f);
341     if (out_len < array.size()) {
342         stream << " ...";
343     }
344     stream << "]";
345     return stream;
346 }
347 
348 /**
349  * Sets a custom data directory for initialization of global parameters
350  *
351  * If no instances of \see document currently exist, this will save the
352  * given path as a custom data directory to be used when the first instance
353  * of the \see document is constructed.
354  *
355  * \returns true on success, false on failure
356  *
357  * \since 0.73.0
358  */
set_data_dir(const std::string & new_data_dir)359 bool poppler::set_data_dir(const std::string &new_data_dir)
360 {
361     return GlobalParamsIniter::setCustomDataDir(new_data_dir);
362 }
363 
364 /**
365  \typedef poppler::debug_func
366 
367  Debug/error function.
368 
369  This function type is used for debugging & error output;
370  the first parameter is the actual message, the second is the unaltered
371  closure argument which was passed to the set_debug_error_function() call.
372 
373  \since 0.30.0
374  */
375 
376 /**
377  Set a new debug/error output function.
378 
379  If not set, by default error and debug messages will be sent to stderr.
380 
381  \param debug_function the new debug function
382  \param closure user data which will be passed as-is to the debug function
383 
384  \since 0.30.0
385  */
set_debug_error_function(debug_func debug_function,void * closure)386 void poppler::set_debug_error_function(debug_func debug_function, void *closure)
387 {
388     poppler::detail::user_debug_function = debug_function;
389     poppler::detail::debug_closure = closure;
390 }
391