document_spec.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /**
  2. * @licstart The following is the entire license notice for the
  3. * JavaScript code in this page
  4. *
  5. * Copyright 2022 Mozilla Foundation
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. *
  19. * @licend The above is the entire license notice for the
  20. * JavaScript code in this page
  21. */
  22. "use strict";
  23. var _test_utils = require("./test_utils.js");
  24. var _primitives = require("../../core/primitives.js");
  25. var _document = require("../../core/document.js");
  26. var _stream = require("../../core/stream.js");
  27. describe("document", function () {
  28. describe("Page", function () {
  29. it("should create correct objId/fontId using the idFactory", function () {
  30. const idFactory1 = (0, _test_utils.createIdFactory)(0);
  31. const idFactory2 = (0, _test_utils.createIdFactory)(1);
  32. expect(idFactory1.createObjId()).toEqual("p0_1");
  33. expect(idFactory1.createObjId()).toEqual("p0_2");
  34. expect(idFactory1.createFontId()).toEqual("f1");
  35. expect(idFactory1.createFontId()).toEqual("f2");
  36. expect(idFactory1.getDocId()).toEqual("g_d0");
  37. expect(idFactory2.createObjId()).toEqual("p1_1");
  38. expect(idFactory2.createObjId()).toEqual("p1_2");
  39. expect(idFactory2.createFontId()).toEqual("f1");
  40. expect(idFactory2.createFontId()).toEqual("f2");
  41. expect(idFactory2.getDocId()).toEqual("g_d0");
  42. expect(idFactory1.createObjId()).toEqual("p0_3");
  43. expect(idFactory1.createObjId()).toEqual("p0_4");
  44. expect(idFactory1.createFontId()).toEqual("f3");
  45. expect(idFactory1.createFontId()).toEqual("f4");
  46. expect(idFactory1.getDocId()).toEqual("g_d0");
  47. });
  48. });
  49. describe("PDFDocument", function () {
  50. const stream = new _stream.StringStream("Dummy_PDF_data");
  51. function getDocument(acroForm, xref = new _test_utils.XRefMock()) {
  52. const catalog = {
  53. acroForm
  54. };
  55. const pdfManager = {
  56. get docId() {
  57. return "d0";
  58. },
  59. ensureDoc(prop, args) {
  60. return pdfManager.ensure(pdfDocument, prop, args);
  61. },
  62. ensureCatalog(prop, args) {
  63. return pdfManager.ensure(catalog, prop, args);
  64. },
  65. async ensure(obj, prop, args) {
  66. const value = obj[prop];
  67. if (typeof value === "function") {
  68. return value.apply(obj, args);
  69. }
  70. return value;
  71. },
  72. get evaluatorOptions() {
  73. return {
  74. isOffscreenCanvasSupported: false
  75. };
  76. }
  77. };
  78. const pdfDocument = new _document.PDFDocument(pdfManager, stream);
  79. pdfDocument.xref = xref;
  80. pdfDocument.catalog = catalog;
  81. return pdfDocument;
  82. }
  83. it("should get form info when no form data is present", function () {
  84. const pdfDocument = getDocument(null);
  85. expect(pdfDocument.formInfo).toEqual({
  86. hasAcroForm: false,
  87. hasSignatures: false,
  88. hasXfa: false,
  89. hasFields: false
  90. });
  91. });
  92. it("should get form info when XFA is present", function () {
  93. const acroForm = new _primitives.Dict();
  94. acroForm.set("XFA", []);
  95. let pdfDocument = getDocument(acroForm);
  96. expect(pdfDocument.formInfo).toEqual({
  97. hasAcroForm: false,
  98. hasSignatures: false,
  99. hasXfa: false,
  100. hasFields: false
  101. });
  102. acroForm.set("XFA", ["foo", "bar"]);
  103. pdfDocument = getDocument(acroForm);
  104. expect(pdfDocument.formInfo).toEqual({
  105. hasAcroForm: false,
  106. hasSignatures: false,
  107. hasXfa: true,
  108. hasFields: false
  109. });
  110. acroForm.set("XFA", new _stream.StringStream(""));
  111. pdfDocument = getDocument(acroForm);
  112. expect(pdfDocument.formInfo).toEqual({
  113. hasAcroForm: false,
  114. hasSignatures: false,
  115. hasXfa: false,
  116. hasFields: false
  117. });
  118. acroForm.set("XFA", new _stream.StringStream("non-empty"));
  119. pdfDocument = getDocument(acroForm);
  120. expect(pdfDocument.formInfo).toEqual({
  121. hasAcroForm: false,
  122. hasSignatures: false,
  123. hasXfa: true,
  124. hasFields: false
  125. });
  126. });
  127. it("should get form info when AcroForm is present", function () {
  128. const acroForm = new _primitives.Dict();
  129. acroForm.set("Fields", []);
  130. let pdfDocument = getDocument(acroForm);
  131. expect(pdfDocument.formInfo).toEqual({
  132. hasAcroForm: false,
  133. hasSignatures: false,
  134. hasXfa: false,
  135. hasFields: false
  136. });
  137. acroForm.set("Fields", ["foo", "bar"]);
  138. pdfDocument = getDocument(acroForm);
  139. expect(pdfDocument.formInfo).toEqual({
  140. hasAcroForm: true,
  141. hasSignatures: false,
  142. hasXfa: false,
  143. hasFields: true
  144. });
  145. acroForm.set("Fields", ["foo", "bar"]);
  146. acroForm.set("SigFlags", 2);
  147. pdfDocument = getDocument(acroForm);
  148. expect(pdfDocument.formInfo).toEqual({
  149. hasAcroForm: true,
  150. hasSignatures: false,
  151. hasXfa: false,
  152. hasFields: true
  153. });
  154. const annotationDict = new _primitives.Dict();
  155. annotationDict.set("FT", _primitives.Name.get("Sig"));
  156. annotationDict.set("Rect", [0, 0, 0, 0]);
  157. const annotationRef = _primitives.Ref.get(11, 0);
  158. const kidsDict = new _primitives.Dict();
  159. kidsDict.set("Kids", [annotationRef]);
  160. const kidsRef = _primitives.Ref.get(10, 0);
  161. const xref = new _test_utils.XRefMock([{
  162. ref: annotationRef,
  163. data: annotationDict
  164. }, {
  165. ref: kidsRef,
  166. data: kidsDict
  167. }]);
  168. acroForm.set("Fields", [kidsRef]);
  169. acroForm.set("SigFlags", 3);
  170. pdfDocument = getDocument(acroForm, xref);
  171. expect(pdfDocument.formInfo).toEqual({
  172. hasAcroForm: false,
  173. hasSignatures: true,
  174. hasXfa: false,
  175. hasFields: true
  176. });
  177. });
  178. it("should get calculation order array or null", function () {
  179. const acroForm = new _primitives.Dict();
  180. let pdfDocument = getDocument(acroForm);
  181. expect(pdfDocument.calculationOrderIds).toEqual(null);
  182. acroForm.set("CO", [_primitives.Ref.get(1, 0), _primitives.Ref.get(2, 0), _primitives.Ref.get(3, 0)]);
  183. pdfDocument = getDocument(acroForm);
  184. expect(pdfDocument.calculationOrderIds).toEqual(["1R", "2R", "3R"]);
  185. acroForm.set("CO", []);
  186. pdfDocument = getDocument(acroForm);
  187. expect(pdfDocument.calculationOrderIds).toEqual(null);
  188. acroForm.set("CO", ["1", "2"]);
  189. pdfDocument = getDocument(acroForm);
  190. expect(pdfDocument.calculationOrderIds).toEqual(null);
  191. acroForm.set("CO", ["1", _primitives.Ref.get(1, 0), "2"]);
  192. pdfDocument = getDocument(acroForm);
  193. expect(pdfDocument.calculationOrderIds).toEqual(["1R"]);
  194. });
  195. it("should get field objects array or null", async function () {
  196. const acroForm = new _primitives.Dict();
  197. let pdfDocument = getDocument(acroForm);
  198. let fields = await pdfDocument.fieldObjects;
  199. expect(fields).toEqual(null);
  200. acroForm.set("Fields", []);
  201. pdfDocument = getDocument(acroForm);
  202. fields = await pdfDocument.fieldObjects;
  203. expect(fields).toEqual(null);
  204. const kid1Ref = _primitives.Ref.get(314, 0);
  205. const kid11Ref = _primitives.Ref.get(159, 0);
  206. const kid2Ref = _primitives.Ref.get(265, 0);
  207. const kid2BisRef = _primitives.Ref.get(266, 0);
  208. const parentRef = _primitives.Ref.get(358, 0);
  209. const allFields = Object.create(null);
  210. for (const name of ["parent", "kid1", "kid2", "kid11"]) {
  211. const buttonWidgetDict = new _primitives.Dict();
  212. buttonWidgetDict.set("Type", _primitives.Name.get("Annot"));
  213. buttonWidgetDict.set("Subtype", _primitives.Name.get("Widget"));
  214. buttonWidgetDict.set("FT", _primitives.Name.get("Btn"));
  215. buttonWidgetDict.set("T", name);
  216. allFields[name] = buttonWidgetDict;
  217. }
  218. allFields.kid1.set("Kids", [kid11Ref]);
  219. allFields.parent.set("Kids", [kid1Ref, kid2Ref, kid2BisRef]);
  220. const xref = new _test_utils.XRefMock([{
  221. ref: parentRef,
  222. data: allFields.parent
  223. }, {
  224. ref: kid1Ref,
  225. data: allFields.kid1
  226. }, {
  227. ref: kid11Ref,
  228. data: allFields.kid11
  229. }, {
  230. ref: kid2Ref,
  231. data: allFields.kid2
  232. }, {
  233. ref: kid2BisRef,
  234. data: allFields.kid2
  235. }]);
  236. acroForm.set("Fields", [parentRef]);
  237. pdfDocument = getDocument(acroForm, xref);
  238. fields = await pdfDocument.fieldObjects;
  239. for (const [name, objs] of Object.entries(fields)) {
  240. fields[name] = objs.map(obj => obj.id);
  241. }
  242. expect(fields["parent.kid1"]).toEqual(["314R"]);
  243. expect(fields["parent.kid1.kid11"]).toEqual(["159R"]);
  244. expect(fields["parent.kid2"]).toEqual(["265R", "266R"]);
  245. expect(fields.parent).toEqual(["358R"]);
  246. });
  247. it("should check if fields have any actions", async function () {
  248. const acroForm = new _primitives.Dict();
  249. let pdfDocument = getDocument(acroForm);
  250. let hasJSActions = await pdfDocument.hasJSActions;
  251. expect(hasJSActions).toEqual(false);
  252. acroForm.set("Fields", []);
  253. pdfDocument = getDocument(acroForm);
  254. hasJSActions = await pdfDocument.hasJSActions;
  255. expect(hasJSActions).toEqual(false);
  256. const kid1Ref = _primitives.Ref.get(314, 0);
  257. const kid11Ref = _primitives.Ref.get(159, 0);
  258. const kid2Ref = _primitives.Ref.get(265, 0);
  259. const parentRef = _primitives.Ref.get(358, 0);
  260. const allFields = Object.create(null);
  261. for (const name of ["parent", "kid1", "kid2", "kid11"]) {
  262. const buttonWidgetDict = new _primitives.Dict();
  263. buttonWidgetDict.set("Type", _primitives.Name.get("Annot"));
  264. buttonWidgetDict.set("Subtype", _primitives.Name.get("Widget"));
  265. buttonWidgetDict.set("FT", _primitives.Name.get("Btn"));
  266. buttonWidgetDict.set("T", name);
  267. allFields[name] = buttonWidgetDict;
  268. }
  269. allFields.kid1.set("Kids", [kid11Ref]);
  270. allFields.parent.set("Kids", [kid1Ref, kid2Ref]);
  271. const xref = new _test_utils.XRefMock([{
  272. ref: parentRef,
  273. data: allFields.parent
  274. }, {
  275. ref: kid1Ref,
  276. data: allFields.kid1
  277. }, {
  278. ref: kid11Ref,
  279. data: allFields.kid11
  280. }, {
  281. ref: kid2Ref,
  282. data: allFields.kid2
  283. }]);
  284. acroForm.set("Fields", [parentRef]);
  285. pdfDocument = getDocument(acroForm, xref);
  286. hasJSActions = await pdfDocument.hasJSActions;
  287. expect(hasJSActions).toEqual(false);
  288. const JS = _primitives.Name.get("JavaScript");
  289. const additionalActionsDict = new _primitives.Dict();
  290. const eDict = new _primitives.Dict();
  291. eDict.set("JS", "hello()");
  292. eDict.set("S", JS);
  293. additionalActionsDict.set("E", eDict);
  294. allFields.kid2.set("AA", additionalActionsDict);
  295. pdfDocument = getDocument(acroForm, xref);
  296. hasJSActions = await pdfDocument.hasJSActions;
  297. expect(hasJSActions).toEqual(true);
  298. });
  299. });
  300. });