w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

FileSpec.cc
Go to the documentation of this file.
1 //========================================================================
2 //
3 // FileSpec.cc
4 //
5 // All changes made under the Poppler project to this file are licensed
6 // under GPL version 2 or later
7 //
8 // Copyright (C) 2008-2009 Carlos Garcia Campos <carlosgc@gnome.org>
9 // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
10 // Copyright (C) 2012, 2017-2020 Albert Astals Cid <aacid@kde.org>
11 // Copyright (C) 2012 Hib Eris <hib@hiberis.nl>
12 // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
13 // Copyright (C) 2018 Adam Reichold <adam.reichold@t-online.de>
14 // Copyright (C) 2019 Christian Persch <chpe@src.gnome.org>
15 //
16 // To see a description of the changes please see the Changelog file that
17 // came with your tarball or type make ChangeLog if you are building from git
18 //
19 //========================================================================
20 
21 //========================================================================
22 //
23 // Most of the code from Link.cc and PSOutputDev.cc
24 //
25 // Copyright 1996-2003 Glyph & Cog, LLC
26 //
27 //========================================================================
28 
29 #include <config.h>
30 
31 #include "FileSpec.h"
32 #include "XRef.h"
33 #include "goo/gfile.h"
34 
35 EmbFile::EmbFile(Object &&efStream)
36 {
37  m_size = -1;
38  m_createDate = nullptr;
39  m_modDate = nullptr;
40  m_checksum = nullptr;
41  m_mimetype = nullptr;
42 
43  m_objStr = std::move(efStream);
44 
45  if (m_objStr.isStream()) {
46  // dataDict corresponds to Table 3.41 in the PDF1.6 spec.
47  Dict *dataDict = m_objStr.streamGetDict();
48 
49  // subtype is normally the mimetype
50  Object subtypeName = dataDict->lookup("Subtype");
51  if (subtypeName.isName()) {
52  m_mimetype = new GooString(subtypeName.getName());
53  }
54 
55  // paramDict corresponds to Table 3.42 in the PDF1.6 spec
56  Object paramDict = dataDict->lookup("Params");
57  if (paramDict.isDict()) {
58  Object paramObj = paramDict.dictLookup("ModDate");
59  if (paramObj.isString())
60  m_modDate = new GooString(paramObj.getString());
61 
62  paramObj = paramDict.dictLookup("CreationDate");
63  if (paramObj.isString())
64  m_createDate = new GooString(paramObj.getString());
65 
66  paramObj = paramDict.dictLookup("Size");
67  if (paramObj.isInt())
68  m_size = paramObj.getInt();
69 
70  paramObj = paramDict.dictLookup("CheckSum");
71  if (paramObj.isString())
72  m_checksum = new GooString(paramObj.getString());
73  }
74  }
75 }
76 
78 {
79  delete m_createDate;
80  delete m_modDate;
81  delete m_checksum;
82  delete m_mimetype;
83 }
84 
85 bool EmbFile::save(const char *path)
86 {
87  FILE *f;
88  bool ret;
89 
90  if (!(f = openFile(path, "wb"))) {
91  return false;
92  }
93  ret = save2(f);
94  fclose(f);
95  return ret;
96 }
97 
98 bool EmbFile::save2(FILE *f)
99 {
100  int c;
101 
102  if (unlikely(!m_objStr.isStream()))
103  return false;
104 
106  while ((c = m_objStr.streamGetChar()) != EOF) {
107  fputc(c, f);
108  }
109  return true;
110 }
111 
112 FileSpec::FileSpec(const Object *fileSpecA)
113 {
114  ok = true;
115  fileName = nullptr;
116  platformFileName = nullptr;
117  embFile = nullptr;
118  desc = nullptr;
119  fileSpec = fileSpecA->copy();
120 
121  Object obj1 = getFileSpecName(fileSpecA);
122  if (!obj1.isString()) {
123  ok = false;
124  error(errSyntaxError, -1, "Invalid FileSpec");
125  return;
126  }
127 
128  fileName = obj1.getString()->copy();
129 
130  if (fileSpec.isDict()) {
131  obj1 = fileSpec.dictLookup("EF");
132  if (obj1.isDict()) {
133  fileStream = obj1.dictLookupNF("F").copy();
134  if (!fileStream.isRef()) {
135  ok = false;
137  error(errSyntaxError, -1, "Invalid FileSpec: Embedded file stream is not an indirect reference");
138  return;
139  }
140  }
141 
142  obj1 = fileSpec.dictLookup("Desc");
143  if (obj1.isString()) {
144  desc = obj1.getString()->copy();
145  }
146  }
147 }
148 
150 {
151  delete fileName;
152  delete platformFileName;
153  delete embFile;
154  delete desc;
155 }
156 
158 {
159  if (!ok || !fileSpec.isDict())
160  return nullptr;
161 
162  if (embFile)
163  return embFile;
164 
165  XRef *xref = fileSpec.getDict()->getXRef();
167 
168  return embFile;
169 }
170 
172 {
173  Object paramsDict = Object(new Dict(xref));
174  paramsDict.dictSet("Size", Object(file->size()));
175 
176  // No Subtype in the embedded file stream dictionary for now
177  Object streamDict = Object(new Dict(xref));
178  streamDict.dictSet("Length", Object(file->size()));
179  streamDict.dictSet("Params", std::move(paramsDict));
180 
181  FileStream *fStream = new FileStream(file, 0, false, file->size(), std::move(streamDict));
182  fStream->setNeedsEncryptionOnSave(true);
183  Stream *stream = fStream;
184  Object streamObj = Object(stream);
185  const Ref streamRef = xref->addIndirectObject(&streamObj);
186 
187  Dict *efDict = new Dict(xref);
188  efDict->set("F", Object(streamRef));
189 
190  Dict *fsDict = new Dict(xref);
191  fsDict->set("Type", Object(objName, "Filespec"));
192  fsDict->set("UF", Object(new GooString(fileName)));
193  fsDict->set("EF", Object(efDict));
194 
195  return Object(fsDict);
196 }
197 
199 {
200  if (platformFileName)
201  return platformFileName;
202 
204  if (obj1.isString())
205  platformFileName = obj1.getString()->copy();
206 
207  return platformFileName;
208 }
209 
210 Object getFileSpecName(const Object *fileSpec)
211 {
212  if (fileSpec->isString()) {
213  return fileSpec->copy();
214  }
215 
216  if (fileSpec->isDict()) {
217  Object fileName = fileSpec->dictLookup("UF");
218  if (fileName.isString()) {
219  return fileName;
220  }
221  fileName = fileSpec->dictLookup("F");
222  if (fileName.isString()) {
223  return fileName;
224  }
225  fileName = fileSpec->dictLookup("DOS");
226  if (fileName.isString()) {
227  return fileName;
228  }
229  fileName = fileSpec->dictLookup("Mac");
230  if (fileName.isString()) {
231  return fileName;
232  }
233  fileName = fileSpec->dictLookup("Unix");
234  if (fileName.isString()) {
235  return fileName;
236  }
237  }
238  return Object();
239 }
240 
242 {
243  if (fileSpec->isString()) {
244  return fileSpec->copy();
245  }
246 
248  if (fileSpec->isDict()) {
249  fileName = fileSpec->dictLookup("UF");
250  if (!fileName.isString()) {
251  fileName = fileSpec->dictLookup("F");
252  if (!fileName.isString()) {
253 #ifdef _WIN32
254  const char *platform = "DOS";
255 #else
256  const char *platform = "Unix";
257 #endif
258  fileName = fileSpec->dictLookup(platform);
259  if (!fileName.isString()) {
260  error(errSyntaxError, -1, "Illegal file spec");
261  return Object();
262  }
263  }
264  }
265  } else {
266  error(errSyntaxError, -1, "Illegal file spec");
267  return Object();
268  }
269 
270  // system-dependent path manipulation
271 #ifdef _WIN32
272  int i, j;
273  GooString *name = fileName.getString()->copy();
274  // "//...." --> "\...."
275  // "/x/...." --> "x:\...."
276  // "/server/share/...." --> "\\server\share\...."
277  // convert escaped slashes to slashes and unescaped slashes to backslashes
278  i = 0;
279  if (name->getChar(0) == '/') {
280  if (name->getLength() >= 2 && name->getChar(1) == '/') {
281  name->del(0);
282  i = 0;
283  } else if (name->getLength() >= 2 && ((name->getChar(1) >= 'a' && name->getChar(1) <= 'z') || (name->getChar(1) >= 'A' && name->getChar(1) <= 'Z')) && (name->getLength() == 2 || name->getChar(2) == '/')) {
284  name->setChar(0, name->getChar(1));
285  name->setChar(1, ':');
286  i = 2;
287  } else {
288  for (j = 2; j < name->getLength(); ++j) {
289  if (name->getChar(j - 1) != '\\' && name->getChar(j) == '/') {
290  break;
291  }
292  }
293  if (j < name->getLength()) {
294  name->setChar(0, '\\');
295  name->insert(0, '\\');
296  i = 2;
297  }
298  }
299  }
300  for (; i < name->getLength(); ++i) {
301  if (name->getChar(i) == '/') {
302  name->setChar(i, '\\');
303  } else if (name->getChar(i) == '\\' && i + 1 < name->getLength() && name->getChar(i + 1) == '/') {
304  name->del(i);
305  }
306  }
307  fileName = Object(name);
308 #endif /* _WIN32 */
309 
310  return fileName;
311 }
#define name
Definition: Dict.h:29
XRef * getXRef() const
Definition: Dict.h:99
Object * lookup(const char *key, Object *obj, int recursion=0)
Definition: Dict.cc:122
void set(const char *key, Object &&val)
Definition: Dict.cc:142
GooString * m_modDate
Definition: FileSpec.h:45
GooString * m_mimetype
Definition: FileSpec.h:47
bool save(const char *path)
Definition: FileSpec.cc:85
int m_size
Definition: FileSpec.h:43
GooString * m_checksum
Definition: FileSpec.h:46
~EmbFile()
Definition: FileSpec.cc:77
GooString * m_createDate
Definition: FileSpec.h:44
bool save2(FILE *f)
Definition: FileSpec.cc:98
Object m_objStr
Definition: FileSpec.h:48
EmbFile(Object &&efStream)
Definition: FileSpec.cc:35
GooString * desc
Definition: FileSpec.h:78
static Object newFileSpecObject(XRef *xref, GooFile *file, const std::string &fileName)
Definition: FileSpec.cc:171
Object fileStream
Definition: FileSpec.h:76
~FileSpec()
Definition: FileSpec.cc:149
Object fileSpec
Definition: FileSpec.h:72
GooString * getFileNameForPlatform()
Definition: FileSpec.cc:198
EmbFile * embFile
Definition: FileSpec.h:77
FileSpec(const Object *fileSpec)
Definition: FileSpec.cc:112
EmbFile * getEmbeddedFile()
Definition: FileSpec.cc:157
GooString * fileName
Definition: FileSpec.h:74
GooString * platformFileName
Definition: FileSpec.h:75
bool ok
Definition: FileSpec.h:70
void setNeedsEncryptionOnSave(bool needsEncryptionOnSaveA)
Definition: Stream.h:540
GString * copy()
Definition: GString.h:42
Definition: gfile.h:115
Definition: Object.h:84
GBool isDict()
Definition: Object.h:137
Object * dictLookup(const char *key, Object *obj, int recursion=0)
Definition: Object.h:266
void setToNull()
Definition: Object.h:259
GBool isName()
Definition: Object.h:134
GBool isStream()
Definition: Object.h:138
GBool isRef()
Definition: Object.h:139
Object * copy(Object *obj)
Definition: Object.cc:80
Object * fetch(XRef *xref, Object *obj, int recursion=0)
Definition: Object.cc:114
char * getName()
Definition: Object.h:159
int getInt()
Definition: Object.h:155
GBool isInt()
Definition: Object.h:130
Dict * streamGetDict()
Definition: Object.h:317
void streamReset()
Definition: Object.h:293
int streamGetChar()
Definition: Object.h:299
GBool isString()
Definition: Object.h:133
GString * getString()
Definition: Object.h:158
Dict * getDict()
Definition: Object.h:161
Object * dictLookupNF(const char *key, Object *obj)
Definition: Object.h:269
void dictSet(const char *key, Object &&val)
Definition: Object.h:595
Definition: Stream.h:67
Definition: XRef.h:58
#define error(a)
Definition: dviinfo.c:48
struct _FileStream FileStream
Definition: filestrm.h:32
struct move_struct move
mpz_t * f
Definition: gen-fib.c:34
#define c(n)
Definition: gpos-common.c:150
#define unlikely(x)
Definition: jbig2arith.cc:116
small capitals from c petite p scientific i
Definition: afcover.h:80
#define EOF
Definition: afmparse.c:59
FILE * openFile(const char *path, const char *mode)
Definition: gfile.cc:612
@ errSyntaxError
Definition: Error.h:25
@ objName
Definition: Object.h:52
unsigned short platform
Definition: cidtype2.c:153
#define fclose
Definition: debug.h:100
static int ret
Definition: convert.c:72
#define string
Definition: ctangleboot.c:111
int getLength(char *s)
Definition: lengths.c:99
Object getFileSpecName(const Object *fileSpec)
Definition: FileSpec.cc:210
Object getFileSpecNameForPlatform(const Object *fileSpec)
Definition: FileSpec.cc:241
struct stream_s stream
Definition: pts_fax.h:93
Definition: Object.h:37
Definition: filedef.h:30
Definition: tpic.c:45
#define FILE
Definition: t1stdio.h:34
int j
Definition: t4ht.c:1589
#define xref
Definition: tex2xindy.c:758
const char * fileName
Definition: ugrep.cpp:52