| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | |
| 6 | |
| 7 #include "core/fpdfapi/fpdf_parser/fpdf_parser_utility.h" | |
| 8 | |
| 9 #include "core/fpdfapi/fpdf_parser/cpdf_array.h" | |
| 10 #include "core/fpdfapi/fpdf_parser/cpdf_dictionary.h" | |
| 11 #include "core/fpdfapi/fpdf_parser/cpdf_number.h" | |
| 12 #include "core/fpdfapi/fpdf_parser/cpdf_reference.h" | |
| 13 #include "core/fpdfapi/fpdf_parser/cpdf_stream.h" | |
| 14 #include "core/fpdfapi/fpdf_parser/cpdf_stream_acc.h" | |
| 15 #include "core/fpdfapi/fpdf_parser/cpdf_string.h" | |
| 16 #include "core/fpdfapi/fpdf_parser/fpdf_parser_decode.h" | |
| 17 #include "core/fxcrt/fx_ext.h" | |
| 18 | |
| 19 // Indexed by 8-bit character code, contains either: | |
| 20 // 'W' - for whitespace: NUL, TAB, CR, LF, FF, SPACE, 0x80, 0xff | |
| 21 // 'N' - for numeric: 0123456789+-. | |
| 22 // 'D' - for delimiter: %()/<>[]{} | |
| 23 // 'R' - otherwise. | |
| 24 const char PDF_CharType[256] = { | |
| 25 // NUL SOH STX ETX EOT ENQ ACK BEL BS HT LF VT FF CR SO | |
| 26 // SI | |
| 27 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W', 'W', 'R', 'W', 'W', 'R', | |
| 28 'R', | |
| 29 | |
| 30 // DLE DC1 DC2 DC3 DC4 NAK SYN ETB CAN EM SUB ESC FS GS RS | |
| 31 // US | |
| 32 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 33 'R', | |
| 34 | |
| 35 // SP ! " # $ % & ยด ( ) * + , - . | |
| 36 // / | |
| 37 'W', 'R', 'R', 'R', 'R', 'D', 'R', 'R', 'D', 'D', 'R', 'N', 'R', 'N', 'N', | |
| 38 'D', | |
| 39 | |
| 40 // 0 1 2 3 4 5 6 7 8 9 : ; < = > ? | |
| 41 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'R', 'R', 'D', 'R', 'D', | |
| 42 'R', | |
| 43 | |
| 44 // @ A B C D E F G H I J K L M N O | |
| 45 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 46 'R', | |
| 47 | |
| 48 // P Q R S T U V W X Y Z [ \ ] ^ _ | |
| 49 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', | |
| 50 'R', | |
| 51 | |
| 52 // ` a b c d e f g h i j k l m n o | |
| 53 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 54 'R', | |
| 55 | |
| 56 // p q r s t u v w x y z { | } ~ | |
| 57 // DEL | |
| 58 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'D', 'R', 'D', 'R', | |
| 59 'R', | |
| 60 | |
| 61 'W', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 62 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 63 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 64 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 65 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 66 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 67 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 68 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'R', | |
| 69 'R', 'R', 'R', 'R', 'R', 'R', 'R', 'W'}; | |
| 70 | |
| 71 int32_t GetHeaderOffset(IFX_FileRead* pFile) { | |
| 72 const size_t kBufSize = 4; | |
| 73 uint8_t buf[kBufSize]; | |
| 74 for (int32_t offset = 0; offset <= 1024; ++offset) { | |
| 75 if (!pFile->ReadBlock(buf, offset, kBufSize)) | |
| 76 return -1; | |
| 77 | |
| 78 if (memcmp(buf, "%PDF", 4) == 0) | |
| 79 return offset; | |
| 80 } | |
| 81 return -1; | |
| 82 } | |
| 83 | |
| 84 int32_t GetDirectInteger(CPDF_Dictionary* pDict, const CFX_ByteString& key) { | |
| 85 CPDF_Number* pObj = ToNumber(pDict->GetObjectFor(key)); | |
| 86 return pObj ? pObj->GetInteger() : 0; | |
| 87 } | |
| 88 | |
| 89 CFX_ByteString PDF_NameDecode(const CFX_ByteStringC& bstr) { | |
| 90 if (bstr.Find('#') == -1) | |
| 91 return CFX_ByteString(bstr); | |
| 92 | |
| 93 int size = bstr.GetLength(); | |
| 94 CFX_ByteString result; | |
| 95 FX_CHAR* pDestStart = result.GetBuffer(size); | |
| 96 FX_CHAR* pDest = pDestStart; | |
| 97 for (int i = 0; i < size; i++) { | |
| 98 if (bstr[i] == '#' && i < size - 2) { | |
| 99 *pDest++ = | |
| 100 FXSYS_toHexDigit(bstr[i + 1]) * 16 + FXSYS_toHexDigit(bstr[i + 2]); | |
| 101 i += 2; | |
| 102 } else { | |
| 103 *pDest++ = bstr[i]; | |
| 104 } | |
| 105 } | |
| 106 result.ReleaseBuffer((FX_STRSIZE)(pDest - pDestStart)); | |
| 107 return result; | |
| 108 } | |
| 109 | |
| 110 CFX_ByteString PDF_NameDecode(const CFX_ByteString& orig) { | |
| 111 if (orig.Find('#') == -1) | |
| 112 return orig; | |
| 113 return PDF_NameDecode(orig.AsStringC()); | |
| 114 } | |
| 115 | |
| 116 CFX_ByteString PDF_NameEncode(const CFX_ByteString& orig) { | |
| 117 uint8_t* src_buf = (uint8_t*)orig.c_str(); | |
| 118 int src_len = orig.GetLength(); | |
| 119 int dest_len = 0; | |
| 120 int i; | |
| 121 for (i = 0; i < src_len; i++) { | |
| 122 uint8_t ch = src_buf[i]; | |
| 123 if (ch >= 0x80 || PDFCharIsWhitespace(ch) || ch == '#' || | |
| 124 PDFCharIsDelimiter(ch)) { | |
| 125 dest_len += 3; | |
| 126 } else { | |
| 127 dest_len++; | |
| 128 } | |
| 129 } | |
| 130 if (dest_len == src_len) | |
| 131 return orig; | |
| 132 | |
| 133 CFX_ByteString res; | |
| 134 FX_CHAR* dest_buf = res.GetBuffer(dest_len); | |
| 135 dest_len = 0; | |
| 136 for (i = 0; i < src_len; i++) { | |
| 137 uint8_t ch = src_buf[i]; | |
| 138 if (ch >= 0x80 || PDFCharIsWhitespace(ch) || ch == '#' || | |
| 139 PDFCharIsDelimiter(ch)) { | |
| 140 dest_buf[dest_len++] = '#'; | |
| 141 dest_buf[dest_len++] = "0123456789ABCDEF"[ch / 16]; | |
| 142 dest_buf[dest_len++] = "0123456789ABCDEF"[ch % 16]; | |
| 143 } else { | |
| 144 dest_buf[dest_len++] = ch; | |
| 145 } | |
| 146 } | |
| 147 dest_buf[dest_len] = 0; | |
| 148 res.ReleaseBuffer(); | |
| 149 return res; | |
| 150 } | |
| 151 | |
| 152 CFX_ByteTextBuf& operator<<(CFX_ByteTextBuf& buf, const CPDF_Object* pObj) { | |
| 153 if (!pObj) { | |
| 154 buf << " null"; | |
| 155 return buf; | |
| 156 } | |
| 157 switch (pObj->GetType()) { | |
| 158 case CPDF_Object::NULLOBJ: | |
| 159 buf << " null"; | |
| 160 break; | |
| 161 case CPDF_Object::BOOLEAN: | |
| 162 case CPDF_Object::NUMBER: | |
| 163 buf << " " << pObj->GetString(); | |
| 164 break; | |
| 165 case CPDF_Object::STRING: | |
| 166 buf << PDF_EncodeString(pObj->GetString(), pObj->AsString()->IsHex()); | |
| 167 break; | |
| 168 case CPDF_Object::NAME: { | |
| 169 CFX_ByteString str = pObj->GetString(); | |
| 170 buf << "/" << PDF_NameEncode(str); | |
| 171 break; | |
| 172 } | |
| 173 case CPDF_Object::REFERENCE: { | |
| 174 buf << " " << pObj->AsReference()->GetRefObjNum() << " 0 R "; | |
| 175 break; | |
| 176 } | |
| 177 case CPDF_Object::ARRAY: { | |
| 178 const CPDF_Array* p = pObj->AsArray(); | |
| 179 buf << "["; | |
| 180 for (size_t i = 0; i < p->GetCount(); i++) { | |
| 181 CPDF_Object* pElement = p->GetObjectAt(i); | |
| 182 if (pElement && pElement->GetObjNum()) { | |
| 183 buf << " " << pElement->GetObjNum() << " 0 R"; | |
| 184 } else { | |
| 185 buf << pElement; | |
| 186 } | |
| 187 } | |
| 188 buf << "]"; | |
| 189 break; | |
| 190 } | |
| 191 case CPDF_Object::DICTIONARY: { | |
| 192 const CPDF_Dictionary* p = pObj->AsDictionary(); | |
| 193 buf << "<<"; | |
| 194 for (const auto& it : *p) { | |
| 195 const CFX_ByteString& key = it.first; | |
| 196 CPDF_Object* pValue = it.second; | |
| 197 buf << "/" << PDF_NameEncode(key); | |
| 198 if (pValue && pValue->GetObjNum()) { | |
| 199 buf << " " << pValue->GetObjNum() << " 0 R "; | |
| 200 } else { | |
| 201 buf << pValue; | |
| 202 } | |
| 203 } | |
| 204 buf << ">>"; | |
| 205 break; | |
| 206 } | |
| 207 case CPDF_Object::STREAM: { | |
| 208 const CPDF_Stream* p = pObj->AsStream(); | |
| 209 buf << p->GetDict() << "stream\r\n"; | |
| 210 CPDF_StreamAcc acc; | |
| 211 acc.LoadAllData(p, TRUE); | |
| 212 buf.AppendBlock(acc.GetData(), acc.GetSize()); | |
| 213 buf << "\r\nendstream"; | |
| 214 break; | |
| 215 } | |
| 216 default: | |
| 217 ASSERT(FALSE); | |
| 218 break; | |
| 219 } | |
| 220 return buf; | |
| 221 } | |
| OLD | NEW |