JavaScript generic ASN.1 parser (mirror)
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Convert max content length from a global constant to a passed value. Improve quantity and style of content shown on the DOM.

+76 -40
+48 -35
asn1.js
··· 18 18 (function (undefined) { 19 19 "use strict"; 20 20 21 - var hardLimit = 100, 22 - ellipsis = "\u2026"; 21 + var ellipsis = "\u2026", 22 + reTime = /^((?:1[89]|2\d)?\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; 23 + 24 + function stringCut(str, len) { 25 + if (str.length > len) 26 + str = str.substring(0, len) + ellipsis; 27 + return str; 28 + } 23 29 24 30 function Stream(enc, pos) { 25 31 if (enc instanceof Stream) { ··· 54 60 } 55 61 return s; 56 62 }; 63 + Stream.prototype.isASCII = function (start, end) { 64 + for (var i = start; i < end; ++i) { 65 + var c = this.get(i); 66 + if (c < 32 || c > 176) 67 + return false; 68 + } 69 + return true; 70 + }; 57 71 Stream.prototype.parseStringISO = function (start, end) { 58 72 var s = ""; 59 73 for (var i = start; i < end; ++i) ··· 82 96 } 83 97 return str; 84 98 }; 85 - Stream.prototype.reTime = /^((?:1[89]|2\d)?\d\d)(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])([01]\d|2[0-3])(?:([0-5]\d)(?:([0-5]\d)(?:[.,](\d{1,3}))?)?)?(Z|[-+](?:[0]\d|1[0-2])([0-5]\d)?)?$/; 86 99 Stream.prototype.parseTime = function (start, end) { 87 100 var s = this.parseStringISO(start, end), 88 - m = this.reTime.exec(s); 101 + m = reTime.exec(s); 89 102 if (!m) 90 103 return "Unrecognized time: " + s; 91 104 s = m[1] + "-" + m[2] + "-" + m[3] + " " + m[4]; ··· 127 140 n = (n * 256) + this.get(i); 128 141 return n; 129 142 }; 130 - Stream.prototype.parseBitString = function (start, end) { 143 + Stream.prototype.parseBitString = function (start, end, maxLength) { 131 144 var unusedBit = this.get(start), 132 145 lenBit = ((end - start - 1) << 3) - unusedBit, 133 - s = "(" + lenBit + " bit)"; 134 - if (lenBit <= 20) { 135 - var skip = unusedBit; 136 - s += " "; 137 - for (var i = end - 1; i > start; --i) { 138 - var b = this.get(i); 139 - for (var j = skip; j < 8; ++j) 140 - s += (b >> j) & 1 ? "1" : "0"; 141 - skip = 0; 142 - } 146 + s = "(" + lenBit + " bit)\n", 147 + skip = unusedBit; 148 + for (var i = end - 1; i > start; --i) { 149 + var b = this.get(i); 150 + for (var j = skip; j < 8; ++j) 151 + s += (b >> j) & 1 ? "1" : "0"; 152 + skip = 0; 153 + if (s.length > maxLength) 154 + return stringCut(s, maxLength); 143 155 } 144 156 return s; 145 157 }; 146 - Stream.prototype.parseOctetString = function (start, end) { 158 + Stream.prototype.parseOctetString = function (start, end, maxLength) { 159 + if (this.isASCII(start, end)) 160 + return stringCut(this.parseStringISO(start, end), maxLength); 147 161 var len = end - start, 148 - s = "(" + len + " byte) "; 149 - if (len > hardLimit) 150 - end = start + hardLimit; 162 + s = "(" + len + " byte)\n"; 163 + maxLength /= 2; // we work in bytes 164 + if (len > maxLength) 165 + end = start + maxLength; 151 166 for (var i = start; i < end; ++i) 152 167 s += this.hexByte(this.get(i)); //TODO: also try Latin1? 153 - if (len > hardLimit) 168 + if (len > maxLength) 154 169 s += ellipsis; 155 170 return s; 156 171 }; 157 - Stream.prototype.parseOID = function (start, end) { 172 + Stream.prototype.parseOID = function (start, end, maxLength) { 158 173 var s = '', 159 174 n = 0, 160 175 bits = 0; ··· 169 184 } else 170 185 s += "." + ((bits > 53) ? "bigint" : n); 171 186 n = bits = 0; 187 + if (s.length > maxLength) 188 + return stringCut(s, maxLength); 172 189 } 173 190 } 174 191 if (bits > 0) ··· 222 239 case 3: return "Private_" + this.tag.tagNumber.toString(16); 223 240 } 224 241 }; 225 - ASN1.prototype.reSeemsASCII = /^[ -~]+$/; 226 - ASN1.prototype.content = function () { 242 + ASN1.prototype.content = function (maxLength) { // a preview of the content (intended for humans) 227 243 if (this.tag === undefined) 228 244 return null; 245 + if (maxLength === undefined) 246 + maxLength = Infinity; 229 247 var content = this.posContent(), 230 248 len = Math.abs(this.length); 231 249 if (!this.tag.isUniversal()) { 232 250 if (this.sub !== null) 233 251 return "(" + this.sub.length + " elem)"; 234 - //TODO: TRY TO PARSE ASCII STRING 235 - var s = this.stream.parseStringISO(content, content + Math.min(len, hardLimit)); 236 - if (this.reSeemsASCII.test(s)) 237 - return s.substring(0, 2 * hardLimit) + ((s.length > 2 * hardLimit) ? ellipsis : ""); 238 - else 239 - return this.stream.parseOctetString(content, content + len); 252 + return this.stream.parseOctetString(content, content + len, maxLength); 240 253 } 241 254 switch (this.tag.tagNumber) { 242 255 case 0x01: // BOOLEAN ··· 245 258 return this.stream.parseInteger(content, content + len); 246 259 case 0x03: // BIT_STRING 247 260 return this.sub ? "(" + this.sub.length + " elem)" : 248 - this.stream.parseBitString(content, content + len); 261 + this.stream.parseBitString(content, content + len, maxLength); 249 262 case 0x04: // OCTET_STRING 250 263 return this.sub ? "(" + this.sub.length + " elem)" : 251 - this.stream.parseOctetString(content, content + len); 264 + this.stream.parseOctetString(content, content + len, maxLength); 252 265 //case 0x05: // NULL 253 266 case 0x06: // OBJECT_IDENTIFIER 254 - return this.stream.parseOID(content, content + len); 267 + return this.stream.parseOID(content, content + len, maxLength); 255 268 //case 0x07: // ObjectDescriptor 256 269 //case 0x08: // EXTERNAL 257 270 //case 0x09: // REAL ··· 261 274 case 0x11: // SET 262 275 return "(" + this.sub.length + " elem)"; 263 276 case 0x0C: // UTF8String 264 - return this.stream.parseStringUTF(content, content + len); 277 + return stringCut(this.stream.parseStringUTF(content, content + len), maxLength); 265 278 case 0x12: // NumericString 266 279 case 0x13: // PrintableString 267 280 case 0x14: // TeletexString ··· 271 284 case 0x1A: // VisibleString 272 285 //case 0x1B: // GeneralString 273 286 //case 0x1C: // UniversalString 274 - return this.stream.parseStringISO(content, content + len); 287 + return stringCut(this.stream.parseStringISO(content, content + len), maxLength); 275 288 case 0x1E: // BMPString 276 - return this.stream.parseStringBMP(content, content + len); 289 + return stringCut(this.stream.parseStringBMP(content, content + len), maxLength); 277 290 case 0x17: // UTCTime 278 291 case 0x18: // GeneralizedTime 279 292 return this.stream.parseTime(content, content + len);
+28 -5
dom.js
··· 18 18 (function (undefined) { 19 19 "use strict"; 20 20 21 - var DOM = { 21 + var lineLength = 80, 22 + contentLength = 8 * lineLength, 23 + DOM = { 24 + ellipsis: "\u2026", 22 25 tag: function (tagName, className) { 23 26 var t = document.createElement(tagName); 24 27 t.className = className; ··· 26 29 }, 27 30 text: function (str) { 28 31 return document.createTextNode(str); 32 + }, 33 + breakLines: function (str, length) { 34 + var lines = str.split(/\r?\n/), 35 + o = ''; 36 + for (var i = 0; i < lines.length; ++i) { 37 + var line = lines[i]; 38 + if (i > 0) o += "\n"; 39 + while (line.length > length) { 40 + o += line.substring(0, length); 41 + o += "\n"; 42 + line = line.substring(length); 43 + } 44 + o += line; 45 + } 46 + return o; 29 47 } 30 48 }; 31 49 ··· 35 53 var head = DOM.tag("div", "head"); 36 54 var s = this.typeName().replace(/_/g, " "); 37 55 head.innerHTML = s; 38 - var content = this.content(); 56 + var content = this.content(contentLength); 39 57 if (content !== null) { 40 - content = String(content).replace(/</g, "&lt;"); 41 - var preview = DOM.tag("span", "preview"); 42 - preview.appendChild(DOM.text(content)); 58 + var preview = DOM.tag("span", "preview"), 59 + shortContent; 60 + content = String(content); // it might be a number 61 + shortContent = (content.length > lineLength) ? content.substring(0, lineLength) + DOM.ellipsis : content; 62 + preview.appendChild(DOM.text(shortContent)); 43 63 head.appendChild(preview); 64 + content = DOM.breakLines(content, lineLength); 65 + content = content.replace(/</g, "&lt;"); 66 + content = content.replace(/\n/g, "<br/>"); 44 67 } 45 68 node.appendChild(head); 46 69 this.node = node;