fork(7) download
  1. #! /usr/bin/python
  2.  
  3. # ineptpdf8.4.52.pyw
  4. # ineptpdf, version 8.4.52
  5.  
  6. # To run this program install Python 2.7 from http://w...content-available-to-author-only...n.org/download/
  7. #
  8. # PyCrypto from http://w...content-available-to-author-only...g.uk/python/modules.shtml#pycrypto
  9. #
  10. # and PyWin Extension (Win32API module) from
  11. # http://s...content-available-to-author-only...e.net/projects/pywin32/files/
  12. #
  13. # Make sure to install the dedicated versions for Python 2.7.
  14. #
  15. # It's recommended to use the 32-Bit Python Windows versions (even with a 64-bit
  16. # Windows system).
  17. #
  18. # Save this script file as
  19. # ineptpdf8.4.52.pyw and double-click on it to run it.
  20.  
  21. # Revision history:
  22. # 1 - Initial release
  23. # 2 - Improved determination of key-generation algorithm
  24. # 3 - Correctly handle PDF >=1.5 cross-reference streams
  25. # 4 - Removal of ciando's personal ID (anon)
  26. # 5 - removing small bug with V3 ebooks (anon)
  27. # 6 - changed to adeptkey4.der format for 1.7.2 support (anon)
  28. # 6.1 - backward compatibility for 1.7.1 and old adeptkey.der (anon)
  29. # 7 - Get cross reference streams and object streams working for input.
  30. # Not yet supported on output but this only effects file size,
  31. # not functionality. (anon2)
  32. # 7.1 - Correct a problem when an old trailer is not followed by startxref (anon2)
  33. # 7.2 - Correct malformed Mac OS resource forks for Stanza
  34. # - Support for cross ref streams on output (decreases file size) (anon2)
  35. # 7.3 - Correct bug in trailer with cross ref stream that caused the error (anon2)
  36. # "The root object is missing or invalid" in Adobe Reader.
  37. # 7.4 - Force all generation numbers in output file to be 0, like in v6.
  38. # Fallback code for wrong xref improved (search till last trailer
  39. # instead of first) (anon2)
  40. # 8 - fileopen user machine identifier support (Tetrachroma)
  41. # 8.1 - fileopen user cookies support (Tetrachroma)
  42. # 8.2 - fileopen user name/password support (Tetrachroma)
  43. # 8.3 - fileopen session cookie support (Tetrachroma)
  44. # 8.3.1 - fix for the "specified key file does not exist" error (Tetrachroma)
  45. # 8.3.2 - improved server result parsing (Tetrachroma)
  46. # 8.4 - Ident4D and encrypted Uuid support (Tetrachroma)
  47. # 8.4.1 - improved MAC address processing (Tetrachroma)
  48. # 8.4.2 - FowP3Uuid fallback file processing (Tetrachroma)
  49. # 8.4.3 - improved user/password pdf file detection (Tetrachroma)
  50. # 8.4.4 - small bugfix (Tetrachroma)
  51. # 8.4.5 - improved cookie host searching (Tetrachroma)
  52. # 8.4.6 - STRICT parsing disabled (non-standard pdf processing) (Tetrachroma)
  53. # 8.4.7 - UTF-8 input file conversion (Tetrachroma)
  54. # 8.4.8 - fix for more rare utf8 problems (Tetrachroma)
  55. # 8.4.9 - solution for utf8 in comination with
  56. # ident4id method (Tetrachroma)
  57. # 8.4.10 - line feed processing, non c system drive patch, nrbook support (Tetrachroma)
  58. # 8.4.11 - alternative ident4id calculation (Tetrachroma)
  59. # 8.4.12 - fix for capital username characters and
  60. # other unusual user login names (Tetrachroma & ZeroPoint)
  61. # 8.4.13 - small bug fixes (Tetrachroma)
  62. # 8.4.14 - fix for non-standard-conform fileopen pdfs (Tetrachroma)
  63. # 8.4.15 - 'bad file descriptor'-fix (Tetrachroma)
  64. # 8.4.16 - improves user/pass detection (Tetrachroma)
  65. # 8.4.17 - fix for several '=' chars in a DPRM entity (Tetrachroma)
  66. # 8.4.18 - follow up bug fix for the DPRM problem,
  67. # more readable error messages (Tetrachroma)
  68. # 8.4.19 - 2nd fix for 'bad file descriptor' problem (Tetrachroma)
  69. # 8.4.20 - follow up patch (Tetrachroma)
  70. # 8.4.21 - 3rd patch for 'bad file descriptor' (Tetrachroma)
  71. # 8.4.22 - disable prints for exception prevention (Tetrachroma)
  72. # 8.4.23 - check for additional security attributes (Tetrachroma)
  73. # 8.4.24 - improved cookie session support (Tetrachroma)
  74. # 8.4.25 - more compatibility with unicode files (Tetrachroma)
  75. # 8.4.26 - automated session/user cookie request function (works
  76. # only with Firefox 3.x+) (Tetrachroma)
  77. # 8.4.27 - user/password fallback
  78. # 8.4.28 - AES decryption, improved misconfigured pdf handling,
  79. # limited experimental APS support (Tetrachroma & Neisklar)
  80. # 8.4.29 - backport for bad formatted rc4 encrypted pdfs (Tetrachroma)
  81. # 8.4.30 - extended authorization attributes support (Tetrachroma)
  82. # 8.4.31 - improved session cookie and better server response error
  83. # handling (Tetrachroma)
  84. # 8.4.33 - small cookie optimizations (Tetrachroma)
  85. # 8.4.33 - debug output option (Tetrachroma)
  86. # 8.4.34 - better user/password management
  87. # handles the 'AskUnp' response) (Tetrachroma)
  88. # 8.4.35 - special handling for non-standard systems (Tetrachroma)
  89. # 8.4.36 - previous machine/disk handling [PrevMach/PrevDisk] (Tetrachroma)
  90. # 8.4.36 - FOPN_flock support (Tetrachroma)
  91. # 8.4.37 - patch for unicode paths/filenames (Tetrachroma)
  92. # 8.4.38 - small fix for user/password dialog (Tetrachroma)
  93. # 8.4.39 - sophisticated request mode differentiation, forced
  94. # uuid calculation (Tetrachroma)
  95. # 8.4.40 - fix for non standard server responses (Tetrachroma)
  96. # 8.4.41 - improved user/password request windows,
  97. # better server response tolerance (Tetrachroma)
  98. # 8.4.42 - improved nl/cr server response parsing (Tetrachroma)
  99. # 8.4.43 - fix for user names longer than 13 characters and special
  100. # uuid encryption (Tetrachroma)
  101. # 8.4.44 - another fix for ident4d problem (Tetrachroma)
  102. # 8.4.45 - 2nd fix for ident4d problem (Tetrachroma)
  103. # 8.4.46 - script cleanup and optimizations (Tetrachroma)
  104. # 8.4.47 - script identification change to Adobe Reader (Tetrachroma)
  105. # 8.4.48 - improved tolerance for false file/registry entries (Tetrachroma)
  106. # 8.4.49 - improved username encryption (Tetrachroma)
  107. # 8.4.50 - improved (experimental) APS support (Tetrachroma & Neisklar)
  108. # 8.4.51 - automatic APS offline key retrieval (works only for
  109. # Onleihe right now) (80ka80 & Tetrachroma)
  110. # 8.4.52 - fixed linux support (mazdac) - gets mac from eth0, if doesn't work change hardcodedinterface
  111.  
  112. """
  113. Decrypts Adobe ADEPT-encrypted and Fileopen PDF files.
  114. """
  115.  
  116. from __future__ import with_statement
  117.  
  118. __license__ = 'GPL v3'
  119.  
  120. import sys
  121. import os
  122. import re
  123. import zlib
  124. import struct
  125. import hashlib
  126. from itertools import chain, islice
  127. import xml.etree.ElementTree as etree
  128. import Tkinter
  129. import Tkconstants
  130. import tkFileDialog
  131. import tkMessageBox
  132. # added for fileopen support
  133. import urllib
  134. import urlparse
  135. import time
  136. import socket
  137. import string
  138. import uuid
  139. import subprocess
  140. import time
  141. import getpass
  142. from ctypes import *
  143. import traceback
  144. import inspect
  145. import tempfile
  146. import sqlite3
  147. import httplib
  148. try:
  149. from Crypto.Cipher import ARC4
  150. # needed for newer pdfs
  151. from Crypto.Cipher import AES
  152. from Crypto.Hash import SHA256
  153. from Crypto.PublicKey import RSA
  154.  
  155. except ImportError:
  156. ARC4 = None
  157. RSA = None
  158. try:
  159. from cStringIO import StringIO
  160. except ImportError:
  161. from StringIO import StringIO
  162.  
  163. class ADEPTError(Exception):
  164. pass
  165.  
  166. # global variable (needed for fileopen and password decryption)
  167. INPUTFILEPATH = ''
  168. KEYFILEPATH = ''
  169. PASSWORD = ''
  170. DEBUG_MODE = False
  171. IVERSION = '8.4.52'
  172. INTERFACE = 'eth0'
  173.  
  174. # Do we generate cross reference streams on output?
  175. # 0 = never
  176. # 1 = only if present in input
  177. # 2 = always
  178.  
  179. GEN_XREF_STM = 1
  180.  
  181. # This is the value for the current document
  182. gen_xref_stm = False # will be set in PDFSerializer
  183.  
  184. ###
  185. ### ASN.1 parsing code from tlslite
  186.  
  187. def bytesToNumber(bytes):
  188. total = 0L
  189. for byte in bytes:
  190. total = (total << 8) + byte
  191. return total
  192.  
  193. class ASN1Error(Exception):
  194. pass
  195.  
  196. class ASN1Parser(object):
  197. class Parser(object):
  198. def __init__(self, bytes):
  199. self.bytes = bytes
  200. self.index = 0
  201.  
  202. def get(self, length):
  203. if self.index + length > len(self.bytes):
  204. raise ASN1Error("Error decoding ASN.1")
  205. x = 0
  206. for count in range(length):
  207. x <<= 8
  208. x |= self.bytes[self.index]
  209. self.index += 1
  210. return x
  211.  
  212. def getFixBytes(self, lengthBytes):
  213. bytes = self.bytes[self.index : self.index+lengthBytes]
  214. self.index += lengthBytes
  215. return bytes
  216.  
  217. def getVarBytes(self, lengthLength):
  218. lengthBytes = self.get(lengthLength)
  219. return self.getFixBytes(lengthBytes)
  220.  
  221. def getFixList(self, length, lengthList):
  222. l = [0] * lengthList
  223. for x in range(lengthList):
  224. l[x] = self.get(length)
  225. return l
  226.  
  227. def getVarList(self, length, lengthLength):
  228. lengthList = self.get(lengthLength)
  229. if lengthList % length != 0:
  230. raise ASN1Error("Error decoding ASN.1")
  231. lengthList = int(lengthList/length)
  232. l = [0] * lengthList
  233. for x in range(lengthList):
  234. l[x] = self.get(length)
  235. return l
  236.  
  237. def startLengthCheck(self, lengthLength):
  238. self.lengthCheck = self.get(lengthLength)
  239. self.indexCheck = self.index
  240.  
  241. def setLengthCheck(self, length):
  242. self.lengthCheck = length
  243. self.indexCheck = self.index
  244.  
  245. def stopLengthCheck(self):
  246. if (self.index - self.indexCheck) != self.lengthCheck:
  247. raise ASN1Error("Error decoding ASN.1")
  248.  
  249. def atLengthCheck(self):
  250. if (self.index - self.indexCheck) < self.lengthCheck:
  251. return False
  252. elif (self.index - self.indexCheck) == self.lengthCheck:
  253. return True
  254. else:
  255. raise ASN1Error("Error decoding ASN.1")
  256.  
  257. def __init__(self, bytes):
  258. p = self.Parser(bytes)
  259. p.get(1)
  260. self.length = self._getASN1Length(p)
  261. self.value = p.getFixBytes(self.length)
  262.  
  263. def getChild(self, which):
  264. p = self.Parser(self.value)
  265. for x in range(which+1):
  266. markIndex = p.index
  267. p.get(1)
  268. length = self._getASN1Length(p)
  269. p.getFixBytes(length)
  270. return ASN1Parser(p.bytes[markIndex:p.index])
  271.  
  272. def _getASN1Length(self, p):
  273. firstLength = p.get(1)
  274. if firstLength<=127:
  275. return firstLength
  276. else:
  277. lengthLength = firstLength & 0x7F
  278. return p.get(lengthLength)
  279.  
  280. ###
  281. ### PDF parsing routines from pdfminer, with changes for EBX_HANDLER
  282.  
  283. ## Utilities
  284. ##
  285. def choplist(n, seq):
  286. '''Groups every n elements of the list.'''
  287. r = []
  288. for x in seq:
  289. r.append(x)
  290. if len(r) == n:
  291. yield tuple(r)
  292. r = []
  293. return
  294.  
  295. def nunpack(s, default=0):
  296. '''Unpacks up to 4 bytes big endian.'''
  297. l = len(s)
  298. if not l:
  299. return default
  300. elif l == 1:
  301. return ord(s)
  302. elif l == 2:
  303. return struct.unpack('>H', s)[0]
  304. elif l == 3:
  305. return struct.unpack('>L', '\x00'+s)[0]
  306. elif l == 4:
  307. return struct.unpack('>L', s)[0]
  308. else:
  309. return TypeError('invalid length: %d' % l)
  310.  
  311.  
  312. STRICT = 0
  313.  
  314.  
  315. ## PS Exceptions
  316. ##
  317. class PSException(Exception): pass
  318. class PSEOF(PSException): pass
  319. class PSSyntaxError(PSException): pass
  320. class PSTypeError(PSException): pass
  321. class PSValueError(PSException): pass
  322.  
  323.  
  324. ## Basic PostScript Types
  325. ##
  326.  
  327. # PSLiteral
  328. class PSObject(object): pass
  329.  
  330. class PSLiteral(PSObject):
  331. '''
  332. PS literals (e.g. "/Name").
  333. Caution: Never create these objects directly.
  334. Use PSLiteralTable.intern() instead.
  335. '''
  336. def __init__(self, name):
  337. self.name = name
  338. return
  339.  
  340. def __repr__(self):
  341. name = []
  342. for char in self.name:
  343. if not char.isalnum():
  344. char = '#%02x' % ord(char)
  345. name.append(char)
  346. return '/%s' % ''.join(name)
  347.  
  348. # PSKeyword
  349. class PSKeyword(PSObject):
  350. '''
  351. PS keywords (e.g. "showpage").
  352. Caution: Never create these objects directly.
  353. Use PSKeywordTable.intern() instead.
  354. '''
  355. def __init__(self, name):
  356. self.name = name
  357. return
  358.  
  359. def __repr__(self):
  360. return self.name
  361.  
  362. # PSSymbolTable
  363. class PSSymbolTable(object):
  364.  
  365. '''
  366. Symbol table that stores PSLiteral or PSKeyword.
  367. '''
  368.  
  369. def __init__(self, classe):
  370. self.dic = {}
  371. self.classe = classe
  372. return
  373.  
  374. def intern(self, name):
  375. if name in self.dic:
  376. lit = self.dic[name]
  377. else:
  378. lit = self.classe(name)
  379. self.dic[name] = lit
  380. return lit
  381.  
  382. PSLiteralTable = PSSymbolTable(PSLiteral)
  383. PSKeywordTable = PSSymbolTable(PSKeyword)
  384. LIT = PSLiteralTable.intern
  385. KWD = PSKeywordTable.intern
  386. KEYWORD_BRACE_BEGIN = KWD('{')
  387. KEYWORD_BRACE_END = KWD('}')
  388. KEYWORD_ARRAY_BEGIN = KWD('[')
  389. KEYWORD_ARRAY_END = KWD(']')
  390. KEYWORD_DICT_BEGIN = KWD('<<')
  391. KEYWORD_DICT_END = KWD('>>')
  392.  
  393.  
  394. def literal_name(x):
  395. if not isinstance(x, PSLiteral):
  396. if STRICT:
  397. raise PSTypeError('Literal required: %r' % x)
  398. else:
  399. return str(x)
  400. return x.name
  401.  
  402. def keyword_name(x):
  403. if not isinstance(x, PSKeyword):
  404. if STRICT:
  405. raise PSTypeError('Keyword required: %r' % x)
  406. else:
  407. return str(x)
  408. return x.name
  409.  
  410.  
  411. ## PSBaseParser
  412. ##
  413. EOL = re.compile(r'[\r\n]')
  414. SPC = re.compile(r'\s')
  415. NONSPC = re.compile(r'\S')
  416. HEX = re.compile(r'[0-9a-fA-F]')
  417. END_LITERAL = re.compile(r'[#/%\[\]()<>{}\s]')
  418. END_HEX_STRING = re.compile(r'[^\s0-9a-fA-F]')
  419. HEX_PAIR = re.compile(r'[0-9a-fA-F]{2}|.')
  420. END_NUMBER = re.compile(r'[^0-9]')
  421. END_KEYWORD = re.compile(r'[#/%\[\]()<>{}\s]')
  422. END_STRING = re.compile(r'[()\134]')
  423. OCT_STRING = re.compile(r'[0-7]')
  424. ESC_STRING = { 'b':8, 't':9, 'n':10, 'f':12, 'r':13, '(':40, ')':41, '\\':92 }
  425.  
  426. class PSBaseParser(object):
  427.  
  428. '''
  429. Most basic PostScript parser that performs only basic tokenization.
  430. '''
  431. BUFSIZ = 4096
  432.  
  433. def __init__(self, fp):
  434. self.fp = fp
  435. self.seek(0)
  436. return
  437.  
  438. def __repr__(self):
  439. return '<PSBaseParser: %r, bufpos=%d>' % (self.fp, self.bufpos)
  440.  
  441. def flush(self):
  442. return
  443.  
  444. def close(self):
  445. self.flush()
  446. return
  447.  
  448. def tell(self):
  449. return self.bufpos+self.charpos
  450.  
  451. def poll(self, pos=None, n=80):
  452. pos0 = self.fp.tell()
  453. if not pos:
  454. pos = self.bufpos+self.charpos
  455. self.fp.seek(pos)
  456. ##print >>sys.stderr, 'poll(%d): %r' % (pos, self.fp.read(n))
  457. self.fp.seek(pos0)
  458. return
  459.  
  460. def seek(self, pos):
  461. '''
  462. Seeks the parser to the given position.
  463. '''
  464. self.fp.seek(pos)
  465. # reset the status for nextline()
  466. self.bufpos = pos
  467. self.buf = ''
  468. self.charpos = 0
  469. # reset the status for nexttoken()
  470. self.parse1 = self.parse_main
  471. self.tokens = []
  472. return
  473.  
  474. def fillbuf(self):
  475. if self.charpos < len(self.buf): return
  476. # fetch next chunk.
  477. self.bufpos = self.fp.tell()
  478. self.buf = self.fp.read(self.BUFSIZ)
  479. if not self.buf:
  480. raise PSEOF('Unexpected EOF')
  481. self.charpos = 0
  482. return
  483.  
  484. def parse_main(self, s, i):
  485. m = NONSPC.search(s, i)
  486. if not m:
  487. return (self.parse_main, len(s))
  488. j = m.start(0)
  489. c = s[j]
  490. self.tokenstart = self.bufpos+j
  491. if c == '%':
  492. self.token = '%'
  493. return (self.parse_comment, j+1)
  494. if c == '/':
  495. self.token = ''
  496. return (self.parse_literal, j+1)
  497. if c in '-+' or c.isdigit():
  498. self.token = c
  499. return (self.parse_number, j+1)
  500. if c == '.':
  501. self.token = c
  502. return (self.parse_float, j+1)
  503. if c.isalpha():
  504. self.token = c
  505. return (self.parse_keyword, j+1)
  506. if c == '(':
  507. self.token = ''
  508. self.paren = 1
  509. return (self.parse_string, j+1)
  510. if c == '<':
  511. self.token = ''
  512. return (self.parse_wopen, j+1)
  513. if c == '>':
  514. self.token = ''
  515. return (self.parse_wclose, j+1)
  516. self.add_token(KWD(c))
  517. return (self.parse_main, j+1)
  518.  
  519. def add_token(self, obj):
  520. self.tokens.append((self.tokenstart, obj))
  521. return
  522.  
  523. def parse_comment(self, s, i):
  524. m = EOL.search(s, i)
  525. if not m:
  526. self.token += s[i:]
  527. return (self.parse_comment, len(s))
  528. j = m.start(0)
  529. self.token += s[i:j]
  530. # We ignore comments.
  531. #self.tokens.append(self.token)
  532. return (self.parse_main, j)
  533.  
  534. def parse_literal(self, s, i):
  535. m = END_LITERAL.search(s, i)
  536. if not m:
  537. self.token += s[i:]
  538. return (self.parse_literal, len(s))
  539. j = m.start(0)
  540. self.token += s[i:j]
  541. c = s[j]
  542. if c == '#':
  543. self.hex = ''
  544. return (self.parse_literal_hex, j+1)
  545. self.add_token(LIT(self.token))
  546. return (self.parse_main, j)
  547.  
  548. def parse_literal_hex(self, s, i):
  549. c = s[i]
  550. if HEX.match(c) and len(self.hex) < 2:
  551. self.hex += c
  552. return (self.parse_literal_hex, i+1)
  553. if self.hex:
  554. self.token += chr(int(self.hex, 16))
  555. return (self.parse_literal, i)
  556.  
  557. def parse_number(self, s, i):
  558. m = END_NUMBER.search(s, i)
  559. if not m:
  560. self.token += s[i:]
  561. return (self.parse_number, len(s))
  562. j = m.start(0)
  563. self.token += s[i:j]
  564. c = s[j]
  565. if c == '.':
  566. self.token += c
  567. return (self.parse_float, j+1)
  568. try:
  569. self.add_token(int(self.token))
  570. except ValueError:
  571. pass
  572. return (self.parse_main, j)
  573. def parse_float(self, s, i):
  574. m = END_NUMBER.search(s, i)
  575. if not m:
  576. self.token += s[i:]
  577. return (self.parse_float, len(s))
  578. j = m.start(0)
  579. self.token += s[i:j]
  580. self.add_token(float(self.token))
  581. return (self.parse_main, j)
  582.  
  583. def parse_keyword(self, s, i):
  584. m = END_KEYWORD.search(s, i)
  585. if not m:
  586. self.token += s[i:]
  587. return (self.parse_keyword, len(s))
  588. j = m.start(0)
  589. self.token += s[i:j]
  590. if self.token == 'true':
  591. token = True
  592. elif self.token == 'false':
  593. token = False
  594. else:
  595. token = KWD(self.token)
  596. self.add_token(token)
  597. return (self.parse_main, j)
  598.  
  599. def parse_string(self, s, i):
  600. m = END_STRING.search(s, i)
  601. if not m:
  602. self.token += s[i:]
  603. return (self.parse_string, len(s))
  604. j = m.start(0)
  605. self.token += s[i:j]
  606. c = s[j]
  607. if c == '\\':
  608. self.oct = ''
  609. return (self.parse_string_1, j+1)
  610. if c == '(':
  611. self.paren += 1
  612. self.token += c
  613. return (self.parse_string, j+1)
  614. if c == ')':
  615. self.paren -= 1
  616. if self.paren:
  617. self.token += c
  618. return (self.parse_string, j+1)
  619. self.add_token(self.token)
  620. return (self.parse_main, j+1)
  621. def parse_string_1(self, s, i):
  622. c = s[i]
  623. if OCT_STRING.match(c) and len(self.oct) < 3:
  624. self.oct += c
  625. return (self.parse_string_1, i+1)
  626. if self.oct:
  627. self.token += chr(int(self.oct, 8))
  628. return (self.parse_string, i)
  629. if c in ESC_STRING:
  630. self.token += chr(ESC_STRING[c])
  631. return (self.parse_string, i+1)
  632.  
  633. def parse_wopen(self, s, i):
  634. c = s[i]
  635. if c.isspace() or HEX.match(c):
  636. return (self.parse_hexstring, i)
  637. if c == '<':
  638. self.add_token(KEYWORD_DICT_BEGIN)
  639. i += 1
  640. return (self.parse_main, i)
  641.  
  642. def parse_wclose(self, s, i):
  643. c = s[i]
  644. if c == '>':
  645. self.add_token(KEYWORD_DICT_END)
  646. i += 1
  647. return (self.parse_main, i)
  648.  
  649. def parse_hexstring(self, s, i):
  650. m = END_HEX_STRING.search(s, i)
  651. if not m:
  652. self.token += s[i:]
  653. return (self.parse_hexstring, len(s))
  654. j = m.start(0)
  655. self.token += s[i:j]
  656. token = HEX_PAIR.sub(lambda m: chr(int(m.group(0), 16)),
  657. SPC.sub('', self.token))
  658. self.add_token(token)
  659. return (self.parse_main, j)
  660.  
  661. def nexttoken(self):
  662. while not self.tokens:
  663. self.fillbuf()
  664. (self.parse1, self.charpos) = self.parse1(self.buf, self.charpos)
  665. token = self.tokens.pop(0)
  666. return token
  667.  
  668. def nextline(self):
  669. '''
  670. Fetches a next line that ends either with \\r or \\n.
  671. '''
  672. linebuf = ''
  673. linepos = self.bufpos + self.charpos
  674. eol = False
  675. while 1:
  676. self.fillbuf()
  677. if eol:
  678. c = self.buf[self.charpos]
  679. # handle '\r\n'
  680. if c == '\n':
  681. linebuf += c
  682. self.charpos += 1
  683. break
  684. m = EOL.search(self.buf, self.charpos)
  685. if m:
  686. linebuf += self.buf[self.charpos:m.end(0)]
  687. self.charpos = m.end(0)
  688. if linebuf[-1] == '\r':
  689. eol = True
  690. else:
  691. break
  692. else:
  693. linebuf += self.buf[self.charpos:]
  694. self.charpos = len(self.buf)
  695. return (linepos, linebuf)
  696.  
  697. def revreadlines(self):
  698. '''
  699. Fetches a next line backword. This is used to locate
  700. the trailers at the end of a file.
  701. '''
  702. self.fp.seek(0, 2)
  703. pos = self.fp.tell()
  704. buf = ''
  705. while 0 < pos:
  706. prevpos = pos
  707. pos = max(0, pos-self.BUFSIZ)
  708. self.fp.seek(pos)
  709. s = self.fp.read(prevpos-pos)
  710. if not s: break
  711. while 1:
  712. n = max(s.rfind('\r'), s.rfind('\n'))
  713. if n == -1:
  714. buf = s + buf
  715. break
  716. yield s[n:]+buf
  717. s = s[:n]
  718. buf = ''
  719. return
  720.  
  721.  
  722. ## PSStackParser
  723. ##
  724. class PSStackParser(PSBaseParser):
  725.  
  726. def __init__(self, fp):
  727. PSBaseParser.__init__(self, fp)
  728. self.reset()
  729. return
  730.  
  731. def reset(self):
  732. self.context = []
  733. self.curtype = None
  734. self.curstack = []
  735. self.results = []
  736. return
  737.  
  738. def seek(self, pos):
  739. PSBaseParser.seek(self, pos)
  740. self.reset()
  741. return
  742.  
  743. def push(self, *objs):
  744. self.curstack.extend(objs)
  745. return
  746. def pop(self, n):
  747. objs = self.curstack[-n:]
  748. self.curstack[-n:] = []
  749. return objs
  750. def popall(self):
  751. objs = self.curstack
  752. self.curstack = []
  753. return objs
  754. def add_results(self, *objs):
  755. self.results.extend(objs)
  756. return
  757.  
  758. def start_type(self, pos, type):
  759. self.context.append((pos, self.curtype, self.curstack))
  760. (self.curtype, self.curstack) = (type, [])
  761. return
  762. def end_type(self, type):
  763. if self.curtype != type:
  764. raise PSTypeError('Type mismatch: %r != %r' % (self.curtype, type))
  765. objs = [ obj for (_,obj) in self.curstack ]
  766. (pos, self.curtype, self.curstack) = self.context.pop()
  767. return (pos, objs)
  768.  
  769. def do_keyword(self, pos, token):
  770. return
  771.  
  772. def nextobject(self, direct=False):
  773. '''
  774. Yields a list of objects: keywords, literals, strings,
  775. numbers, arrays and dictionaries. Arrays and dictionaries
  776. are represented as Python sequence and dictionaries.
  777. '''
  778. while not self.results:
  779. (pos, token) = self.nexttoken()
  780. ##print (pos,token), (self.curtype, self.curstack)
  781. if (isinstance(token, int) or
  782. isinstance(token, float) or
  783. isinstance(token, bool) or
  784. isinstance(token, str) or
  785. isinstance(token, PSLiteral)):
  786. # normal token
  787. self.push((pos, token))
  788. elif token == KEYWORD_ARRAY_BEGIN:
  789. # begin array
  790. self.start_type(pos, 'a')
  791. elif token == KEYWORD_ARRAY_END:
  792. # end array
  793. try:
  794. self.push(self.end_type('a'))
  795. except PSTypeError:
  796. if STRICT: raise
  797. elif token == KEYWORD_DICT_BEGIN:
  798. # begin dictionary
  799. self.start_type(pos, 'd')
  800. elif token == KEYWORD_DICT_END:
  801. # end dictionary
  802. try:
  803. (pos, objs) = self.end_type('d')
  804. if len(objs) % 2 != 0:
  805. raise PSSyntaxError(
  806. 'Invalid dictionary construct: %r' % objs)
  807. d = dict((literal_name(k), v) \
  808. for (k,v) in choplist(2, objs))
  809. self.push((pos, d))
  810. except PSTypeError:
  811. if STRICT: raise
  812. else:
  813. self.do_keyword(pos, token)
  814. if self.context:
  815. continue
  816. else:
  817. if direct:
  818. return self.pop(1)[0]
  819. self.flush()
  820. obj = self.results.pop(0)
  821. return obj
  822.  
  823.  
  824. LITERAL_CRYPT = PSLiteralTable.intern('Crypt')
  825. LITERALS_FLATE_DECODE = (PSLiteralTable.intern('FlateDecode'), PSLiteralTable.intern('Fl'))
  826. LITERALS_LZW_DECODE = (PSLiteralTable.intern('LZWDecode'), PSLiteralTable.intern('LZW'))
  827. LITERALS_ASCII85_DECODE = (PSLiteralTable.intern('ASCII85Decode'), PSLiteralTable.intern('A85'))
  828.  
  829.  
  830. ## PDF Objects
  831. ##
  832. class PDFObject(PSObject): pass
  833.  
  834. class PDFException(PSException): pass
  835. class PDFTypeError(PDFException): pass
  836. class PDFValueError(PDFException): pass
  837. class PDFNotImplementedError(PSException): pass
  838.  
  839.  
  840. ## PDFObjRef
  841. ##
  842. class PDFObjRef(PDFObject):
  843.  
  844. def __init__(self, doc, objid, genno):
  845. if objid == 0:
  846. if STRICT:
  847. raise PDFValueError('PDF object id cannot be 0.')
  848. self.doc = doc
  849. self.objid = objid
  850. self.genno = genno
  851. return
  852.  
  853. def __repr__(self):
  854. return '<PDFObjRef:%d %d>' % (self.objid, self.genno)
  855.  
  856. def resolve(self):
  857. return self.doc.getobj(self.objid)
  858.  
  859.  
  860. # resolve
  861. def resolve1(x):
  862. '''
  863. Resolve an object. If this is an array or dictionary,
  864. it may still contains some indirect objects inside.
  865. '''
  866. while isinstance(x, PDFObjRef):
  867. x = x.resolve()
  868. return x
  869.  
  870. def resolve_all(x):
  871. '''
  872. Recursively resolve X and all the internals.
  873. Make sure there is no indirect reference within the nested object.
  874. This procedure might be slow.
  875. '''
  876. while isinstance(x, PDFObjRef):
  877. x = x.resolve()
  878. if isinstance(x, list):
  879. x = [ resolve_all(v) for v in x ]
  880. elif isinstance(x, dict):
  881. for (k,v) in x.iteritems():
  882. x[k] = resolve_all(v)
  883. return x
  884.  
  885. def decipher_all(decipher, objid, genno, x):
  886. '''
  887. Recursively decipher X.
  888. '''
  889. if isinstance(x, str):
  890. return decipher(objid, genno, x)
  891. decf = lambda v: decipher_all(decipher, objid, genno, v)
  892. if isinstance(x, list):
  893. x = [decf(v) for v in x]
  894. elif isinstance(x, dict):
  895. x = dict((k, decf(v)) for (k, v) in x.iteritems())
  896. return x
  897.  
  898.  
  899. # Type cheking
  900. def int_value(x):
  901. x = resolve1(x)
  902. if not isinstance(x, int):
  903. if STRICT:
  904. raise PDFTypeError('Integer required: %r' % x)
  905. return 0
  906. return x
  907.  
  908. def float_value(x):
  909. x = resolve1(x)
  910. if not isinstance(x, float):
  911. if STRICT:
  912. raise PDFTypeError('Float required: %r' % x)
  913. return 0.0
  914. return x
  915.  
  916. def num_value(x):
  917. x = resolve1(x)
  918. if not (isinstance(x, int) or isinstance(x, float)):
  919. if STRICT:
  920. raise PDFTypeError('Int or Float required: %r' % x)
  921. return 0
  922. return x
  923.  
  924. def str_value(x):
  925. x = resolve1(x)
  926. if not isinstance(x, str):
  927. if STRICT:
  928. raise PDFTypeError('String required: %r' % x)
  929. return ''
  930. return x
  931.  
  932. def list_value(x):
  933. x = resolve1(x)
  934. if not (isinstance(x, list) or isinstance(x, tuple)):
  935. if STRICT:
  936. raise PDFTypeError('List required: %r' % x)
  937. return []
  938. return x
  939.  
  940. def dict_value(x):
  941. x = resolve1(x)
  942. if not isinstance(x, dict):
  943. if STRICT:
  944. raise PDFTypeError('Dict required: %r' % x)
  945. return {}
  946. return x
  947.  
  948. def stream_value(x):
  949. x = resolve1(x)
  950. if not isinstance(x, PDFStream):
  951. if STRICT:
  952. raise PDFTypeError('PDFStream required: %r' % x)
  953. return PDFStream({}, '')
  954. return x
  955.  
  956. # ascii85decode(data)
  957. def ascii85decode(data):
  958. n = b = 0
  959. out = ''
  960. for c in data:
  961. if '!' <= c and c <= 'u':
  962. n += 1
  963. b = b*85+(ord(c)-33)
  964. if n == 5:
  965. out += struct.pack('>L',b)
  966. n = b = 0
  967. elif c == 'z':
  968. assert n == 0
  969. out += '\0\0\0\0'
  970. elif c == '~':
  971. if n:
  972. for _ in range(5-n):
  973. b = b*85+84
  974. out += struct.pack('>L',b)[:n-1]
  975. break
  976. return out
  977.  
  978.  
  979. ## PDFStream type
  980. class PDFStream(PDFObject):
  981. def __init__(self, dic, rawdata, decipher=None):
  982. length = int_value(dic.get('Length', 0))
  983. eol = rawdata[length:]
  984. # quick and dirty fix for false length attribute,
  985. # might not work if the pdf stream parser has a problem
  986. if decipher != None and decipher.__name__ == 'decrypt_aes':
  987. if (len(rawdata) % 16) != 0:
  988. cutdiv = len(rawdata) // 16
  989. rawdata = rawdata[:16*cutdiv]
  990. else:
  991. if eol in ('\r', '\n', '\r\n'):
  992. rawdata = rawdata[:length]
  993.  
  994. self.dic = dic
  995. self.rawdata = rawdata
  996. self.decipher = decipher
  997. self.data = None
  998. self.decdata = None
  999. self.objid = None
  1000. self.genno = None
  1001. return
  1002.  
  1003. def set_objid(self, objid, genno):
  1004. self.objid = objid
  1005. self.genno = genno
  1006. return
  1007.  
  1008. def __repr__(self):
  1009. if self.rawdata:
  1010. return '<PDFStream(%r): raw=%d, %r>' % \
  1011. (self.objid, len(self.rawdata), self.dic)
  1012. else:
  1013. return '<PDFStream(%r): data=%d, %r>' % \
  1014. (self.objid, len(self.data), self.dic)
  1015.  
  1016. def decode(self):
  1017. assert self.data is None and self.rawdata is not None
  1018. data = self.rawdata
  1019. if self.decipher:
  1020. # Handle encryption
  1021. data = self.decipher(self.objid, self.genno, data)
  1022. if gen_xref_stm:
  1023. self.decdata = data # keep decrypted data
  1024. if 'Filter' not in self.dic:
  1025. self.data = data
  1026. self.rawdata = None
  1027. ##print self.dict
  1028. return
  1029. filters = self.dic['Filter']
  1030. if not isinstance(filters, list):
  1031. filters = [ filters ]
  1032. for f in filters:
  1033. if f in LITERALS_FLATE_DECODE:
  1034. # will get errors if the document is encrypted.
  1035. data = zlib.decompress(data)
  1036. elif f in LITERALS_LZW_DECODE:
  1037. data = ''.join(LZWDecoder(StringIO(data)).run())
  1038. elif f in LITERALS_ASCII85_DECODE:
  1039. data = ascii85decode(data)
  1040. elif f == LITERAL_CRYPT:
  1041. raise PDFNotImplementedError('/Crypt filter is unsupported')
  1042. else:
  1043. raise PDFNotImplementedError('Unsupported filter: %r' % f)
  1044. # apply predictors
  1045. if 'DP' in self.dic:
  1046. params = self.dic['DP']
  1047. else:
  1048. params = self.dic.get('DecodeParms', {})
  1049. if 'Predictor' in params:
  1050. pred = int_value(params['Predictor'])
  1051. if pred:
  1052. if pred != 12:
  1053. raise PDFNotImplementedError(
  1054. 'Unsupported predictor: %r' % pred)
  1055. if 'Columns' not in params:
  1056. raise PDFValueError(
  1057. 'Columns undefined for predictor=12')
  1058. columns = int_value(params['Columns'])
  1059. buf = ''
  1060. ent0 = '\x00' * columns
  1061. for i in xrange(0, len(data), columns+1):
  1062. pred = data[i]
  1063. ent1 = data[i+1:i+1+columns]
  1064. if pred == '\x02':
  1065. ent1 = ''.join(chr((ord(a)+ord(b)) & 255) \
  1066. for (a,b) in zip(ent0,ent1))
  1067. buf += ent1
  1068. ent0 = ent1
  1069. data = buf
  1070. self.data = data
  1071. self.rawdata = None
  1072. return
  1073.  
  1074. def get_data(self):
  1075. if self.data is None:
  1076. self.decode()
  1077. return self.data
  1078.  
  1079. def get_rawdata(self):
  1080. return self.rawdata
  1081.  
  1082. def get_decdata(self):
  1083. if self.decdata is not None:
  1084. return self.decdata
  1085. data = self.rawdata
  1086. if self.decipher and data:
  1087. # Handle encryption
  1088. data = self.decipher(self.objid, self.genno, data)
  1089. return data
  1090.  
  1091.  
  1092. ## PDF Exceptions
  1093. ##
  1094. class PDFSyntaxError(PDFException): pass
  1095. class PDFNoValidXRef(PDFSyntaxError): pass
  1096. class PDFEncryptionError(PDFException): pass
  1097. class PDFPasswordIncorrect(PDFEncryptionError): pass
  1098.  
  1099. # some predefined literals and keywords.
  1100. LITERAL_OBJSTM = PSLiteralTable.intern('ObjStm')
  1101. LITERAL_XREF = PSLiteralTable.intern('XRef')
  1102. LITERAL_PAGE = PSLiteralTable.intern('Page')
  1103. LITERAL_PAGES = PSLiteralTable.intern('Pages')
  1104. LITERAL_CATALOG = PSLiteralTable.intern('Catalog')
  1105.  
  1106.  
  1107. ## XRefs
  1108. ##
  1109.  
  1110. ## PDFXRef
  1111. ##
  1112. class PDFXRef(object):
  1113.  
  1114. def __init__(self):
  1115. self.offsets = None
  1116. return
  1117.  
  1118. def __repr__(self):
  1119. return '<PDFXRef: objs=%d>' % len(self.offsets)
  1120.  
  1121. def objids(self):
  1122. return self.offsets.iterkeys()
  1123.  
  1124. def load(self, parser):
  1125. self.offsets = {}
  1126. while 1:
  1127. try:
  1128. (pos, line) = parser.nextline()
  1129. except PSEOF:
  1130. raise PDFNoValidXRef('Unexpected EOF - file corrupted?')
  1131. if not line:
  1132. raise PDFNoValidXRef('Premature eof: %r' % parser)
  1133. if line.startswith('trailer'):
  1134. parser.seek(pos)
  1135. break
  1136. f = line.strip().split(' ')
  1137. if len(f) != 2:
  1138. raise PDFNoValidXRef('Trailer not found: %r: line=%r' % (parser, line))
  1139. try:
  1140. (start, nobjs) = map(int, f)
  1141. except ValueError:
  1142. raise PDFNoValidXRef('Invalid line: %r: line=%r' % (parser, line))
  1143. for objid in xrange(start, start+nobjs):
  1144. try:
  1145. (_, line) = parser.nextline()
  1146. except PSEOF:
  1147. raise PDFNoValidXRef('Unexpected EOF - file corrupted?')
  1148. f = line.strip().split(' ')
  1149. if len(f) != 3:
  1150. raise PDFNoValidXRef('Invalid XRef format: %r, line=%r' % (parser, line))
  1151. (pos, genno, use) = f
  1152. if use != 'n': continue
  1153. self.offsets[objid] = (int(genno), int(pos))
  1154. self.load_trailer(parser)
  1155. return
  1156.  
  1157. KEYWORD_TRAILER = PSKeywordTable.intern('trailer')
  1158. def load_trailer(self, parser):
  1159. try:
  1160. (_,kwd) = parser.nexttoken()
  1161. assert kwd is self.KEYWORD_TRAILER
  1162. (_,dic) = parser.nextobject(direct=True)
  1163. except PSEOF:
  1164. x = parser.pop(1)
  1165. if not x:
  1166. raise PDFNoValidXRef('Unexpected EOF - file corrupted')
  1167. (_,dic) = x[0]
  1168. self.trailer = dict_value(dic)
  1169. return
  1170.  
  1171. def getpos(self, objid):
  1172. try:
  1173. (genno, pos) = self.offsets[objid]
  1174. except KeyError:
  1175. raise
  1176. return (None, pos)
  1177.  
  1178.  
  1179. ## PDFXRefStream
  1180. ##
  1181. class PDFXRefStream(object):
  1182.  
  1183. def __init__(self):
  1184. self.index = None
  1185. self.data = None
  1186. self.entlen = None
  1187. self.fl1 = self.fl2 = self.fl3 = None
  1188. return
  1189.  
  1190. def __repr__(self):
  1191. return '<PDFXRef: objids=%s>' % self.index
  1192.  
  1193. def objids(self):
  1194. for first, size in self.index:
  1195. for objid in xrange(first, first + size):
  1196. yield objid
  1197.  
  1198. def load(self, parser, debug=0):
  1199. (_,objid) = parser.nexttoken() # ignored
  1200. (_,genno) = parser.nexttoken() # ignored
  1201. (_,kwd) = parser.nexttoken()
  1202. (_,stream) = parser.nextobject()
  1203. if not isinstance(stream, PDFStream) or \
  1204. stream.dic['Type'] is not LITERAL_XREF:
  1205. raise PDFNoValidXRef('Invalid PDF stream spec.')
  1206. size = stream.dic['Size']
  1207. index = stream.dic.get('Index', (0,size))
  1208. self.index = zip(islice(index, 0, None, 2),
  1209. islice(index, 1, None, 2))
  1210. (self.fl1, self.fl2, self.fl3) = stream.dic['W']
  1211. self.data = stream.get_data()
  1212. self.entlen = self.fl1+self.fl2+self.fl3
  1213. self.trailer = stream.dic
  1214. return
  1215.  
  1216. def getpos(self, objid):
  1217. offset = 0
  1218. for first, size in self.index:
  1219. if first <= objid and objid < (first + size):
  1220. break
  1221. offset += size
  1222. else:
  1223. raise KeyError(objid)
  1224. i = self.entlen * ((objid - first) + offset)
  1225. ent = self.data[i:i+self.entlen]
  1226. f1 = nunpack(ent[:self.fl1], 1)
  1227. if f1 == 1:
  1228. pos = nunpack(ent[self.fl1:self.fl1+self.fl2])
  1229. genno = nunpack(ent[self.fl1+self.fl2:])
  1230. return (None, pos)
  1231. elif f1 == 2:
  1232. objid = nunpack(ent[self.fl1:self.fl1+self.fl2])
  1233. index = nunpack(ent[self.fl1+self.fl2:])
  1234. return (objid, index)
  1235. # this is a free object
  1236. raise KeyError(objid)
  1237.  
  1238.  
  1239. ## PDFDocument
  1240. ##
  1241. ## A PDFDocument object represents a PDF document.
  1242. ## Since a PDF file is usually pretty big, normally it is not loaded
  1243. ## at once. Rather it is parsed dynamically as processing goes.
  1244. ## A PDF parser is associated with the document.
  1245. ##
  1246. class PDFDocument(object):
  1247.  
  1248. def __init__(self):
  1249. self.xrefs = []
  1250. self.objs = {}
  1251. self.parsed_objs = {}
  1252. self.root = None
  1253. self.catalog = None
  1254. self.parser = None
  1255. self.encryption = None
  1256. self.decipher = None
  1257. # dictionaries for fileopen
  1258. self.fileopen = {}
  1259. self.urlresult = {}
  1260. self.ready = False
  1261. return
  1262.  
  1263. # set_parser(parser)
  1264. # Associates the document with an (already initialized) parser object.
  1265. def set_parser(self, parser):
  1266. if self.parser: return
  1267. self.parser = parser
  1268. # The document is set to be temporarily ready during collecting
  1269. # all the basic information about the document, e.g.
  1270. # the header, the encryption information, and the access rights
  1271. # for the document.
  1272. self.ready = True
  1273. # Retrieve the information of each header that was appended
  1274. # (maybe multiple times) at the end of the document.
  1275. self.xrefs = parser.read_xref()
  1276. for xref in self.xrefs:
  1277. trailer = xref.trailer
  1278. if not trailer: continue
  1279.  
  1280. # If there's an encryption info, remember it.
  1281. if 'Encrypt' in trailer:
  1282. #assert not self.encryption
  1283. try:
  1284. self.encryption = (list_value(trailer['ID']),
  1285. dict_value(trailer['Encrypt']))
  1286. # fix for bad files
  1287. except:
  1288. self.encryption = ('ffffffffffffffffffffffffffffffffffff',
  1289. dict_value(trailer['Encrypt']))
  1290. if 'Root' in trailer:
  1291. self.set_root(dict_value(trailer['Root']))
  1292. break
  1293. else:
  1294. raise PDFSyntaxError('No /Root object! - Is this really a PDF?')
  1295. # The document is set to be non-ready again, until all the
  1296. # proper initialization (asking the password key and
  1297. # verifying the access permission, so on) is finished.
  1298. self.ready = False
  1299. return
  1300.  
  1301. # set_root(root)
  1302. # Set the Root dictionary of the document.
  1303. # Each PDF file must have exactly one /Root dictionary.
  1304. def set_root(self, root):
  1305. self.root = root
  1306. self.catalog = dict_value(self.root)
  1307. if self.catalog.get('Type') is not LITERAL_CATALOG:
  1308. if STRICT:
  1309. raise PDFSyntaxError('Catalog not found!')
  1310. return
  1311. # initialize(password='')
  1312. # Perform the initialization with a given password.
  1313. # This step is mandatory even if there's no password associated
  1314. # with the document.
  1315. def initialize(self, password=''):
  1316. if not self.encryption:
  1317. self.is_printable = self.is_modifiable = self.is_extractable = True
  1318. self.ready = True
  1319. return
  1320. (docid, param) = self.encryption
  1321. type = literal_name(param['Filter'])
  1322. if type == 'Adobe.APS':
  1323. return self.initialize_adobe_ps(password, docid, param)
  1324. if type == 'Standard':
  1325. return self.initialize_standard(password, docid, param)
  1326. if type == 'EBX_HANDLER':
  1327. return self.initialize_ebx(password, docid, param)
  1328. if type == 'FOPN_fLock':
  1329. # remove of unnecessairy password attribute
  1330. return self.initialize_fopn_flock(docid, param)
  1331. if type == 'FOPN_foweb':
  1332. # remove of unnecessairy password attribute
  1333. return self.initialize_fopn(docid, param)
  1334. raise PDFEncryptionError('Unknown filter: param=%r' % param)
  1335.  
  1336. def initialize_adobe_ps(self, password, docid, param):
  1337. global KEYFILEPATH
  1338. self.decrypt_key = self.genkey_adobe_ps(param)
  1339. self.genkey = self.genkey_v4
  1340. self.decipher = self.decrypt_aes
  1341. self.ready = True
  1342. return
  1343.  
  1344. def getPrincipalKey(self, k=None, url=None, referer=None):
  1345. if url == None:
  1346. url="ssl://edc.bibliothek-digital.de/edcws/services/urn:EDCLicenseService"
  1347. data1='<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SO'+\
  1348. 'AP-ENV="http://s...content-available-to-author-only...p.org/soap/envelope/" xmlns:SOAP-ENC="http'+\
  1349. '://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://w...content-available-to-author-only...3.org/2001/'+\
  1350. 'XMLSchema-instance" xmlns:xsd="http://w...content-available-to-author-only...3.org/2001/XMLSchema" xmlns:tns1="'+\
  1351. 'http://e...content-available-to-author-only...e.com/edcwebservice" xmlns:impl="http://localhost:8080/axis/s'+\
  1352. 'ervices/urn:EDCLicenseService" xmlns:ns2="http://c...content-available-to-author-only...e.com" xmlns:ns1="'+\
  1353. 'http://n...content-available-to-author-only...e.com/PolicyServer/ws"><SOAP-ENV:Header><EDCSecurity>&lt;wsse:Security '+\
  1354. 'xmlns:wsse="http://d...content-available-to-author-only...n.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-'+\
  1355. '1.0.xsd"&gt;&lt;wsse:UsernameToken&gt;&lt;wsse:Username&gt;edc_anonymous&lt;/wsse:Username&'+\
  1356. 'gt;&lt;wsse:Password Type="http://d...content-available-to-author-only...n.org/wss/2004/01/oasis-200401-wss-username-'+\
  1357. 'token-profile-1.0#PasswordText"&gt;edc_anonymous&lt;/wsse:Password&gt;&lt;/wsse:UsernameToken&'+\
  1358. 'gt;&lt;/wsse:Security&gt;</EDCSecurity><Version>7</Version><Locale>de-de</Locale></SOAP-ENV:Header>'+\
  1359. '<SOAP-ENV:Body><impl:synchronize><SynchronizationRequest><firstTime>1</firstTime><licenseSeqNum>0</'+\
  1360. 'licenseSeqNum><policySeqNum>1</policySeqNum><revocationSeqNum>0</revocationSeqNum><'+\
  1361. 'watermarkTemplateSeqNum>0</watermarkTemplateSeqNum></SynchronizationRequest></'+\
  1362. 'impl:synchronize></SOAP-ENV:Body></SOAP-ENV:Envelope>'
  1363. if k not in url[:40]:
  1364. return None
  1365. #~ extract host and path:
  1366. host=re.compile(r'[a-zA-Z]://([^/]+)/.+', re.I).search(url).group(1)
  1367. urlpath=re.compile(r'[a-zA-Z]://[^/]+(/.+)', re.I).search(url).group(1)
  1368.  
  1369. # open a socket connection on port 80
  1370.  
  1371. conn = httplib.HTTPSConnection(host, 443)
  1372.  
  1373. #~ Headers for request
  1374. headers={"Accept": "*/*", "Host": host, "User-Agent": "Mozilla/3.0 (compatible; Acrobat EDC SOAP 1.0)",
  1375. "Content-Type": "text/xml; charset=utf-8", "Cache-Control": "no-cache", "SOAPAction": ""}
  1376.  
  1377. # send data1 and headers
  1378. try:
  1379. conn.request("POST", urlpath, data1, headers)
  1380. except:
  1381. raise ADEPTError("Could not post request to '"+host+"'.")
  1382.  
  1383. # read respose
  1384. try:
  1385. response = conn.getresponse()
  1386. responsedata=response.read()
  1387. except:
  1388. raise ADEPTError("Could not read response from '"+host+"'.")
  1389.  
  1390. # close connection
  1391. conn.close()
  1392.  
  1393. try:
  1394. key=re.compile(r'PricipalKey"((?!<key>).)*<key[^>]*>(((?!</key>).)*)</key>', re.I).search(responsedata).group(2)
  1395.  
  1396. except :
  1397. key=None
  1398. return key
  1399.  
  1400. def genkey_adobe_ps(self, param):
  1401. # nice little offline principal keys dictionary
  1402. principalkeys = { 'bibliothek-digital.de': 'Dzqx8McQUNd2CDzBVmtnweUxVWlqJTMqyYtiDIc4dZI='.decode('base64')}
  1403. for k, v in principalkeys.iteritems():
  1404. result = self.getPrincipalKey(k)
  1405. #print result
  1406. if result != None:
  1407. principalkeys[k] = result.decode('base64')
  1408. else:
  1409. raise ADEPTError("No (Online) PrincipalKey found.")
  1410.  
  1411. self.is_printable = self.is_modifiable = self.is_extractable = True
  1412. ## print 'keyvalue'
  1413. ## print len(keyvalue)
  1414. ## print keyvalue.encode('hex')
  1415. length = int_value(param.get('Length', 0)) / 8
  1416. edcdata = str_value(param.get('EDCData')).decode('base64')
  1417. pdrllic = str_value(param.get('PDRLLic')).decode('base64')
  1418. pdrlpol = str_value(param.get('PDRLPol')).decode('base64')
  1419. #print 'ecd rights'
  1420. edclist = []
  1421. for pair in edcdata.split('\n'):
  1422. edclist.append(pair)
  1423. ## print edclist
  1424. ## print 'edcdata decrypted'
  1425. ## print edclist[0].decode('base64').encode('hex')
  1426. ## print edclist[1].decode('base64').encode('hex')
  1427. ## print edclist[2].decode('base64').encode('hex')
  1428. ## print edclist[3].decode('base64').encode('hex')
  1429. ## print 'offlinekey'
  1430. ## print len(edclist[9].decode('base64'))
  1431. ## print pdrllic
  1432. # principal key request
  1433. for key in principalkeys:
  1434. if key in pdrllic:
  1435. principalkey = principalkeys[key]
  1436. else:
  1437. raise ADEPTError('Cannot find principal key for this pdf')
  1438. ## print 'minorversion'
  1439. ## print int(edclist[8])
  1440. # fix for minor version
  1441. ## minorversion = int(edclist[8]) - 100
  1442. ## if minorversion < 1:
  1443. ## minorversion = 1
  1444. ## print int(minorversion)
  1445. shakey = SHA256.new()
  1446. shakey.update(principalkey)
  1447. ## for i in range(0,minorversion):
  1448. ## shakey.update(principalkey)
  1449. shakey = shakey.digest()
  1450. ## shakey = SHA256.new(principalkey).digest()
  1451. ivector = 16 * chr(0)
  1452. #print shakey
  1453. plaintext = AES.new(shakey,AES.MODE_CBC,ivector).decrypt(edclist[9].decode('base64'))
  1454. if plaintext[-16:] != 16 * chr(16):
  1455. raise ADEPTError('Offlinekey cannot be decrypted, aborting (hint: redownload pdf) ...')
  1456. pdrlpol = AES.new(plaintext[16:32],AES.MODE_CBC,edclist[2].decode('base64')).decrypt(pdrlpol)
  1457. if ord(pdrlpol[-1]) < 1 or ord(pdrlpol[-1]) > 16:
  1458. raise ADEPTError('Could not decrypt PDRLPol, aborting ...')
  1459. else:
  1460. cutter = -1 * ord(pdrlpol[-1])
  1461. #print cutter
  1462. pdrlpol = pdrlpol[:cutter]
  1463. #print plaintext.encode('hex')
  1464. #print 'pdrlpol'
  1465. #print pdrlpol
  1466. return plaintext[:16]
  1467.  
  1468. PASSWORD_PADDING = '(\xbfN^Nu\x8aAd\x00NV\xff\xfa\x01\x08..' \
  1469. '\x00\xb6\xd0h>\x80/\x0c\xa9\xfedSiz'
  1470. # experimental aes pw support
  1471. def initialize_standard(self, password, docid, param):
  1472. # copy from a global variable
  1473. V = int_value(param.get('V', 0))
  1474. if (V <=0 or V > 4):
  1475. raise PDFEncryptionError('Unknown algorithm: param=%r' % param)
  1476. length = int_value(param.get('Length', 40)) # Key length (bits)
  1477. O = str_value(param['O'])
  1478. R = int_value(param['R']) # Revision
  1479. if 5 <= R:
  1480. raise PDFEncryptionError('Unknown revision: %r' % R)
  1481. U = str_value(param['U'])
  1482. P = int_value(param['P'])
  1483. try:
  1484. EncMetadata = str_value(param['EncryptMetadata'])
  1485. except:
  1486. EncMetadata = 'True'
  1487. self.is_printable = bool(P & 4)
  1488. self.is_modifiable = bool(P & 8)
  1489. self.is_extractable = bool(P & 16)
  1490. self.is_annotationable = bool(P & 32)
  1491. self.is_formsenabled = bool(P & 256)
  1492. self.is_textextractable = bool(P & 512)
  1493. self.is_assemblable = bool(P & 1024)
  1494. self.is_formprintable = bool(P & 2048)
  1495. # Algorithm 3.2
  1496. password = (password+self.PASSWORD_PADDING)[:32] # 1
  1497. hash = hashlib.md5(password) # 2
  1498. hash.update(O) # 3
  1499. hash.update(struct.pack('<l', P)) # 4
  1500. hash.update(docid[0]) # 5
  1501. # aes special handling if metadata isn't encrypted
  1502. if EncMetadata == ('False' or 'false'):
  1503. hash.update('ffffffff'.decode('hex'))
  1504. # 6
  1505. ## raise PDFNotImplementedError(
  1506. ## 'Revision 4 encryption is currently unsupported')
  1507. if 5 <= R:
  1508. # 8
  1509. for _ in xrange(50):
  1510. hash = hashlib.md5(hash.digest()[:length/8])
  1511. key = hash.digest()[:length/8]
  1512. if R == 2:
  1513. # Algorithm 3.4
  1514. u1 = ARC4.new(key).decrypt(password)
  1515. elif R >= 3:
  1516. # Algorithm 3.5
  1517. hash = hashlib.md5(self.PASSWORD_PADDING) # 2
  1518. hash.update(docid[0]) # 3
  1519. x = ARC4.new(key).decrypt(hash.digest()[:16]) # 4
  1520. for i in xrange(1,19+1):
  1521. k = ''.join( chr(ord(c) ^ i) for c in key )
  1522. x = ARC4.new(k).decrypt(x)
  1523. u1 = x+x # 32bytes total
  1524. if R == 2:
  1525. is_authenticated = (u1 == U)
  1526. else:
  1527. is_authenticated = (u1[:16] == U[:16])
  1528. if not is_authenticated:
  1529. raise ADEPTError('Password is not correct.')
  1530. ## raise PDFPasswordIncorrect
  1531. self.decrypt_key = key
  1532. # genkey method
  1533. if V == 1 or V == 2:
  1534. self.genkey = self.genkey_v2
  1535. elif V == 3:
  1536. self.genkey = self.genkey_v3
  1537. elif V == 4:
  1538. self.genkey = self.genkey_v2
  1539. #self.genkey = self.genkey_v3 if V == 3 else self.genkey_v2
  1540. # rc4
  1541. if V != 4:
  1542. self.decipher = self.decipher_rc4 # XXX may be AES
  1543. # aes
  1544. elif V == 4 and Length == 128:
  1545. elf.decipher = self.decipher_aes
  1546. elif V == 4 and Length == 256:
  1547. raise PDFNotImplementedError('AES256 encryption is currently unsupported')
  1548. self.ready = True
  1549. return
  1550.  
  1551. def initialize_ebx(self, password, docid, param):
  1552. global KEYFILEPATH
  1553. self.is_printable = self.is_modifiable = self.is_extractable = True
  1554. # keyfile path is wrong
  1555. if KEYFILEPATH == False:
  1556. errortext = 'Cannot find adeptkey.der keyfile. Use ineptkey to generate it.'
  1557. raise ADEPTError(errortext)
  1558. with open(password, 'rb') as f:
  1559. keyder = f.read()
  1560. # KEYFILEPATH = ''
  1561. key = ASN1Parser([ord(x) for x in keyder])
  1562. key = [bytesToNumber(key.getChild(x).value) for x in xrange(1, 4)]
  1563. rsa = RSA.construct(key)
  1564. length = int_value(param.get('Length', 0)) / 8
  1565. rights = str_value(param.get('ADEPT_LICENSE')).decode('base64')
  1566. rights = zlib.decompress(rights, -15)
  1567. rights = etree.fromstring(rights)
  1568. expr = './/{http://n...content-available-to-author-only...e.com/adept}encryptedKey'
  1569. bookkey = ''.join(rights.findtext(expr)).decode('base64')
  1570. bookkey = rsa.decrypt(bookkey)
  1571. if bookkey[0] != '\x02':
  1572. raise ADEPTError('error decrypting book session key')
  1573. index = bookkey.index('\0') + 1
  1574. bookkey = bookkey[index:]
  1575. ebx_V = int_value(param.get('V', 4))
  1576. ebx_type = int_value(param.get('EBX_ENCRYPTIONTYPE', 6))
  1577. # added because of the booktype / decryption book session key error
  1578. if ebx_V == 3:
  1579. V = 3
  1580. elif ebx_V < 4 or ebx_type < 6:
  1581. V = ord(bookkey[0])
  1582. bookkey = bookkey[1:]
  1583. else:
  1584. V = 2
  1585. if length and len(bookkey) != length:
  1586. raise ADEPTError('error decrypting book session key')
  1587. self.decrypt_key = bookkey
  1588. self.genkey = self.genkey_v3 if V == 3 else self.genkey_v2
  1589. self.decipher = self.decrypt_rc4
  1590. self.ready = True
  1591. return
  1592.  
  1593. # fileopen support
  1594. def initialize_fopn_flock(self, docid, param):
  1595. raise ADEPTError('FOPN_fLock not supported, yet ...')
  1596. # debug mode processing
  1597. global DEBUG_MODE
  1598. global IVERSION
  1599. if DEBUG_MODE == True:
  1600. if os.access('.',os.W_OK) == True:
  1601. debugfile = open('ineptpdf-'+IVERSION+'-debug.txt','w')
  1602. else:
  1603. raise ADEPTError('Cannot write debug file, current directory is not writable')
  1604. self.is_printable = self.is_modifiable = self.is_extractable = True
  1605. # get parameters and add it to the fo dictionary
  1606. self.fileopen['V'] = int_value(param.get('V',2))
  1607. # crypt base
  1608. (docid, param) = self.encryption
  1609. #rights = dict_value(param['Info'])
  1610. rights = param['Info']
  1611. #print rights
  1612. if DEBUG_MODE == True: debugfile.write(rights + '\n\n')
  1613. ## for pair in rights.split(';'):
  1614. ## try:
  1615. ## key, value = pair.split('=',1)
  1616. ## self.fileopen[key] = value
  1617. ## # fix for some misconfigured INFO variables
  1618. ## except:
  1619. ## pass
  1620. ## kattr = { 'SVID': 'ServiceID', 'DUID': 'DocumentID', 'I3ID': 'Ident3ID', \
  1621. ## 'I4ID': 'Ident4ID', 'VERS': 'EncrVer', 'PRID': 'USR'}
  1622. ## for keys in kattr:
  1623. ## try:
  1624. ## self.fileopen[kattr[keys]] = self.fileopen[keys]
  1625. ## del self.fileopen[keys]
  1626. ## except:
  1627. ## continue
  1628. # differentiate OS types
  1629. ## sysplatform = sys.platform
  1630. ## # if ostype is Windows
  1631. ## if sysplatform=='win32':
  1632. ## self.osuseragent = 'Windows NT 6.0'
  1633. ## self.get_macaddress = self.get_win_macaddress
  1634. ## self.fo_sethwids = self.fo_win_sethwids
  1635. ## self.BrowserCookie = WinBrowserCookie
  1636. ## elif sysplatform=='linux2':
  1637. ## adeptout = 'Linux is not supported, yet.\n'
  1638. ## raise ADEPTError(adeptout)
  1639. ## self.osuseragent = 'Linux i686'
  1640. ## self.get_macaddress = self.get_linux_macaddress
  1641. ## self.fo_sethwids = self.fo_linux_sethwids
  1642. ## else:
  1643. ## adeptout = ''
  1644. ## adeptout = adeptout + 'Due to various privacy violations from Apple\n'
  1645. ## adeptout = adeptout + 'Mac OS X support is disabled by default.'
  1646. ## raise ADEPTError(adeptout)
  1647. ## # add static arguments for http/https request
  1648. ## self.fo_setattributes()
  1649. ## # add hardware specific arguments for http/https request
  1650. ## self.fo_sethwids()
  1651. ##
  1652. ## if 'Code' in self.urlresult:
  1653. ## if self.fileopen['Length'] == len(self.urlresult['Code']):
  1654. ## self.decrypt_key = self.urlresult['Code']
  1655. ## else:
  1656. ## self.decrypt_key = self.urlresult['Code'].decode('hex')
  1657. ## else:
  1658. ## raise ADEPTError('Cannot find decryption key.')
  1659. self.decrypt_key = 'stuff'
  1660. self.genkey = self.genkey_v2
  1661. self.decipher = self.decrypt_rc4
  1662. self.ready = True
  1663. return
  1664.  
  1665. def initialize_fopn(self, docid, param):
  1666. # debug mode processing
  1667. global DEBUG_MODE
  1668. global IVERSION
  1669. if DEBUG_MODE == True:
  1670. if os.access('.',os.W_OK) == True:
  1671. debugfile = open('ineptpdf-'+IVERSION+'-debug.txt','w')
  1672. else:
  1673. raise ADEPTError('Cannot write debug file, current directory is not writable')
  1674. self.is_printable = self.is_modifiable = self.is_extractable = True
  1675. # get parameters and add it to the fo dictionary
  1676. self.fileopen['Length'] = int_value(param.get('Length', 0)) / 8
  1677. self.fileopen['VEID'] = str_value(param.get('VEID'))
  1678. self.fileopen['BUILD'] = str_value(param.get('BUILD'))
  1679. self.fileopen['SVID'] = str_value(param.get('SVID'))
  1680. self.fileopen['DUID'] = str_value(param.get('DUID'))
  1681. self.fileopen['V'] = int_value(param.get('V',2))
  1682. # crypt base
  1683. rights = str_value(param.get('INFO')).decode('base64')
  1684. rights = self.genkey_fileopeninfo(rights)
  1685. if DEBUG_MODE == True: debugfile.write(rights + '\n\n')
  1686. for pair in rights.split(';'):
  1687. try:
  1688. key, value = pair.split('=',1)
  1689. self.fileopen[key] = value
  1690. # fix for some misconfigured INFO variables
  1691. except:
  1692. pass
  1693. kattr = { 'SVID': 'ServiceID', 'DUID': 'DocumentID', 'I3ID': 'Ident3ID', \
  1694. 'I4ID': 'Ident4ID', 'VERS': 'EncrVer', 'PRID': 'USR'}
  1695. for keys in kattr:
  1696. # fishing some misconfigured slashs out of it
  1697. try:
  1698. self.fileopen[kattr[keys]] = urllib.quote(self.fileopen[keys],safe='')
  1699. del self.fileopen[keys]
  1700. except:
  1701. continue
  1702. # differentiate OS types
  1703. sysplatform = sys.platform
  1704. # if ostype is Windows
  1705. if sysplatform=='win32':
  1706. self.osuseragent = 'Windows NT 6.0'
  1707. self.get_macaddress = self.get_win_macaddress
  1708. self.fo_sethwids = self.fo_win_sethwids
  1709. self.BrowserCookie = WinBrowserCookie
  1710. elif sysplatform=='linux2' or sysplatform=='linux3':
  1711. import fcntl
  1712. import struct
  1713. self.osuseragent = 'Linux i686'
  1714. self.get_macaddress = self.get_linux_macaddress
  1715. self.fo_sethwids = self.fo_linux_sethwids
  1716. self.BrowserCookie = LinBrowserCookie
  1717. else:
  1718. adeptout = ''
  1719. adeptout = adeptout + 'Mac OS X is not supported, yet.'
  1720. adeptout = adeptout + 'Read the blogs FAQs for more information'
  1721. raise ADEPTError(adeptout)
  1722. # add static arguments for http/https request
  1723. self.fo_setattributes()
  1724. # add hardware specific arguments for http/https request
  1725. self.fo_sethwids()
  1726. #if DEBUG_MODE == True: debugfile.write(self.fileopen)
  1727. if 'UURL' in self.fileopen:
  1728. buildurl = self.fileopen['UURL']
  1729. else:
  1730. buildurl = self.fileopen['PURL']
  1731. # fix for bad DPRM structure
  1732. if self.fileopen['DPRM'][0] != r'/':
  1733. self.fileopen['DPRM'] = r'/' + self.fileopen['DPRM']
  1734. # genius fix for bad server urls (IMHO)
  1735. if '?' in self.fileopen['DPRM']:
  1736. buildurl = buildurl + self.fileopen['DPRM'] + '&'
  1737. else:
  1738. buildurl = buildurl + self.fileopen['DPRM'] + '?'
  1739.  
  1740. # debug customization
  1741. #self.fileopen['Machine'] = ''
  1742. #self.fileopen['Disk'] = ''
  1743.  
  1744.  
  1745. surl = ( 'Stamp', 'Mode', 'USR', 'ServiceID', 'DocumentID',\
  1746. 'Ident3ID', 'Ident4ID','DocStrFmt', 'OSType', 'OSName', 'OSData', 'Language',\
  1747. 'LngLCID', 'LngRFC1766', 'LngISO4Char', 'Build', 'ProdVer', 'EncrVer',\
  1748. 'Machine', 'Disk', 'Uuid', 'PrevMach', 'PrevDisk',\
  1749. 'FormHFT',\
  1750. 'SelServer', 'AcroVersion', 'AcroProduct', 'AcroReader',\
  1751. 'AcroCanEdit', 'AcroPrefIDib', 'InBrowser', 'CliAppName',\
  1752. 'DocIsLocal', 'DocPathUrl', 'VolName', 'VolType', 'VolSN',\
  1753. 'FSName', 'FowpKbd', 'OSBuild',\
  1754. 'RequestSchema')
  1755.  
  1756. #settings request and special modes
  1757. if 'EVER' in self.fileopen and float(self.fileopen['EVER']) < 3.8:
  1758. self.fileopen['Mode'] = 'ICx'
  1759.  
  1760. origurl = buildurl
  1761. buildurl = buildurl + 'Request=Setting'
  1762. for keys in surl:
  1763. try:
  1764. buildurl = buildurl + '&' + keys + '=' + self.fileopen[keys]
  1765. except:
  1766. continue
  1767. if DEBUG_MODE == True: debugfile.write( 'settings url:\n')
  1768. if DEBUG_MODE == True: debugfile.write( buildurl+'\n\n')
  1769. # custom user agent identification?
  1770. if 'AGEN' in self.fileopen:
  1771. useragent = self.fileopen['AGEN']
  1772. urllib.URLopener.version = useragent
  1773. # attribute doesn't exist - take the default user agent
  1774. else:
  1775. urllib.URLopener.version = self.osuseragent
  1776. # try to open the url
  1777. try:
  1778. u = urllib.urlopen(buildurl)
  1779. u.geturl()
  1780. result = u.read()
  1781. except:
  1782. raise ADEPTError('No internet connection or a blocking firewall!')
  1783. ## finally:
  1784. ## u.close()
  1785. # getting rid of the line feed
  1786. if DEBUG_MODE == True: debugfile.write('Settings'+'\n')
  1787. if DEBUG_MODE == True: debugfile.write(result+'\n\n')
  1788. #get rid of unnecessary characters
  1789. result = result.rstrip('\n')
  1790. result = result.rstrip(chr(13))
  1791. result = result.lstrip('\n')
  1792. result = result.lstrip(chr(13))
  1793. self.surlresult = {}
  1794. for pair in result.split('&'):
  1795. try:
  1796. key, value = pair.split('=',1)
  1797. # fix for bad server response
  1798. if key not in self.surlresult:
  1799. self.surlresult[key] = value
  1800. except:
  1801. pass
  1802. if 'RequestSchema' in self.surlresult:
  1803. self.fileopen['RequestSchema'] = self.surlresult['RequestSchema']
  1804. if 'ServerSessionData' in self.surlresult:
  1805. self.fileopen['ServerSessionData'] = self.surlresult['ServerSessionData']
  1806. if 'SetScope' in self.surlresult:
  1807. self.fileopen['RequestSchema'] = self.surlresult['SetScope']
  1808. #print self.surlresult
  1809. if 'RetVal' in self.surlresult and 'SEMO' not in self.fileopen and(('Reason' in self.surlresult and \
  1810. self.surlresult['Reason'] == 'AskUnp') or ('SetTarget' in self.surlresult and\
  1811. self.surlresult['SetTarget'] == 'UnpDlg')):
  1812. # get user and password dialog
  1813. try:
  1814. self.gen_pw_dialog(self.surlresult['UnpUiName'], self.surlresult['UnpUiPass'],\
  1815. self.surlresult['UnpUiTitle'], self.surlresult['UnpUiOk'],\
  1816. self.surlresult['UnpUiSunk'], self.surlresult['UnpUiComm'])
  1817. except:
  1818. self.gen_pw_dialog()
  1819.  
  1820. # the fileopen check might not be always right because of strange server responses
  1821. if 'SEMO' in self.fileopen and (self.fileopen['SEMO'] == '1'\
  1822. or self.fileopen['SEMO'] == '2') and ('CSES' in self.fileopen and\
  1823. self.fileopen['CSES'] != 'fileopen'):
  1824. # get the url name for the cookie(s)
  1825. if 'CURL' in self.fileopen:
  1826. self.surl = self.fileopen['CURL']
  1827. if 'CSES' in self.fileopen:
  1828. self.cses = self.fileopen['CSES']
  1829. elif 'PHOS' in self.fileopen:
  1830. self.surl = self.fileopen['PHOS']
  1831. elif 'LHOS' in self.fileopen:
  1832. self.surl = self.fileopen['LHOS']
  1833. else:
  1834. raise ADEPTError('unknown Cookie name.\n Check ineptpdf forum for further assistance')
  1835. self.pwfieldreq = 1
  1836. # session cookie processing
  1837. if self.fileopen['SEMO'] == '1':
  1838. cookies = self.BrowserCookie()
  1839. #print self.cses
  1840. #print self.surl
  1841.  
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:1:2: error: invalid preprocessing directive #!
 #! /usr/bin/python
  ^
prog.cpp:3:3: error: invalid preprocessing directive #ineptpdf8
 # ineptpdf8.4.52.pyw
   ^
prog.cpp:4:3: error: invalid preprocessing directive #ineptpdf
 # ineptpdf, version 8.4.52
   ^
prog.cpp:6:3: error: invalid preprocessing directive #To
 # To run this program install Python 2.7 from http://w...content-available-to-author-only...n.org/download/ 
   ^
prog.cpp:8:3: error: invalid preprocessing directive #PyCrypto
 # PyCrypto from http://w...content-available-to-author-only...g.uk/python/modules.shtml#pycrypto
   ^
prog.cpp:10:3: error: invalid preprocessing directive #and
 # and PyWin Extension (Win32API module) from
   ^
prog.cpp:11:3: error: invalid preprocessing directive #http
 # http://s...content-available-to-author-only...e.net/projects/pywin32/files/
   ^
prog.cpp:13:3: error: invalid preprocessing directive #Make
 # Make sure to install the dedicated versions for Python 2.7.
   ^
prog.cpp:15:3: error: invalid preprocessing directive #It
 # It's recommended to use the 32-Bit Python Windows versions (even with a 64-bit
   ^
prog.cpp:15:5: warning: missing terminating ' character
 # It's recommended to use the 32-Bit Python Windows versions (even with a 64-bit
     ^
prog.cpp:16:3: error: invalid preprocessing directive #Windows
 # Windows system).
   ^
prog.cpp:18:3: error: invalid preprocessing directive #Save
 # Save this script file as
   ^
prog.cpp:19:3: error: invalid preprocessing directive #ineptpdf8
 # ineptpdf8.4.52.pyw and double-click on it to run it.
   ^
prog.cpp:21:3: error: invalid preprocessing directive #Revision
 # Revision history:
   ^
prog.cpp:22:7: error: "-" is not a valid filename
 #   1 - Initial release
       ^
prog.cpp:23:7: error: "-" is not a valid filename
 #   2 - Improved determination of key-generation algorithm
       ^
prog.cpp:24:7: error: "-" is not a valid filename
 #   3 - Correctly handle PDF >=1.5 cross-reference streams
       ^
prog.cpp:25:7: error: "-" is not a valid filename
 #   4 - Removal of ciando's personal ID (anon)
       ^
prog.cpp:25:26: warning: missing terminating ' character
 #   4 - Removal of ciando's personal ID (anon)
                          ^
prog.cpp:26:7: error: "-" is not a valid filename
 #   5 - removing small bug with V3 ebooks (anon)
       ^
prog.cpp:27:7: error: "-" is not a valid filename
 #   6 - changed to adeptkey4.der format for 1.7.2 support (anon)
       ^
prog.cpp:28:5: error: "6.1" after # is not a positive integer
 #   6.1 - backward compatibility for 1.7.1 and old adeptkey.der (anon)
     ^
prog.cpp:29:7: error: "-" is not a valid filename
 #   7 - Get cross reference streams and object streams working for input.
       ^
prog.cpp:30:9: error: invalid preprocessing directive #Not
 #       Not yet supported on output but this only effects file size,
         ^
prog.cpp:31:9: error: invalid preprocessing directive #not
 #       not functionality. (anon2)
         ^
prog.cpp:32:5: error: "7.1" after # is not a positive integer
 #   7.1 - Correct a problem when an old trailer is not followed by startxref (anon2)
     ^
prog.cpp:33:5: error: "7.2" after # is not a positive integer
 #   7.2 - Correct malformed Mac OS resource forks for Stanza
     ^
prog.cpp:34:9: error: invalid preprocessing directive #-
 #       - Support for cross ref streams on output (decreases file size) (anon2)
         ^
prog.cpp:35:5: error: "7.3" after # is not a positive integer
 #   7.3 - Correct bug in trailer with cross ref stream that caused the error (anon2)
     ^
prog.cpp:36:11: error: invalid preprocessing directive #"The root object is missing or invalid"
 #         "The root object is missing or invalid" in Adobe Reader.
           ^
prog.cpp:37:5: error: "7.4" after # is not a positive integer
 #   7.4 - Force all generation numbers in output file to be 0, like in v6.
     ^
prog.cpp:38:11: error: invalid preprocessing directive #Fallback
 #         Fallback code for wrong xref improved (search till last trailer
           ^
prog.cpp:39:11: error: invalid preprocessing directive #instead
 #         instead of first) (anon2)
           ^
prog.cpp:40:7: error: "-" is not a valid filename
 #   8 - fileopen user machine identifier support (Tetrachroma)
       ^
prog.cpp:41:5: error: "8.1" after # is not a positive integer
 #   8.1 - fileopen user cookies support (Tetrachroma)
     ^
prog.cpp:42:5: error: "8.2" after # is not a positive integer
 #   8.2 - fileopen user name/password support (Tetrachroma)
     ^
prog.cpp:43:5: error: "8.3" after # is not a positive integer
 #   8.3 - fileopen session cookie support (Tetrachroma)
     ^
prog.cpp:44:5: error: "8.3.1" after # is not a positive integer
 #   8.3.1 - fix for the "specified key file does not exist" error (Tetrachroma)
     ^
prog.cpp:45:5: error: "8.3.2" after # is not a positive integer
 #   8.3.2 - improved server result parsing (Tetrachroma)
     ^
prog.cpp:46:5: error: "8.4" after # is not a positive integer
 #   8.4 - Ident4D and encrypted Uuid support (Tetrachroma)
     ^
prog.cpp:47:5: error: "8.4.1" after # is not a positive integer
 #   8.4.1 - improved MAC address processing (Tetrachroma)
     ^
prog.cpp:48:5: error: "8.4.2" after # is not a positive integer
 #   8.4.2 - FowP3Uuid fallback file processing (Tetrachroma)
     ^
prog.cpp:49:5: error: "8.4.3" after # is not a positive integer
 #   8.4.3 - improved user/password pdf file detection (Tetrachroma)
     ^
prog.cpp:50:5: error: "8.4.4" after # is not a positive integer
 #   8.4.4 - small bugfix (Tetrachroma)
     ^
prog.cpp:51:5: error: "8.4.5" after # is not a positive integer
 #   8.4.5 - improved cookie host searching (Tetrachroma)
     ^
prog.cpp:52:5: error: "8.4.6" after # is not a positive integer
 #   8.4.6 - STRICT parsing disabled (non-standard pdf processing) (Tetrachroma)
     ^
prog.cpp:53:5: error: "8.4.7" after # is not a positive integer
 #   8.4.7 - UTF-8 input file conversion (Tetrachroma)
     ^
prog.cpp:54:5: error: "8.4.8" after # is not a positive integer
 #   8.4.8 - fix for more rare utf8 problems (Tetrachroma)
     ^
prog.cpp:55:5: error: "8.4.9" after # is not a positive integer
 #   8.4.9 - solution for utf8 in comination with
     ^
prog.cpp:56:13: error: invalid preprocessing directive #ident4id
 #           ident4id method (Tetrachroma)
             ^
prog.cpp:57:5: error: "8.4.10" after # is not a positive integer
 #   8.4.10 - line feed processing, non c system drive patch, nrbook support (Tetrachroma)
     ^
prog.cpp:58:5: error: "8.4.11" after # is not a positive integer
 #   8.4.11 - alternative ident4id calculation (Tetrachroma)
     ^
prog.cpp:59:5: error: "8.4.12" after # is not a positive integer
 #   8.4.12 - fix for capital username characters and
     ^
prog.cpp:60:14: error: invalid preprocessing directive #other
 #            other unusual user login names (Tetrachroma & ZeroPoint)
              ^
prog.cpp:61:5: error: "8.4.13" after # is not a positive integer
 #   8.4.13 - small bug fixes (Tetrachroma)
     ^
prog.cpp:62:5: error: "8.4.14" after # is not a positive integer
 #   8.4.14 - fix for non-standard-conform fileopen pdfs (Tetrachroma)
     ^
prog.cpp:63:5: error: "8.4.15" after # is not a positive integer
 #   8.4.15 - 'bad file descriptor'-fix (Tetrachroma)
     ^
prog.cpp:64:5: error: "8.4.16" after # is not a positive integer
 #   8.4.16 - improves user/pass detection (Tetrachroma)
     ^
prog.cpp:65:5: error: "8.4.17" after # is not a positive integer
 #   8.4.17 - fix for several '=' chars in a DPRM entity (Tetrachroma)
     ^
prog.cpp:66:5: error: "8.4.18" after # is not a positive integer
 #   8.4.18 - follow up bug fix for the DPRM problem,
     ^
prog.cpp:67:14: error: invalid preprocessing directive #more
 #            more readable error messages (Tetrachroma)
              ^
prog.cpp:68:5: error: "8.4.19" after # is not a positive integer
 #   8.4.19 - 2nd fix for 'bad file descriptor' problem (Tetrachroma)
     ^
prog.cpp:69:5: error: "8.4.20" after # is not a positive integer
 #   8.4.20 - follow up patch (Tetrachroma)
     ^
prog.cpp:70:5: error: "8.4.21" after # is not a positive integer
 #   8.4.21 - 3rd patch for 'bad file descriptor' (Tetrachroma)
     ^
prog.cpp:71:5: error: "8.4.22" after # is not a positive integer
 #   8.4.22 - disable prints for exception prevention (Tetrachroma)
     ^
prog.cpp:72:5: error: "8.4.23" after # is not a positive integer
 #   8.4.23 - check for additional security attributes (Tetrachroma)
     ^
prog.cpp:73:5: error: "8.4.24" after # is not a positive integer
 #   8.4.24 - improved cookie session support (Tetrachroma)
     ^
prog.cpp:74:5: error: "8.4.25" after # is not a positive integer
 #   8.4.25 - more compatibility with unicode files (Tetrachroma)
     ^
prog.cpp:75:5: error: "8.4.26" after # is not a positive integer
 #   8.4.26 - automated session/user cookie request function (works
     ^
prog.cpp:76:14: error: invalid preprocessing directive #only
 #            only with Firefox 3.x+) (Tetrachroma)
              ^
prog.cpp:77:5: error: "8.4.27" after # is not a positive integer
 #   8.4.27 - user/password fallback
     ^
prog.cpp:78:5: error: "8.4.28" after # is not a positive integer
 #   8.4.28 - AES decryption, improved misconfigured pdf handling,
     ^
prog.cpp:79:14: error: invalid preprocessing directive #limited
 #            limited experimental APS support (Tetrachroma & Neisklar)
              ^
prog.cpp:80:5: error: "8.4.29" after # is not a positive integer
 #   8.4.29 - backport for bad formatted rc4 encrypted pdfs (Tetrachroma)
     ^
prog.cpp:81:5: error: "8.4.30" after # is not a positive integer
 #   8.4.30 - extended authorization attributes support (Tetrachroma)
     ^
prog.cpp:82:5: error: "8.4.31" after # is not a positive integer
 #   8.4.31 - improved session cookie and better server response error
     ^
prog.cpp:83:14: error: invalid preprocessing directive #handling
 #            handling (Tetrachroma)
              ^
prog.cpp:84:5: error: "8.4.33" after # is not a positive integer
 #   8.4.33 - small cookie optimizations (Tetrachroma)
     ^
prog.cpp:85:5: error: "8.4.33" after # is not a positive integer
 #   8.4.33 - debug output option (Tetrachroma)
     ^
prog.cpp:86:5: error: "8.4.34" after # is not a positive integer
 #   8.4.34 - better user/password management
     ^
prog.cpp:87:14: error: invalid preprocessing directive #handles
 #            handles the 'AskUnp' response) (Tetrachroma)
              ^
prog.cpp:88:5: error: "8.4.35" after # is not a positive integer
 #   8.4.35 - special handling for non-standard systems (Tetrachroma)
     ^
prog.cpp:89:5: error: "8.4.36" after # is not a positive integer
 #   8.4.36 - previous machine/disk handling [PrevMach/PrevDisk] (Tetrachroma)
     ^
prog.cpp:90:5: error: "8.4.36" after # is not a positive integer
 #   8.4.36 - FOPN_flock support (Tetrachroma)
     ^
prog.cpp:91:5: error: "8.4.37" after # is not a positive integer
 #   8.4.37 - patch for unicode paths/filenames (Tetrachroma)
     ^
prog.cpp:92:5: error: "8.4.38" after # is not a positive integer
 #   8.4.38 - small fix for user/password dialog (Tetrachroma)
     ^
prog.cpp:93:5: error: "8.4.39" after # is not a positive integer
 #   8.4.39 - sophisticated request mode differentiation, forced
     ^
prog.cpp:94:14: error: invalid preprocessing directive #uuid
 #            uuid calculation (Tetrachroma)
              ^
prog.cpp:95:5: error: "8.4.40" after # is not a positive integer
 #   8.4.40 - fix for non standard server responses (Tetrachroma)
     ^
prog.cpp:96:5: error: "8.4.41" after # is not a positive integer
 #   8.4.41 - improved user/password request windows,
     ^
prog.cpp:97:14: error: invalid preprocessing directive #better
 #            better server response tolerance (Tetrachroma)
              ^
prog.cpp:98:5: error: "8.4.42" after # is not a positive integer
 #   8.4.42 - improved nl/cr server response parsing (Tetrachroma)
     ^
prog.cpp:99:5: error: "8.4.43" after # is not a positive integer
 #   8.4.43 - fix for user names longer than 13 characters and special
     ^
prog.cpp:100:14: error: invalid preprocessing directive #uuid
 #            uuid encryption (Tetrachroma)
              ^
prog.cpp:101:5: error: "8.4.44" after # is not a positive integer
 #   8.4.44 - another fix for ident4d problem (Tetrachroma)
     ^
prog.cpp:102:5: error: "8.4.45" after # is not a positive integer
 #   8.4.45 - 2nd fix for ident4d problem (Tetrachroma)
     ^
prog.cpp:103:5: error: "8.4.46" after # is not a positive integer
 #   8.4.46 - script cleanup and optimizations (Tetrachroma)
     ^
prog.cpp:104:5: error: "8.4.47" after # is not a positive integer
 #   8.4.47 - script identification change to Adobe Reader (Tetrachroma)
     ^
prog.cpp:105:5: error: "8.4.48" after # is not a positive integer
 #   8.4.48 - improved tolerance for false file/registry entries (Tetrachroma)
     ^
prog.cpp:106:5: error: "8.4.49" after # is not a positive integer
 #   8.4.49 - improved username encryption (Tetrachroma)
     ^
prog.cpp:107:5: error: "8.4.50" after # is not a positive integer
 #   8.4.50 - improved (experimental) APS support (Tetrachroma & Neisklar)
     ^
prog.cpp:108:5: error: "8.4.51" after # is not a positive integer
 #   8.4.51 - automatic APS offline key retrieval (works only for
     ^
prog.cpp:109:14: error: invalid preprocessing directive #Onleihe
 #            Onleihe right now) (80ka80 & Tetrachroma)
              ^
prog.cpp:110:5: error: "8.4.52" after # is not a positive integer
 #   8.4.52 - fixed linux support (mazdac) - gets mac from eth0, if doesn't work change hardcodedinterface
     ^
prog.cpp:110:73: warning: missing terminating ' character
 #   8.4.52 - fixed linux support (mazdac) - gets mac from eth0, if doesn't work change hardcodedinterface
                                                                         ^
prog.cpp:112:3: warning: missing terminating " character
 """
   ^
prog.cpp:112:1: error: missing terminating " character
 """
 ^
prog.cpp:114:3: warning: missing terminating " character
 """
   ^
prog.cpp:114:1: error: missing terminating " character
 """
 ^
prog.cpp:118:15: warning: character constant too long for its type
 __license__ = 'GPL v3'
               ^
prog.cpp:132:3: error: invalid preprocessing directive #added
 # added for fileopen support
   ^
prog.cpp:150:7: error: invalid preprocessing directive #needed
     # needed for newer pdfs
       ^
prog.cpp:166:3: error: invalid preprocessing directive #global
 # global variable (needed for fileopen and password decryption)
   ^
prog.cpp:167:17: error: empty character constant
 INPUTFILEPATH = ''
                 ^
prog.cpp:168:15: error: empty character constant
 KEYFILEPATH = ''
               ^
prog.cpp:169:12: error: empty character constant
 PASSWORD = ''
            ^
prog.cpp:171:12: warning: character constant too long for its type
 IVERSION = '8.4.52'
            ^
prog.cpp:172:13: warning: multi-character character constant [-Wmultichar]
 INTERFACE = 'eth0'
             ^
prog.cpp:174:3: error: invalid preprocessing directive #Do
 # Do we generate cross reference streams on output?
   ^
prog.cpp:175:5: error: "=" is not a valid filename
 # 0 = never
     ^
prog.cpp:176:5: error: "=" is not a valid filename
 # 1 = only if present in input
     ^
prog.cpp:177:5: error: "=" is not a valid filename
 # 2 = always
     ^
prog.cpp:181:3: error: invalid preprocessing directive #This
 # This is the value for the current document
   ^
prog.cpp:182:22: error: stray '#' in program
 gen_xref_stm = False # will be set in PDFSerializer
                      ^
prog.cpp:184:1: error: stray '##' in program
 ### 
 ^
prog.cpp:184:3: error: stray '#' in program
 ### 
   ^
prog.cpp:185:1: error: stray '##' in program
 ### ASN.1 parsing code from tlslite
 ^
prog.cpp:185:3: error: stray '#' in program
 ### ASN.1 parsing code from tlslite
   ^
prog.cpp:280:1: error: stray '##' in program
 ###
 ^
prog.cpp:280:3: error: stray '#' in program
 ###
   ^
prog.cpp:281:1: error: stray '##' in program
 ### PDF parsing routines from pdfminer, with changes for EBX_HANDLER
 ^
prog.cpp:281:3: error: stray '#' in program
 ### PDF parsing routines from pdfminer, with changes for EBX_HANDLER
   ^
prog.cpp:283:1: error: stray '##' in program
 ##  Utilities
 ^
prog.cpp:284:1: error: stray '##' in program
 ##
 ^
prog.cpp:286:5: error: empty character constant
     '''Groups every n elements of the list.'''
     ^
prog.cpp:286:7: warning: character constant too long for its type
     '''Groups every n elements of the list.'''
       ^
prog.cpp:286:45: error: empty character constant
     '''Groups every n elements of the list.'''
                                             ^
prog.cpp:296:5: error: empty character constant
     '''Unpacks up to 4 bytes big endian.'''
     ^
prog.cpp:296:7: warning: character constant too long for its type
     '''Unpacks up to 4 bytes big endian.'''
       ^
prog.cpp:296:42: error: empty character constant
     '''Unpacks up to 4 bytes big endian.'''
                                          ^
prog.cpp:303:30: warning: multi-character character constant [-Wmultichar]
         return struct.unpack('>H', s)[0]
                              ^
prog.cpp:305:30: warning: multi-character character constant [-Wmultichar]
         return struct.unpack('>L', '\x00'+s)[0]
                              ^
prog.cpp:307:30: warning: multi-character character constant [-Wmultichar]
         return struct.unpack('>L', s)[0]
                              ^
prog.cpp:309:26: warning: character constant too long for its type
         return TypeError('invalid length: %d' % l)
                          ^
prog.cpp:315:1: error: stray '##' in program
 ##  PS Exceptions
 ^
prog.cpp:316:1: error: stray '##' in program
 ##
 ^
prog.cpp:324:1: error: stray '##' in program
 ##  Basic PostScript Types
 ^
prog.cpp:325:1: error: stray '##' in program
 ##
 ^
prog.cpp:327:3: error: invalid preprocessing directive #PSLiteral
 # PSLiteral
   ^
prog.cpp:331:5: error: empty character constant
     '''
     ^
prog.cpp:331:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:331:5: error: missing terminating ' character
     '''
     ^
prog.cpp:335:5: error: empty character constant
     '''
     ^
prog.cpp:335:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:335:5: error: missing terminating ' character
     '''
     ^
prog.cpp:344:24: warning: character constant too long for its type
                 char = '#%02x' % ord(char)
                        ^
prog.cpp:346:16: warning: multi-character character constant [-Wmultichar]
         return '/%s' % ''.join(name)
                ^
prog.cpp:346:24: error: empty character constant
         return '/%s' % ''.join(name)
                        ^
prog.cpp:348:3: error: invalid preprocessing directive #PSKeyword
 # PSKeyword
   ^
prog.cpp:350:5: error: empty character constant
     '''
     ^
prog.cpp:350:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:350:5: error: missing terminating ' character
     '''
     ^
prog.cpp:354:5: error: empty character constant
     '''
     ^
prog.cpp:354:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:354:5: error: missing terminating ' character
     '''
     ^
prog.cpp:362:3: error: invalid preprocessing directive #PSSymbolTable
 # PSSymbolTable
   ^
prog.cpp:365:5: error: empty character constant
     '''
     ^
prog.cpp:365:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:365:5: error: missing terminating ' character
     '''
     ^
prog.cpp:367:5: error: empty character constant
     '''
     ^
prog.cpp:367:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:367:5: error: missing terminating ' character
     '''
     ^
prog.cpp:390:26: warning: multi-character character constant [-Wmultichar]
 KEYWORD_DICT_BEGIN = KWD('<<')
                          ^
prog.cpp:391:24: warning: multi-character character constant [-Wmultichar]
 KEYWORD_DICT_END = KWD('>>')
                        ^
prog.cpp:397:31: warning: character constant too long for its type
             raise PSTypeError('Literal required: %r' % x)
                               ^
prog.cpp:405:31: warning: character constant too long for its type
             raise PSTypeError('Keyword required: %r' % x)
                               ^
prog.cpp:411:1: error: stray '##' in program
 ##  PSBaseParser
 ^
prog.cpp:412:1: error: stray '##' in program
 ##
 ^
prog.cpp:413:19: warning: multi-character character constant [-Wmultichar]
 EOL = re.compile(r'[\r\n]')
                   ^
prog.cpp:414:19: warning: unknown escape sequence: '\s'
 SPC = re.compile(r'\s')
                   ^
prog.cpp:415:22: warning: unknown escape sequence: '\S'
 NONSPC = re.compile(r'\S')
                      ^
prog.cpp:416:19: warning: character constant too long for its type
 HEX = re.compile(r'[0-9a-fA-F]')
                   ^
prog.cpp:417:27: warning: unknown escape sequence: '\]'
 END_LITERAL = re.compile(r'[#/%\[\]()<>{}\s]')
                           ^
prog.cpp:417:27: warning: unknown escape sequence: '\s'
prog.cpp:417:27: warning: character constant too long for its type
prog.cpp:418:30: warning: unknown escape sequence: '\s'
 END_HEX_STRING = re.compile(r'[^\s0-9a-fA-F]')
                              ^
prog.cpp:418:30: warning: character constant too long for its type
prog.cpp:419:24: warning: character constant too long for its type
 HEX_PAIR = re.compile(r'[0-9a-fA-F]{2}|.')
                        ^
prog.cpp:420:26: warning: character constant too long for its type
 END_NUMBER = re.compile(r'[^0-9]')
                          ^
prog.cpp:421:27: warning: unknown escape sequence: '\]'
 END_KEYWORD = re.compile(r'[#/%\[\]()<>{}\s]')
                           ^
prog.cpp:421:27: warning: unknown escape sequence: '\s'
prog.cpp:421:27: warning: character constant too long for its type
prog.cpp:422:26: warning: character constant too long for its type
 END_STRING = re.compile(r'[()\134]')
                          ^
prog.cpp:423:26: warning: character constant too long for its type
 OCT_STRING = re.compile(r'[0-7]')
                          ^
prog.cpp:428:5: error: empty character constant
     '''
     ^
prog.cpp:428:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:428:5: error: missing terminating ' character
     '''
     ^
prog.cpp:430:5: error: empty character constant
     '''
     ^
prog.cpp:430:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:430:5: error: missing terminating ' character
     '''
     ^
prog.cpp:439:16: warning: character constant too long for its type
         return '<PSBaseParser: %r, bufpos=%d>' % (self.fp, self.bufpos)
                ^
prog.cpp:456:9: error: stray '##' in program
         ##print >>sys.stderr, 'poll(%d): %r' % (pos, self.fp.read(n))
         ^
prog.cpp:456:31: warning: character constant too long for its type
         ##print >>sys.stderr, 'poll(%d): %r' % (pos, self.fp.read(n))
                               ^
prog.cpp:461:9: error: empty character constant
         '''
         ^
prog.cpp:461:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:461:9: error: missing terminating ' character
         '''
         ^
prog.cpp:463:9: error: empty character constant
         '''
         ^
prog.cpp:463:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:463:9: error: missing terminating ' character
         '''
         ^
prog.cpp:465:11: error: invalid preprocessing directive #reset
         # reset the status for nextline()
           ^
prog.cpp:467:20: error: empty character constant
         self.buf = ''
                    ^
prog.cpp:469:11: error: invalid preprocessing directive #reset
         # reset the status for nexttoken()
           ^
prog.cpp:476:11: error: invalid preprocessing directive #fetch
         # fetch next chunk.
           ^
prog.cpp:480:25: warning: character constant too long for its type
             raise PSEOF('Unexpected EOF')
                         ^
prog.cpp:495:26: error: empty character constant
             self.token = ''
                          ^
prog.cpp:497:17: warning: multi-character character constant [-Wmultichar]
         if c in '-+' or c.isdigit():
                 ^
prog.cpp:507:26: error: empty character constant
             self.token = ''
                          ^
prog.cpp:511:26: error: empty character constant
             self.token = ''
                          ^
prog.cpp:514:26: error: empty character constant
             self.token = ''
                          ^
prog.cpp:530:11: error: invalid preprocessing directive #We
         # We ignore comments.
           ^
prog.cpp:531:10: error: invalid preprocessing directive #self
         #self.tokens.append(self.token)
          ^
prog.cpp:543:24: error: empty character constant
             self.hex = ''
                        ^
prog.cpp:590:26: warning: multi-character character constant [-Wmultichar]
         if self.token == 'true':
                          ^
prog.cpp:592:28: warning: character constant too long for its type
         elif self.token == 'false':
                            ^
prog.cpp:608:24: error: empty character constant
             self.oct = ''
                        ^
prog.cpp:657:58: error: empty character constant
                                                  SPC.sub('', self.token))
                                                          ^
prog.cpp:669:9: error: empty character constant
         '''
         ^
prog.cpp:669:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:669:9: error: missing terminating ' character
         '''
         ^
prog.cpp:670:9: error: stray '\' in program
         Fetches a next line that ends either with \\r or \\n.
         ^
prog.cpp:670:9: error: stray '\' in program
prog.cpp:670:9: error: stray '\' in program
prog.cpp:670:9: error: stray '\' in program
prog.cpp:671:9: error: empty character constant
         '''
         ^
prog.cpp:671:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:671:9: error: missing terminating ' character
         '''
         ^
prog.cpp:672:19: error: empty character constant
         linebuf = ''
                   ^
prog.cpp:679:19: error: invalid preprocessing directive #handle
                 # handle '\r\n'
                   ^
prog.cpp:698:9: error: empty character constant
         '''
         ^
prog.cpp:698:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:698:9: error: missing terminating ' character
         '''
         ^
prog.cpp:701:9: error: empty character constant
         '''
         ^
prog.cpp:701:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:701:9: error: missing terminating ' character
         '''
         ^
prog.cpp:704:15: error: empty character constant
         buf = ''
               ^
prog.cpp:718:23: error: empty character constant
                 buf = ''
                       ^
prog.cpp:722:1: error: stray '##' in program
 ##  PSStackParser
 ^
prog.cpp:723:1: error: stray '##' in program
 ##
 ^
prog.cpp:764:31: warning: character constant too long for its type
             raise PSTypeError('Type mismatch: %r != %r' % (self.curtype, type))
                               ^
prog.cpp:773:9: error: empty character constant
         '''
         ^
prog.cpp:773:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:773:9: error: missing terminating ' character
         '''
         ^
prog.cpp:777:9: error: empty character constant
         '''
         ^
prog.cpp:777:11: warning: missing terminating ' character
         '''
           ^
prog.cpp:777:9: error: missing terminating ' character
         '''
         ^
prog.cpp:780:13: error: stray '##' in program
             ##print (pos,token), (self.curtype, self.curstack)
             ^
prog.cpp:786:19: error: invalid preprocessing directive #normal
                 # normal token
                   ^
prog.cpp:789:19: error: invalid preprocessing directive #begin
                 # begin array
                   ^
prog.cpp:792:19: error: invalid preprocessing directive #end
                 # end array
                   ^
prog.cpp:798:19: error: invalid preprocessing directive #begin
                 # begin dictionary
                   ^
prog.cpp:801:19: error: invalid preprocessing directive #end
                 # end dictionary
                   ^
prog.cpp:806:29: warning: character constant too long for its type
                             'Invalid dictionary construct: %r' % objs)
                             ^
prog.cpp:824:39: warning: character constant too long for its type
 LITERAL_CRYPT = PSLiteralTable.intern('Crypt')
                                       ^
prog.cpp:825:48: warning: character constant too long for its type
 LITERALS_FLATE_DECODE = (PSLiteralTable.intern('FlateDecode'), PSLiteralTable.intern('Fl'))
                                                ^
prog.cpp:825:86: warning: multi-character character constant [-Wmultichar]
 LITERALS_FLATE_DECODE = (PSLiteralTable.intern('FlateDecode'), PSLiteralTable.intern('Fl'))
                                                                                      ^
prog.cpp:826:46: warning: character constant too long for its type
 LITERALS_LZW_DECODE = (PSLiteralTable.intern('LZWDecode'), PSLiteralTable.intern('LZW'))
                                              ^
prog.cpp:826:82: warning: multi-character character constant [-Wmultichar]
 LITERALS_LZW_DECODE = (PSLiteralTable.intern('LZWDecode'), PSLiteralTable.intern('LZW'))
                                                                                  ^
prog.cpp:827:50: warning: character constant too long for its type
 LITERALS_ASCII85_DECODE = (PSLiteralTable.intern('ASCII85Decode'), PSLiteralTable.intern('A85'))
                                                  ^
prog.cpp:827:90: warning: multi-character character constant [-Wmultichar]
 LITERALS_ASCII85_DECODE = (PSLiteralTable.intern('ASCII85Decode'), PSLiteralTable.intern('A85'))
                                                                                          ^
prog.cpp:830:1: error: stray '##' in program
 ##  PDF Objects
 ^
prog.cpp:831:1: error: stray '##' in program
 ##
 ^
prog.cpp:840:1: error: stray '##' in program
 ##  PDFObjRef
 ^
prog.cpp:841:1: error: stray '##' in program
 ##
 ^
prog.cpp:847:37: warning: character constant too long for its type
                 raise PDFValueError('PDF object id cannot be 0.')
                                     ^
prog.cpp:854:16: warning: character constant too long for its type
         return '<PDFObjRef:%d %d>' % (self.objid, self.genno)
                ^
prog.cpp:860:3: error: invalid preprocessing directive #resolve
 # resolve
   ^
prog.cpp:862:5: error: empty character constant
     '''
     ^
prog.cpp:862:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:862:5: error: missing terminating ' character
     '''
     ^
prog.cpp:865:5: error: empty character constant
     '''
     ^
prog.cpp:865:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:865:5: error: missing terminating ' character
     '''
     ^
prog.cpp:871:5: error: empty character constant
     '''
     ^
prog.cpp:871:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:871:5: error: missing terminating ' character
     '''
     ^
prog.cpp:875:5: error: empty character constant
     '''
     ^
prog.cpp:875:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:875:5: error: missing terminating ' character
     '''
     ^
prog.cpp:886:5: error: empty character constant
     '''
     ^
prog.cpp:886:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:886:5: error: missing terminating ' character
     '''
     ^
prog.cpp:888:5: error: empty character constant
     '''
     ^
prog.cpp:888:7: warning: missing terminating ' character
     '''
       ^
prog.cpp:888:5: error: missing terminating ' character
     '''
     ^
prog.cpp:899:3: error: invalid preprocessing directive #Type
 # Type cheking
   ^
prog.cpp:904:32: warning: character constant too long for its type
             raise PDFTypeError('Integer required: %r' % x)
                                ^
prog.cpp:912:32: warning: character constant too long for its type
             raise PDFTypeError('Float required: %r' % x)
                                ^
prog.cpp:920:32: warning: character constant too long for its type
             raise PDFTypeError('Int or Float required: %r' % x)
                                ^
prog.cpp:928:32: warning: character constant too long for its type
             raise PDFTypeError('String required: %r' % x)
                                ^
prog.cpp:929:16: error: empty character constant
         return ''
                ^
prog.cpp:936:32: warning: character constant too long for its type
             raise PDFTypeError('List required: %r' % x)
                                ^
prog.cpp:944:32: warning: character constant too long for its type
             raise PDFTypeError('Dict required: %r' % x)
                                ^
prog.cpp:952:32: warning: character constant too long for its type
             raise PDFTypeError('PDFStream required: %r' % x)
                                ^
prog.cpp:953:30: error: empty character constant
         return PDFStream({}, '')
                              ^
prog.cpp:956:3: error: invalid preprocessing directive #ascii85decode
 # ascii85decode(data)
   ^
prog.cpp:959:9: error: empty character constant
   out = ''
         ^
prog.cpp:965:28: warning: multi-character character constant [-Wmultichar]
         out += struct.pack('>L',b)
                            ^
prog.cpp:969:14: warning: multi-character character constant [-Wmultichar]
       out += '\0\0\0\0'
              ^
prog.cpp:974:28: warning: multi-character character constant [-Wmultichar]
         out += struct.pack('>L',b)[:n-1]
                            ^
prog.cpp:979:1: error: stray '##' in program
 ##  PDFStream type
 ^
prog.cpp:982:36: warning: character constant too long for its type
         length = int_value(dic.get('Length', 0))
                                    ^
prog.cpp:984:11: error: invalid preprocessing directive #quick
         # quick and dirty fix for false length attribute,
           ^
prog.cpp:985:11: error: invalid preprocessing directive #might
         # might not work if the pdf stream parser has a problem
           ^
prog.cpp:986:54: warning: character constant too long for its type
         if decipher != None and decipher.__name__ == 'decrypt_aes':
                                                      ^
prog.cpp:991:36: warning: multi-character character constant [-Wmultichar]
             if eol in ('\r', '\n', '\r\n'):
                                    ^
prog.cpp:1010:20: warning: character constant too long for its type
             return '<PDFStream(%r): raw=%d, %r>' % \
                    ^
prog.cpp:1013:20: warning: character constant too long for its type
             return '<PDFStream(%r): data=%d, %r>' % \
                    ^
prog.cpp:1020:15: error: invalid preprocessing directive #Handle
             # Handle encryption
               ^
prog.cpp:1023:37: error: stray '#' in program
                 self.decdata = data # keep decrypted data
                                     ^
prog.cpp:1024:12: warning: character constant too long for its type
         if 'Filter' not in self.dic:
            ^
prog.cpp:1027:13: error: stray '##' in program
             ##print self.dict
             ^
prog.cpp:1029:28: warning: character constant too long for its type
         filters = self.dic['Filter']
                            ^
prog.cpp:1034:19: error: invalid preprocessing directive #will
                 # will get errors if the document is encrypted.
                   ^
prog.cpp:1037:24: error: empty character constant
                 data = ''.join(LZWDecoder(StringIO(data)).run())
                        ^
prog.cpp:1041:46: warning: character constant too long for its type
                 raise PDFNotImplementedError('/Crypt filter is unsupported')
                                              ^
prog.cpp:1043:46: warning: character constant too long for its type
                 raise PDFNotImplementedError('Unsupported filter: %r' % f)
                                              ^
prog.cpp:1044:15: error: invalid preprocessing directive #apply
             # apply predictors
               ^
prog.cpp:1045:16: warning: multi-character character constant [-Wmultichar]
             if 'DP' in self.dic:
                ^
prog.cpp:1046:35: warning: multi-character character constant [-Wmultichar]
                 params = self.dic['DP']
                                   ^
prog.cpp:1048:39: warning: character constant too long for its type
                 params = self.dic.get('DecodeParms', {})
                                       ^
prog.cpp:1049:16: warning: character constant too long for its type
             if 'Predictor' in params:
                ^
prog.cpp:1050:41: warning: character constant too long for its type
                 pred = int_value(params['Predictor'])
                                         ^
prog.cpp:1054:29: warning: character constant too long for its type
                             'Unsupported predictor: %r' % pred)
                             ^
prog.cpp:1055:24: warning: character constant too long for its type
                     if 'Columns' not in params:
                        ^
prog.cpp:1057:29: warning: character constant too long for its type
                             'Columns undefined for predictor=12')
                             ^
prog.cpp:1058:48: warning: character constant too long for its type
                     columns = int_value(params['Columns'])
                                                ^
prog.cpp:1059:27: error: empty character constant
                     buf = ''
                           ^
prog.cpp:1065:36: error: empty character constant
                             ent1 = ''.join(chr((ord(a)+ord(b)) & 255) \
                                    ^
prog.cpp:1087:15: error: invalid preprocessing directive #Handle
             # Handle encryption
               ^
prog.cpp:1092:1: error: stray '##' in program
 ##  PDF Exceptions
 ^
prog.cpp:1093:1: error: stray '##' in program
 ##
 ^
prog.cpp:1099:3: error: invalid preprocessing directive #some
 # some predefined literals and keywords.
   ^
prog.cpp:1100:40: warning: character constant too long for its type
 LITERAL_OBJSTM = PSLiteralTable.intern('ObjStm')
                                        ^
prog.cpp:1101:38: warning: multi-character character constant [-Wmultichar]
 LITERAL_XREF = PSLiteralTable.intern('XRef')
                                      ^
prog.cpp:1102:38: warning: multi-character character constant [-Wmultichar]
 LITERAL_PAGE = PSLiteralTable.intern('Page')
                                      ^
prog.cpp:1103:39: warning: character constant too long for its type
 LITERAL_PAGES = PSLiteralTable.intern('Pages')
                                       ^
prog.cpp:1104:41: warning: character constant too long for its type
 LITERAL_CATALOG = PSLiteralTable.intern('Catalog')
                                         ^
prog.cpp:1107:1: error: stray '##' in program
 ##  XRefs
 ^
prog.cpp:1108:1: error: stray '##' in program
 ##
 ^
prog.cpp:1110:1: error: stray '##' in program
 ##  PDFXRef
 ^
prog.cpp:1111:1: error: stray '##' in program
 ##
 ^
prog.cpp:1119:16: warning: character constant too long for its type
         return '<PDFXRef: objs=%d>' % len(self.offsets)
                ^
prog.cpp:1130:38: warning: character constant too long for its type
                 raise PDFNoValidXRef('Unexpected EOF - file corrupted?')
                                      ^
prog.cpp:1132:38: warning: character constant too long for its type
                 raise PDFNoValidXRef('Premature eof: %r' % parser)
                                      ^
prog.cpp:1133:32: warning: character constant too long for its type
             if line.startswith('trailer'):
                                ^
prog.cpp:1138:38: warning: character constant too long for its type
                 raise PDFNoValidXRef('Trailer not found: %r: line=%r' % (parser, line))
                                      ^
prog.cpp:1142:38: warning: character constant too long for its type
                 raise PDFNoValidXRef('Invalid line: %r: line=%r' % (parser, line))
                                      ^
prog.cpp:1147:42: warning: character constant too long for its type
                     raise PDFNoValidXRef('Unexpected EOF - file corrupted?')
                                          ^
prog.cpp:1150:42: warning: character constant too long for its type
                     raise PDFNoValidXRef('Invalid XRef format: %r, line=%r' % (parser, line))
                                          ^
prog.cpp:1157:45: warning: character constant too long for its type
     KEYWORD_TRAILER = PSKeywordTable.intern('trailer')
                                             ^
prog.cpp:1166:38: warning: character constant too long for its type
                 raise PDFNoValidXRef('Unexpected EOF - file corrupted')
                                      ^
prog.cpp:1179:1: error: stray '##' in program
 ##  PDFXRefStream
 ^
prog.cpp:1180:1: error: stray '##' in program
 ##
 ^
prog.cpp:1191:16: warning: character constant too long for its type
         return '<PDFXRef: objids=%s>' % self.index
                ^
prog.cpp:1199:40: error: stray '#' in program
         (_,objid) = parser.nexttoken() # ignored
                                        ^
prog.cpp:1200:40: error: stray '#' in program
         (_,genno) = parser.nexttoken() # ignored
                                        ^
prog.cpp:1204:23: warning: multi-character character constant [-Wmultichar]
            stream.dic['Type'] is not LITERAL_XREF:
                       ^
prog.cpp:1205:34: warning: character constant too long for its type
             raise PDFNoValidXRef('Invalid PDF stream spec.')
                                  ^
prog.cpp:1206:27: warning: multi-character character constant [-Wmultichar]
         size = stream.dic['Size']
                           ^
prog.cpp:1207:32: warning: character constant too long for its type
         index = stream.dic.get('Index', (0,size))
                                ^
prog.cpp:1235:11: error: invalid preprocessing directive #this
         # this is a free object
           ^
prog.cpp:1239:1: error: stray '##' in program
 ##  PDFDocument
 ^
prog.cpp:1240:1: error: stray '##' in program
 ##
 ^
prog.cpp:1241:1: error: stray '##' in program
 ##  A PDFDocument object represents a PDF document.
 ^
prog.cpp:1242:1: error: stray '##' in program
 ##  Since a PDF file is usually pretty big, normally it is not loaded
 ^
prog.cpp:1243:1: error: stray '##' in program
 ##  at once. Rather it is parsed dynamically as processing goes.
 ^
prog.cpp:1244:1: error: stray '##' in program
 ##  A PDF parser is associated with the document.
 ^
prog.cpp:1245:1: error: stray '##' in program
 ##
 ^
prog.cpp:1257:11: error: invalid preprocessing directive #dictionaries
         # dictionaries for fileopen
           ^
prog.cpp:1263:7: error: invalid preprocessing directive #set_parser
     # set_parser(parser)
       ^
prog.cpp:1264:9: error: invalid preprocessing directive #Associates
     #   Associates the document with an (already initialized) parser object.
         ^
prog.cpp:1268:11: error: invalid preprocessing directive #The
         # The document is set to be temporarily ready during collecting
           ^
prog.cpp:1269:11: error: invalid preprocessing directive #all
         # all the basic information about the document, e.g.
           ^
prog.cpp:1270:11: error: invalid preprocessing directive #the
         # the header, the encryption information, and the access rights 
           ^
prog.cpp:1271:11: error: invalid preprocessing directive #for
         # for the document.
           ^
prog.cpp:1273:11: error: invalid preprocessing directive #Retrieve
         # Retrieve the information of each header that was appended
           ^
prog.cpp:1274:11: error: invalid preprocessing directive #(
         # (maybe multiple times) at the end of the document.
           ^
prog.cpp:1280:15: error: invalid preprocessing directive #If
             # If there's an encryption info, remember it.
               ^
prog.cpp:1280:23: warning: missing terminating ' character
             # If there's an encryption info, remember it.
                       ^
prog.cpp:1281:16: warning: character constant too long for its type
             if 'Encrypt' in trailer:
                ^
prog.cpp:1282:18: warning: #assert is a deprecated GCC extension [-Wdeprecated]
                 #assert not self.encryption
                  ^
prog.cpp:1282:25: error: predicate must be an identifier
                 #assert not self.encryption
                         ^
prog.cpp:1284:59: warning: multi-character character constant [-Wmultichar]
                     self.encryption = (list_value(trailer['ID']),
                                                           ^
prog.cpp:1285:55: warning: character constant too long for its type
                                    dict_value(trailer['Encrypt']))
                                                       ^
prog.cpp:1286:19: error: invalid preprocessing directive #fix
                 # fix for bad files
                   ^
prog.cpp:1288:40: warning: character constant too long for its type
                     self.encryption = ('ffffffffffffffffffffffffffffffffffff',
                                        ^
prog.cpp:1289:59: warning: character constant too long for its type
                                        dict_value(trailer['Encrypt']))
                                                           ^
prog.cpp:1290:16: warning: multi-character character constant [-Wmultichar]
             if 'Root' in trailer:
                ^
prog.cpp:1291:50: warning: multi-character character constant [-Wmultichar]
                 self.set_root(dict_value(trailer['Root']))
                                                  ^
prog.cpp:1294:34: warning: character constant too long for its type
             raise PDFSyntaxError('No /Root object! - Is this really a PDF?')
                                  ^
prog.cpp:1295:11: error: invalid preprocessing directive #The
         # The document is set to be non-ready again, until all the
           ^
prog.cpp:1296:11: error: invalid preprocessing directive #proper
         # proper initialization (asking the password key and
           ^
prog.cpp:1297:11: error: invalid preprocessing directive #verifying
         # verifying the access permission, so on) is finished.
           ^
prog.cpp:1301:7: error: invalid preprocessing directive #set_root
     # set_root(root)
       ^
prog.cpp:1302:9: error: invalid preprocessing directive #Set
     #   Set the Root dictionary of the document.
         ^
prog.cpp:1303:9: error: invalid preprocessing directive #Each
     #   Each PDF file must have exactly one /Root dictionary.
         ^
prog.cpp:1307:29: warning: multi-character character constant [-Wmultichar]
         if self.catalog.get('Type') is not LITERAL_CATALOG:
                             ^
prog.cpp:1309:38: warning: character constant too long for its type
                 raise PDFSyntaxError('Catalog not found!')
                                      ^
prog.cpp:1311:7: error: invalid preprocessing directive #initialize
     # initialize(password='')
       ^
prog.cpp:1312:9: error: invalid preprocessing directive #Perform
     #   Perform the initialization with a given password.
         ^
prog.cpp:1313:9: error: invalid preprocessing directive #This
     #   This step is mandatory even if there's no password associated
         ^
prog.cpp:1313:45: warning: missing terminating ' character
     #   This step is mandatory even if there's no password associated
                                             ^
prog.cpp:1314:9: error: invalid preprocessing directive #with
     #   with the document.
         ^
prog.cpp:1315:35: error: empty character constant
     def initialize(self, password=''):
                                   ^
prog.cpp:1321:35: warning: character constant too long for its type
         type = literal_name(param['Filter'])
                                   ^
prog.cpp:1322:20: warning: character constant too long for its type
         if type == 'Adobe.APS':
                    ^
prog.cpp:1324:20: warning: character constant too long for its type
         if type == 'Standard':
                    ^
prog.cpp:1326:20: warning: character constant too long for its type
         if type == 'EBX_HANDLER':
                    ^
prog.cpp:1328:20: warning: character constant too long for its type
         if type == 'FOPN_fLock':
                    ^
prog.cpp:1329:15: error: invalid preprocessing directive #remove
             # remove of unnecessairy password attribute
               ^
prog.cpp:1331:20: warning: character constant too long for its type
         if type == 'FOPN_foweb':
                    ^
prog.cpp:1332:15: error: invalid preprocessing directive #remove
             # remove of unnecessairy password attribute
               ^
prog.cpp:1334:34: warning: character constant too long for its type
         raise PDFEncryptionError('Unknown filter: param=%r' % param)
                                  ^
prog.cpp:1347:19: warning: character constant too long for its type
             data1='<?xml version="1.0" encoding="UTF-8"?><SOAP-ENV:Envelope xmlns:SO'+\
                   ^
prog.cpp:1348:13: warning: character constant too long for its type
             'AP-ENV="http://s...content-available-to-author-only...p.org/soap/envelope/" xmlns:SOAP-ENC="http'+\
             ^
prog.cpp:1349:13: warning: character constant too long for its type
             '://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://w...content-available-to-author-only...3.org/2001/'+\
             ^
prog.cpp:1350:13: warning: character constant too long for its type
             'XMLSchema-instance" xmlns:xsd="http://w...content-available-to-author-only...3.org/2001/XMLSchema" xmlns:tns1="'+\
             ^
prog.cpp:1351:13: warning: character constant too long for its type
             'http://e...content-available-to-author-only...e.com/edcwebservice" xmlns:impl="http://localhost:8080/axis/s'+\
             ^
prog.cpp:1352:13: warning: character constant too long for its type
             'ervices/urn:EDCLicenseService" xmlns:ns2="http://c...content-available-to-author-only...e.com" xmlns:ns1="'+\
             ^
prog.cpp:1353:13: warning: character constant too long for its type
             'http://n...content-available-to-author-only...e.com/PolicyServer/ws"><SOAP-ENV:Header><EDCSecurity>&lt;wsse:Security '+\
             ^
prog.cpp:1354:13: warning: character constant too long for its type
             'xmlns:wsse="http://d...content-available-to-author-only...n.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-'+\
             ^
prog.cpp:1355:13: warning: character constant too long for its type
             '1.0.xsd"&gt;&lt;wsse:UsernameToken&gt;&lt;wsse:Username&gt;edc_anonymous&lt;/wsse:Username&'+\
             ^
prog.cpp:1356:13: warning: character constant too long for its type
             'gt;&lt;wsse:Password Type="http://d...content-available-to-author-only...n.org/wss/2004/01/oasis-200401-wss-username-'+\
             ^
prog.cpp:1357:13: warning: character constant too long for its type
             'token-profile-1.0#PasswordText"&gt;edc_anonymous&lt;/wsse:Password&gt;&lt;/wsse:UsernameToken&'+\
             ^
prog.cpp:1358:13: warning: character constant too long for its type
             'gt;&lt;/wsse:Security&gt;</EDCSecurity><Version>7</Version><Locale>de-de</Locale></SOAP-ENV:Header>'+\
             ^
prog.cpp:1359:13: warning: character constant too long for its type
             '<SOAP-ENV:Body><impl:synchronize><SynchronizationRequest><firstTime>1</firstTime><licenseSeqNum>0</'+\
             ^
prog.cpp:1360:13: warning: character constant too long for its type
             'licenseSeqNum><policySeqNum>1</policySeqNum><revocationSeqNum>0</revocationSeqNum><'+\
             ^
prog.cpp:1361:13: warning: character constant too long for its type
             'watermarkTemplateSeqNum>0</watermarkTemplateSeqNum></SynchronizationRequest></'+\
             ^
prog.cpp:1362:13: warning: character constant too long for its type
             'impl:synchronize></SOAP-ENV:Body></SOAP-ENV:Envelope>'
             ^
prog.cpp:1365:14: error: invalid preprocessing directive #~
             #~ extract host and path:
              ^
prog.cpp:1366:30: warning: character constant too long for its type
             host=re.compile(r'[a-zA-Z]://([^/]+)/.+', re.I).search(url).group(1)
                              ^
prog.cpp:1367:33: warning: character constant too long for its type
             urlpath=re.compile(r'[a-zA-Z]://[^/]+(/.+)', re.I).search(url).group(1)
                                 ^
prog.cpp:1369:15: error: invalid preprocessing directive #open
             # open a socket connection on port 80
               ^
prog.cpp:1373:14: error: invalid preprocessing directive #~
             #~ Headers for request
              ^
prog.cpp:1377:15: error: invalid preprocessing directive #send
             # send data1 and headers
               ^
prog.cpp:1383:15: error: invalid preprocessing directive #read
             # read respose
               ^
prog.cpp:1390:15: error: invalid preprocessing directive #close
             # close connection
               ^
prog.cpp:1394:37: warning: character constant too long for its type
                     key=re.compile(r'PricipalKey"((?!<key>).)*<key[^>]*>(((?!</key>).)*)</key>', re.I).search(responsedata).group(2)
                                     ^
prog.cpp:1401:11: error: invalid preprocessing directive #nice
         # nice little offline principal keys dictionary
           ^
prog.cpp:1402:27: warning: character constant too long for its type
         principalkeys = { 'bibliothek-digital.de': 'Dzqx8McQUNd2CDzBVmtnweUxVWlqJTMqyYtiDIc4dZI='.decode('base64')}
                           ^
prog.cpp:1402:52: warning: character constant too long for its type
         principalkeys = { 'bibliothek-digital.de': 'Dzqx8McQUNd2CDzBVmtnweUxVWlqJTMqyYtiDIc4dZI='.decode('base64')}
                                                    ^
prog.cpp:1402:106: warning: character constant too long for its type
         principalkeys = { 'bibliothek-digital.de': 'Dzqx8McQUNd2CDzBVmtnweUxVWlqJTMqyYtiDIc4dZI='.decode('base64')}
                                                                                                          ^
prog.cpp:1405:14: error: invalid preprocessing directive #print
             #print result
              ^
prog.cpp:1407:50: warning: character constant too long for its type
                 principalkeys[k] = result.decode('base64')
                                                  ^
prog.cpp:1412:1: error: stray '##' in program
 ##        print 'keyvalue'
 ^
prog.cpp:1412:17: warning: character constant too long for its type
 ##        print 'keyvalue'
                 ^
prog.cpp:1413:1: error: stray '##' in program
 ##        print len(keyvalue)
 ^
prog.cpp:1414:1: error: stray '##' in program
 ##        print keyvalue.encode('hex')
 ^
prog.cpp:1414:33: warning: multi-character character constant [-Wmultichar]
 ##        print keyvalue.encode('hex')
                                 ^
prog.cpp:1415:38: warning: character constant too long for its type
         length = int_value(param.get('Length', 0)) / 8
                                      ^
prog.cpp:1416:39: warning: character constant too long for its type
         edcdata = str_value(param.get('EDCData')).decode('base64')
                                       ^
prog.cpp:1416:58: warning: character constant too long for its type
         edcdata = str_value(param.get('EDCData')).decode('base64')
                                                          ^
prog.cpp:1417:39: warning: character constant too long for its type
         pdrllic = str_value(param.get('PDRLLic')).decode('base64')
                                       ^
prog.cpp:1417:58: warning: character constant too long for its type
         pdrllic = str_value(param.get('PDRLLic')).decode('base64')
                                                          ^
prog.cpp:1418:39: warning: character constant too long for its type
         pdrlpol = str_value(param.get('PDRLPol')).decode('base64')          
                                       ^
prog.cpp:1418:58: warning: character constant too long for its type
         pdrlpol = str_value(param.get('PDRLPol')).decode('base64')          
                                                          ^
prog.cpp:1419:10: error: invalid preprocessing directive #print
         #print 'ecd rights'
          ^
prog.cpp:1423:1: error: stray '##' in program
 ##        print edclist
 ^
prog.cpp:1424:1: error: stray '##' in program
 ##        print 'edcdata decrypted'
 ^
prog.cpp:1424:17: warning: character constant too long for its type
 ##        print 'edcdata decrypted'
                 ^
prog.cpp:1425:1: error: stray '##' in program
 ##        print edclist[0].decode('base64').encode('hex')
 ^
prog.cpp:1425:35: warning: character constant too long for its type
 ##        print edclist[0].decode('base64').encode('hex')
                                   ^
prog.cpp:1425:52: warning: multi-character character constant [-Wmultichar]
 ##        print edclist[0].decode('base64').encode('hex')
                                                    ^
prog.cpp:1426:1: error: stray '##' in program
 ##        print edclist[1].decode('base64').encode('hex')
 ^
prog.cpp:1426:35: warning: character constant too long for its type
 ##        print edclist[1].decode('base64').encode('hex')
                                   ^
prog.cpp:1426:52: warning: multi-character character constant [-Wmultichar]
 ##        print edclist[1].decode('base64').encode('hex')
                                                    ^
prog.cpp:1427:1: error: stray '##' in program
 ##        print edclist[2].decode('base64').encode('hex')
 ^
prog.cpp:1427:35: warning: character constant too long for its type
 ##        print edclist[2].decode('base64').encode('hex')
                                   ^
prog.cpp:1427:52: warning: multi-character character constant [-Wmultichar]
 ##        print edclist[2].decode('base64').encode('hex')
                                                    ^
prog.cpp:1428:1: error: stray '##' in program
 ##        print edclist[3].decode('base64').encode('hex')
 ^
prog.cpp:1428:35: warning: character constant too long for its type
 ##        print edclist[3].decode('base64').encode('hex')
                                   ^
prog.cpp:1428:52: warning: multi-character character constant [-Wmultichar]
 ##        print edclist[3].decode('base64').encode('hex')
                                                    ^
prog.cpp:1429:1: error: stray '##' in program
 ##        print 'offlinekey'
 ^
prog.cpp:1429:17: warning: character constant too long for its type
 ##        print 'offlinekey'
                 ^
prog.cpp:1430:1: error: stray '##' in program
 ##        print len(edclist[9].decode('base64'))
 ^
prog.cpp:1430:39: warning: character constant too long for its type
 ##        print len(edclist[9].decode('base64'))
                                       ^
prog.cpp:1431:1: error: stray '##' in program
 ##        print pdrllic
 ^
prog.cpp:1432:11: error: invalid preprocessing directive #principal
         # principal key request
           ^
prog.cpp:1437:34: warning: character constant too long for its type
                 raise ADEPTError('Cannot find principal key for this pdf')
                                  ^
prog.cpp:1438:1: error: stray '##' in program
 ##        print 'minorversion'
 ^
prog.cpp:1438:17: warning: character constant too long for its type
 ##        print 'minorversion'
                 ^
prog.cpp:1439:1: error: stray '##' in program
 ##        print int(edclist[8])
 ^
prog.cpp:1440:11: error: invalid preprocessing directive #fix
         # fix for minor version
           ^
prog.cpp:1441:1: error: stray '##' in program
 ##        minorversion = int(edclist[8]) - 100
 ^
prog.cpp:1442:1: error: stray '##' in program
 ##        if minorversion < 1:
 ^
prog.cpp:1443:1: error: stray '##' in program
 ##            minorversion = 1
 ^
prog.cpp:1444:1: error: stray '##' in program
 ##        print int(minorversion)
 ^
prog.cpp:1447:1: error: stray '##' in program
 ##        for i in range(0,minorversion):
 ^
prog.cpp:1448:1: error: stray '##' in program
 ##            shakey.update(principalkey)
 ^
prog.cpp:1450:1: error: stray '##' in program
 ##        shakey = SHA256.new(principalkey).digest()
 ^
prog.cpp:1452:10: error: invalid preprocessing directive #print
         #print shakey
          ^
prog.cpp:1453:84: warning: character constant too long for its type
         plaintext = AES.new(shakey,AES.MODE_CBC,ivector).decrypt(edclist[9].decode('base64'))
                                                                                    ^
prog.cpp:1455:30: warning: character constant too long for its type
             raise ADEPTError('Offlinekey cannot be decrypted, aborting (hint: redownload pdf) ...')
                              ^
prog.cpp:1456:75: warning: character constant too long for its type
         pdrlpol = AES.new(plaintext[16:32],AES.MODE_CBC,edclist[2].decode('base64')).decrypt(pdrlpol)
                                                                           ^
prog.cpp:1458:30: warning: character constant too long for its type
             raise ADEPTError('Could not decrypt PDRLPol, aborting ...')
                              ^
prog.cpp:1461:14: error: invalid preprocessing directive #print
             #print cutter
              ^
prog.cpp:1463:10: error: invalid preprocessing directive #print
         #print plaintext.encode('hex')
          ^
prog.cpp:1464:10: error: invalid preprocessing directive #print
         #print 'pdrlpol'
          ^
prog.cpp:1465:10: error: invalid preprocessing directive #print
         #print pdrlpol
          ^
prog.cpp:1468:24: warning: hex escape sequence out of range
     PASSWORD_PADDING = '(\xbfN^Nu\x8aAd\x00NV\xff\xfa\x01\x08..' \
                        ^
prog.cpp:1468:24: warning: character constant too long for its type
prog.cpp:1469:24: warning: hex escape sequence out of range
                        '\x00\xb6\xd0h>\x80/\x0c\xa9\xfedSiz'
                        ^
prog.cpp:1469:24: warning: character constant too long for its type
prog.cpp:1470:7: error: invalid preprocessing directive #experimental
     # experimental aes pw support
       ^
prog.cpp:1472:11: error: invalid preprocessing directive #copy
         # copy from a global variable
           ^
prog.cpp:1475:38: warning: character constant too long for its type
             raise PDFEncryptionError('Unknown algorithm: param=%r' % param)
                                      ^
prog.cpp:1476:38: warning: character constant too long for its type
         length = int_value(param.get('Length', 40)) # Key length (bits)
                                      ^
prog.cpp:1476:53: error: stray '#' in program
         length = int_value(param.get('Length', 40)) # Key length (bits)
                                                     ^
prog.cpp:1478:35: error: stray '#' in program
         R = int_value(param['R']) # Revision
                                   ^
prog.cpp:1480:38: warning: character constant too long for its type
             raise PDFEncryptionError('Unknown revision: %r' % R)
                                      ^
prog.cpp:1484:43: warning: character constant too long for its type
             EncMetadata = str_value(param['EncryptMetadata'])
                                           ^
prog.cpp:1486:27: warning: multi-character character constant [-Wmultichar]
             EncMetadata = 'True'
                           ^
prog.cpp:1495:11: error: invalid preprocessing directive #Algorithm
         # Algorithm 3.2
           ^
prog.cpp:1496:58: error: stray '#' in program
         password = (password+self.PASSWORD_PADDING)[:32] # 1
                                                          ^
prog.cpp:1497:38: error: stray '#' in program
         hash = hashlib.md5(password) # 2
                                      ^
prog.cpp:1498:24: error: stray '#' in program
         hash.update(O) # 3
                        ^
prog.cpp:1499:33: warning: multi-character character constant [-Wmultichar]
         hash.update(struct.pack('<l', P)) # 4
                                 ^
prog.cpp:1499:43: error: stray '#' in program
         hash.update(struct.pack('<l', P)) # 4
                                           ^
prog.cpp:1500:31: 
stdout
Standard output is empty