XmlDtd.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. "use strict";
  2. /**
  3. * Copyright (C) 2016-2019 Michael Kourlas
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. var __importDefault = (this && this.__importDefault) || function (mod) {
  18. return (mod && mod.__esModule) ? mod : { "default": mod };
  19. };
  20. Object.defineProperty(exports, "__esModule", { value: true });
  21. exports.validatePubId = void 0;
  22. var error_1 = require("../error");
  23. var options_1 = require("../options");
  24. var validate_1 = require("../validate");
  25. var XmlComment_1 = __importDefault(require("./XmlComment"));
  26. var XmlDtdAttlist_1 = __importDefault(require("./XmlDtdAttlist"));
  27. var XmlDtdElement_1 = __importDefault(require("./XmlDtdElement"));
  28. var XmlDtdEntity_1 = __importDefault(require("./XmlDtdEntity"));
  29. var XmlDtdNotation_1 = __importDefault(require("./XmlDtdNotation"));
  30. var XmlDtdParamEntityRef_1 = __importDefault(require("./XmlDtdParamEntityRef"));
  31. var XmlProcInst_1 = __importDefault(require("./XmlProcInst"));
  32. /**
  33. * Represents an XML document type definition (DTD).
  34. *
  35. * A document type definition is structured as follows, where `{name}` is
  36. * the name of the DTD, `{sysId}` is the system identifier of the DTD,
  37. * `{pubId}` is the public identifier of the DTD, and `{intSubset}` is the
  38. * internal subset of the DTD:
  39. *
  40. * ```xml
  41. * <!DOCTYPE {name} SYSTEM "{sysId}" PUBLIC "{pubId}" [
  42. * {intSubset}
  43. * ]>
  44. * ```
  45. *
  46. * DTDs can have an unlimited number of comments, attribute-list declarations,
  47. * element declarations, entity declarations, notation declarations, parameter
  48. * entity references, and processing instructions.
  49. */
  50. var XmlDtd = /** @class */ (function () {
  51. function XmlDtd(parent, validation, options) {
  52. this._pubId = undefined;
  53. this._sysId = undefined;
  54. this._validation = validation;
  55. this._children = [];
  56. this._parent = parent;
  57. this.name = options.name;
  58. if (!(0, validate_1.isUndefined)(options.sysId)) {
  59. this.sysId = options.sysId;
  60. }
  61. if (!(0, validate_1.isUndefined)(options.pubId)) {
  62. this.pubId = options.pubId;
  63. }
  64. }
  65. Object.defineProperty(XmlDtd.prototype, "name", {
  66. /**
  67. * Gets the name of the DTD.
  68. */
  69. get: function () {
  70. return this._name;
  71. },
  72. /**
  73. * Sets the name of the DTD.
  74. */
  75. set: function (name) {
  76. if (this._validation && !(0, validate_1.validateName)(name)) {
  77. throw new Error((0, error_1.getContext)(this.up()) + ": DTD name \"" + name + "\""
  78. + " should not contain characters not allowed in"
  79. + " XML names");
  80. }
  81. this._name = name;
  82. },
  83. enumerable: false,
  84. configurable: true
  85. });
  86. Object.defineProperty(XmlDtd.prototype, "pubId", {
  87. /**
  88. * Gets the public identifier of the DTD.
  89. */
  90. get: function () {
  91. return this._pubId;
  92. },
  93. /**
  94. * Sets the public identifier of the DTD.
  95. */
  96. set: function (pubId) {
  97. if (!(0, validate_1.isUndefined)(pubId)) {
  98. if (this._validation && !validatePubId(pubId)) {
  99. throw new Error((0, error_1.getContext)(this.up()) + ": DTD public"
  100. + (" identifier \"" + pubId + "\" should not contain")
  101. + " characters not allowed in public"
  102. + " identifiers");
  103. }
  104. if (this._validation && (0, validate_1.isUndefined)(this._sysId)) {
  105. throw new Error((0, error_1.getContext)(this.up()) + ": DTD public"
  106. + (" identifier \"" + pubId + "\" should not be defined")
  107. + " if system identifier is undefined");
  108. }
  109. }
  110. this._pubId = pubId;
  111. },
  112. enumerable: false,
  113. configurable: true
  114. });
  115. Object.defineProperty(XmlDtd.prototype, "sysId", {
  116. /**
  117. * Gets the system identifier of the DTD.
  118. */
  119. get: function () {
  120. return this._sysId;
  121. },
  122. /**
  123. * Sets the system identifier of the DTD.
  124. */
  125. set: function (sysId) {
  126. if (!(0, validate_1.isUndefined)(sysId)) {
  127. if (this._validation && !(0, validate_1.validateChar)(sysId)) {
  128. throw new Error((0, error_1.getContext)(this.up()) + ": DTD system"
  129. + (" identifier \"" + sysId + "\" should not contain")
  130. + " characters not allowed in XML");
  131. }
  132. else if (this._validation
  133. && sysId.indexOf("'") !== -1
  134. && sysId.indexOf("\"") !== -1) {
  135. throw new Error((0, error_1.getContext)(this.up()) + ": DTD system"
  136. + (" identifier \"" + sysId + "\" should not contain")
  137. + " both single quotes and double quotes");
  138. }
  139. }
  140. this._sysId = sysId;
  141. },
  142. enumerable: false,
  143. configurable: true
  144. });
  145. /**
  146. * Adds an attribute-list declaration to this document type declaration
  147. * and returns the new attribute-list declaration.
  148. */
  149. XmlDtd.prototype.attlist = function (options) {
  150. var attlist = new XmlDtdAttlist_1.default(this, this._validation, options);
  151. this._children.push(attlist);
  152. return attlist;
  153. };
  154. /**
  155. * Adds a comment to this document type declaration and returns the
  156. * new comment.
  157. */
  158. XmlDtd.prototype.comment = function (options) {
  159. var comment = new XmlComment_1.default(this, this._validation, options);
  160. this._children.push(comment);
  161. return comment;
  162. };
  163. /**
  164. * Adds an element declaration to this document type declaration
  165. * and returns the new element declaration.
  166. */
  167. XmlDtd.prototype.element = function (options) {
  168. var element = new XmlDtdElement_1.default(this, this._validation, options);
  169. this._children.push(element);
  170. return element;
  171. };
  172. /**
  173. * Adds an entity declaration to this document type declaration
  174. * and returns the new entity declaration.
  175. */
  176. XmlDtd.prototype.entity = function (options) {
  177. var entity = new XmlDtdEntity_1.default(this, this._validation, options);
  178. this._children.push(entity);
  179. return entity;
  180. };
  181. /**
  182. * Adds a notation declaration to this document type declaration
  183. * and returns the new notation declaration.
  184. */
  185. XmlDtd.prototype.notation = function (options) {
  186. var notation = new XmlDtdNotation_1.default(this, this._validation, options);
  187. this._children.push(notation);
  188. return notation;
  189. };
  190. /**
  191. * Adds a parameter entity reference to this document type declaration
  192. * and returns the new parameter entity reference.
  193. */
  194. XmlDtd.prototype.paramEntityRef = function (options) {
  195. var paramEntity = new XmlDtdParamEntityRef_1.default(this, this._validation, options);
  196. this._children.push(paramEntity);
  197. return paramEntity;
  198. };
  199. /**
  200. * Adds a processing instruction to this document type declaration
  201. * and returns the new processing instruction.
  202. */
  203. XmlDtd.prototype.procInst = function (options) {
  204. var procInst = new XmlProcInst_1.default(this, this._validation, options);
  205. this._children.push(procInst);
  206. return procInst;
  207. };
  208. /**
  209. * Returns an XML string representation of this document type declaration.
  210. */
  211. XmlDtd.prototype.toString = function (options) {
  212. if (options === void 0) { options = {}; }
  213. var optionsObj = new options_1.StringOptions(options);
  214. var str = "<!DOCTYPE " + this._name;
  215. if ((0, validate_1.isUndefined)(this._pubId)) {
  216. if (!(0, validate_1.isUndefined)(this._sysId)) {
  217. str += " ";
  218. str = this.appendId("SYSTEM", this._sysId, str, optionsObj);
  219. }
  220. }
  221. else {
  222. if ((0, validate_1.isUndefined)(this._sysId)) {
  223. throw new Error((0, error_1.getContext)(this.up()) + ": DTD system"
  224. + " identifier is not undefined");
  225. }
  226. str += " ";
  227. str = this.appendId("PUBLIC", this._pubId, str, optionsObj);
  228. str = this.appendId("", this._sysId, str, optionsObj);
  229. }
  230. if (this._children.length !== 0) {
  231. str += " [";
  232. for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
  233. var node = _a[_i];
  234. if (optionsObj.pretty) {
  235. str += optionsObj.newline + optionsObj.indent;
  236. }
  237. str += node.toString();
  238. }
  239. if (optionsObj.pretty) {
  240. str += optionsObj.newline;
  241. }
  242. str += "]>";
  243. }
  244. else {
  245. str += ">";
  246. }
  247. return str;
  248. };
  249. /**
  250. * Returns the parent of this attribute.
  251. */
  252. XmlDtd.prototype.up = function () {
  253. return this._parent;
  254. };
  255. /**
  256. * Appends the XML string representation of a public or system identifier
  257. * to an existing string.
  258. */
  259. XmlDtd.prototype.appendId = function (type, value, str, options) {
  260. str += type + " ";
  261. if (options.doubleQuotes) {
  262. if (this._validation && value.indexOf("\"") !== -1) {
  263. throw new Error((0, error_1.getContext)(this.up()) + ": doubleQuotes option"
  264. + " inconsistent with DTD system identifier or"
  265. + " public identifier");
  266. }
  267. str += "\"" + value + "\"";
  268. }
  269. else {
  270. if (this._validation && value.indexOf("'") !== -1) {
  271. throw new Error((0, error_1.getContext)(this) + ": doubleQuotes option"
  272. + " inconsistent with DTD system identifier or"
  273. + " public identifier");
  274. }
  275. str += "'" + value + "'";
  276. }
  277. return str;
  278. };
  279. return XmlDtd;
  280. }());
  281. exports.default = XmlDtd;
  282. /**
  283. * Returns true if the specified public identifier only contains characters
  284. * permitted by the XML specification.
  285. */
  286. function validatePubId(str) {
  287. for (var i = 0; i < str.length; i++) {
  288. var char = str.charCodeAt(i);
  289. if (char === 0xA
  290. || char === 0xD
  291. || char === 0x20
  292. || char === 0x21
  293. || (char >= 0x23 && char <= 0x25)
  294. || (char >= 0x27 && char <= 0x2F)
  295. || (char >= 0x30 && char <= 0x39)
  296. || char === 0x3A
  297. || char === 0x3B
  298. || char === 0x3D
  299. || char === 0x3F
  300. || (char >= 0x40 && char <= 0x5A)
  301. || char === 0x5F
  302. || (char >= 0x61 && char <= 0x7A)) {
  303. continue;
  304. }
  305. if (i + 1 === str.length) {
  306. return false;
  307. }
  308. return false;
  309. }
  310. return true;
  311. }
  312. exports.validatePubId = validatePubId;