styled-exceljs 0.21.2 → 0.21.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -157,10 +157,10 @@ var DO_NOT_EXPORT_CODEPAGE = true;
157
157
  /*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
158
158
  /* vim: set ts=2: */
159
159
  /*exported XLSX */
160
- /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false */
160
+ /*global global, exports, module, require:false, process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false, Set:false, Float32Array:false, Int8Array:false */
161
161
  var XLSX = {};
162
162
  function make_xlsx_lib(XLSX){
163
- XLSX.version = '0.21.2';
163
+ XLSX.version = '0.21.3';
164
164
  var current_codepage = 1200, current_ansi = 1252;
165
165
  /*global cptable:true, window */
166
166
  var $cptable;
@@ -314,9 +314,9 @@ function Base64_decode(input) {
314
314
  var o = "";
315
315
  var c1 = 0, c2 = 0, c3 = 0, e1 = 0, e2 = 0, e3 = 0, e4 = 0;
316
316
  if (input.slice(0, 5) == "data:") {
317
- var i = input.slice(0, 1024).indexOf(";base64,");
318
- if (i > -1)
319
- input = input.slice(i + 8);
317
+ var sep = input.slice(0, 1024).indexOf(";base64,");
318
+ if (sep > -1)
319
+ input = input.slice(sep + 8);
320
320
  }
321
321
  input = input.replace(/[^\w\+\/\=]/g, "");
322
322
  for (var i = 0; i < input.length; ) {
@@ -3388,7 +3388,7 @@ function blobify(data) {
3388
3388
  }
3389
3389
  /* write or download file */
3390
3390
  function write_dl(fname, payload, enc) {
3391
- /*global IE_SaveFile, Blob, navigator, saveAs, document, File, chrome */
3391
+ /*global IE_SaveFile, navigator, saveAs, document, chrome */
3392
3392
  if(typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
3393
3393
  if(typeof Deno !== 'undefined') {
3394
3394
  /* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
@@ -4036,6 +4036,19 @@ function escapexlml(text){
4036
4036
  return s.replace(decregex, function(y) { return rencoding[y]; }).replace(htmlcharegex,function(s) { return "&#x" + (s.charCodeAt(0).toString(16)).toUpperCase() + ";"; });
4037
4037
  }
4038
4038
 
4039
+ /* Extract text from XML fragments in linear time. This is a parser helper,
4040
+ * not an HTML sanitizer: text is escaped separately at HTML output boundaries. */
4041
+ function strip_xml_tags(text) {
4042
+ var str = String(text), out = [], inTag = false;
4043
+ for(var i = 0; i < str.length; ++i) {
4044
+ var cc = str.charCodeAt(i);
4045
+ if(!inTag && cc == 60 /* < */) inTag = true;
4046
+ else if(inTag && cc == 62 /* > */) inTag = false;
4047
+ else if(!inTag) out.push(str.charAt(i));
4048
+ }
4049
+ return out.join("");
4050
+ }
4051
+
4039
4052
  /* TODO: handle codepages */
4040
4053
  var xlml_fixstr = (function() {
4041
4054
  var entregex = /&#(\d+);/g;
@@ -4142,8 +4155,8 @@ var htmldecode = (function() {
4142
4155
  .replace(/[\t\n\r ]+/g, " ")
4143
4156
  // Replace <br> tags with new lines
4144
4157
  .replace(/<\s*[bB][rR]\s*\/?>/g,"\n")
4145
- // Strip HTML elements
4146
- .replace(/<[^<>]*>/g,"");
4158
+ ;
4159
+ o = strip_xml_tags(o);
4147
4160
  for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
4148
4161
  return o;
4149
4162
  };
@@ -4714,9 +4727,25 @@ function format_cell(cell, v, o) {
4714
4727
  return safe_format_cell(cell, v);
4715
4728
  }
4716
4729
 
4730
+ /* Worksheet names are document-controlled. A normal object treats
4731
+ * "__proto__" as a setter, so all workbook sheet maps must use an own-property
4732
+ * preserving dictionary and all lookups must reject inherited properties. */
4733
+ function sheet_map_new() {
4734
+ return Object.create ? Object.create(null) : {};
4735
+ }
4736
+ function sheet_map_set(sheets, name, sheet) {
4737
+ if(name == "__proto__" && Object.defineProperty) Object.defineProperty(sheets, name, {
4738
+ value: sheet, configurable: true, enumerable: true, writable: true
4739
+ });
4740
+ else sheets[name] = sheet;
4741
+ }
4742
+ function sheet_map_get(sheets, name) {
4743
+ return sheets != null && Object.prototype.hasOwnProperty.call(sheets, name) ? sheets[name] : void 0;
4744
+ }
4745
+
4717
4746
  function sheet_to_workbook(sheet, opts) {
4718
4747
  var n = opts && opts.sheet ? opts.sheet : "Sheet1";
4719
- var sheets = {}; sheets[n] = sheet;
4748
+ var sheets = sheet_map_new(); sheet_map_set(sheets, n, sheet);
4720
4749
  return { SheetNames: [n], Sheets: sheets };
4721
4750
  }
4722
4751
 
@@ -6389,8 +6418,8 @@ function parse_TypedPropertyValue(blob, type, _opts) {
6389
6418
  case 0x03 /*VT_I4*/: ret = blob.read_shift(4, 'i'); return ret;
6390
6419
  case 0x0B /*VT_BOOL*/: return blob.read_shift(4) !== 0x0;
6391
6420
  case 0x13 /*VT_UI4*/: ret = blob.read_shift(4); return ret;
6392
- case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
6393
- case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
6421
+ case 0x1E /*VT_LPSTR*/: blob.l += 4; return parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1");
6422
+ case 0x1F /*VT_LPWSTR*/: blob.l += 4; return parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1");
6394
6423
  case 0x40 /*VT_FILETIME*/: return parse_FILETIME(blob);
6395
6424
  case 0x41 /*VT_BLOB*/: return parse_BLOB(blob);
6396
6425
  case 0x47 /*VT_CF*/: return parse_ClipboardData(blob);
@@ -6899,7 +6928,6 @@ function parse_LongRGBA(blob) { var r = blob.read_shift(1), g = blob.read_shift(
6899
6928
  /* 2.5.177 LongRGB */
6900
6929
  function parse_LongRGB(blob, length) { var x = parse_LongRGBA(blob, length); x[3] = 0; return x; }
6901
6930
 
6902
-
6903
6931
  /* [MS-XLS] 2.5.19 */
6904
6932
  function parse_XLSCell(blob, length, opts) {
6905
6933
  var rw = blob.read_shift(2); // 0-indexed
@@ -8361,7 +8389,7 @@ function dbf_to_workbook(buf, opts) {
8361
8389
  o.bookType = "dbf";
8362
8390
  return o;
8363
8391
  } catch(e) { if(opts && opts.WTF) throw e; }
8364
- return ({SheetNames:[],Sheets:{}});
8392
+ return ({SheetNames:[],Sheets:sheet_map_new()});
8365
8393
  }
8366
8394
 
8367
8395
  var _RLEN = { 'B': 8, 'C': 250, 'L': 1, 'D': 8, '?': 0, '': 0 };
@@ -9257,7 +9285,7 @@ function read_wb_TABL(d, opts) {
9257
9285
  try {
9258
9286
  var out = DIF.to_workbook(d, o);
9259
9287
  if(!out || !out.Sheets) throw "DIF bad workbook";
9260
- var ws = out.Sheets[out.SheetNames[0]];
9288
+ var ws = sheet_map_get(out.Sheets, out.SheetNames[0]);
9261
9289
  if(!ws || !ws["!ref"]) throw "DIF empty worksheet";
9262
9290
  o.WTF = OLD_WTF;
9263
9291
  return out;
@@ -9313,7 +9341,7 @@ var WK_ = (function() {
9313
9341
  var o = opts || {};
9314
9342
  if(DENSE != null && o.dense == null) o.dense = DENSE;
9315
9343
  var s = ({}), n = "Sheet1", next_n = "", sidx = 0;
9316
- var sheets = {}, snames = [], realnames = [], sdata = [];
9344
+ var sheets = sheet_map_new(), snames = [], realnames = [], sdata = [];
9317
9345
  if(o.dense) sdata = s["!data"] = [];
9318
9346
 
9319
9347
  var refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
@@ -9358,7 +9386,7 @@ var WK_ = (function() {
9358
9386
  if(o.qpro) {
9359
9387
  if(val[3] > sidx) {
9360
9388
  s["!ref"] = encode_range(refguess);
9361
- sheets[n] = s;
9389
+ sheet_map_set(sheets, n, s);
9362
9390
  snames.push(n);
9363
9391
  s = ({}); if(o.dense) sdata = s["!data"] = [];
9364
9392
  refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
@@ -9409,7 +9437,7 @@ var WK_ = (function() {
9409
9437
  case 0x28: /* FORMULA28 */
9410
9438
  if(val[3] > sidx) {
9411
9439
  s["!ref"] = encode_range(refguess);
9412
- sheets[n] = s;
9440
+ sheet_map_set(sheets, n, s);
9413
9441
  snames.push(n);
9414
9442
  s = ({}); if(o.dense) sdata = s["!data"] = [];
9415
9443
  refguess = {s: {r:0, c:0}, e: {r:0, c:0} };
@@ -9432,17 +9460,17 @@ var WK_ = (function() {
9432
9460
  }}, o);
9433
9461
  } else throw new Error("Unrecognized LOTUS BOF " + d[2]);
9434
9462
  s["!ref"] = encode_range(refguess);
9435
- sheets[next_n || n] = s;
9463
+ sheet_map_set(sheets, next_n || n, s);
9436
9464
  snames.push(next_n || n);
9437
9465
  if(!realnames.length) return { SheetNames: snames, Sheets: sheets };
9438
- var osheets = {}, rnames = [];
9466
+ var osheets = sheet_map_new(), rnames = [];
9439
9467
  /* TODO: verify no collisions */
9440
- for(var i = 0; i < realnames.length; ++i) if(sheets[snames[i]]) {
9468
+ for(var i = 0; i < realnames.length; ++i) if(sheet_map_get(sheets, snames[i])) {
9441
9469
  rnames.push(realnames[i] || snames[i]);
9442
- osheets[realnames[i]] = sheets[realnames[i]] || sheets[snames[i]];
9470
+ sheet_map_set(osheets, realnames[i] || snames[i], sheet_map_get(sheets, realnames[i]) || sheet_map_get(sheets, snames[i]));
9443
9471
  } else {
9444
9472
  rnames.push(realnames[i]);
9445
- osheets[realnames[i]] = ({ "!ref": "A1" });
9473
+ sheet_map_set(osheets, realnames[i], ({ "!ref": "A1" }));
9446
9474
  }
9447
9475
  return { SheetNames: rnames, Sheets: osheets };
9448
9476
  }
@@ -9496,11 +9524,11 @@ var WK_ = (function() {
9496
9524
 
9497
9525
  write_biff_rec(ba, 0x00, write_BOF_WK3(wb));
9498
9526
 
9499
- for(var i = 0, cnt = 0; i < wb.SheetNames.length; ++i) if((wb.Sheets[wb.SheetNames[i]] || {})["!ref"]) write_biff_rec(ba, 0x1b, write_XFORMAT_SHEETNAME(wb.SheetNames[i], cnt++));
9527
+ for(var i = 0, cnt = 0; i < wb.SheetNames.length; ++i) if((sheet_map_get(wb.Sheets, wb.SheetNames[i]) || {})["!ref"]) write_biff_rec(ba, 0x1b, write_XFORMAT_SHEETNAME(wb.SheetNames[i], cnt++));
9500
9528
 
9501
9529
  var wsidx = 0;
9502
9530
  for(i = 0; i < wb.SheetNames.length; ++i) {
9503
- var ws = wb.Sheets[wb.SheetNames[i]];
9531
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
9504
9532
  if(!ws || !ws["!ref"]) continue;
9505
9533
  var range = safe_decode_range(ws["!ref"]);
9506
9534
  var dense = ws["!data"] != null;
@@ -9545,7 +9573,7 @@ var WK_ = (function() {
9545
9573
  var rows = 0, cols = 0, wscnt = 0;
9546
9574
  for(var i = 0; i < wb.SheetNames.length; ++i) {
9547
9575
  var name = wb.SheetNames[i];
9548
- var ws = wb.Sheets[name];
9576
+ var ws = sheet_map_get(wb.Sheets, name);
9549
9577
  if(!ws || !ws["!ref"]) continue;
9550
9578
  ++wscnt;
9551
9579
  var range = decode_range(ws["!ref"]);
@@ -10273,7 +10301,7 @@ var WK_ = (function() {
10273
10301
  var SST = [], sname = "", formulae = [];
10274
10302
  var range = {s:{r:-1,c:-1}, e:{r:-1,c:-1}};
10275
10303
  var cnt = 0, type = 0, C = 0, R = 0;
10276
- var wb = { SheetNames: [], Sheets: {} };
10304
+ var wb = { SheetNames: [], Sheets: sheet_map_new() };
10277
10305
  var FMTS = [];
10278
10306
  outer: while(d.l < d.length) {
10279
10307
  var RT = d.read_shift(2), length = d.read_shift(2);
@@ -10577,13 +10605,13 @@ var parse_rs = (function() {
10577
10605
 
10578
10606
  /* Parse a list of <r> tags */
10579
10607
  var rs_to_html = (function parse_rs_factory() {
10580
- var nlregex = /(\r\n|\n)/g;
10581
10608
  function parse_rpr2(font, intro, outro) {
10582
10609
  var style = [];
10583
10610
 
10584
10611
  if(font.u) style.push("text-decoration: underline;");
10585
- if(font.uval) style.push("text-underline-style:" + font.uval + ";");
10586
- if(font.sz) style.push("font-size:" + font.sz + "pt;");
10612
+ if(font.uval && /^(?:single|double|single-accounting|double-accounting)$/.test(font.uval)) style.push("text-underline-style:" + font.uval + ";");
10613
+ var sz = +font.sz;
10614
+ if(isFinite(sz) && sz > 0) style.push("font-size:" + Math.min(sz, 409) + "pt;");
10587
10615
  if(font.outline) style.push("text-effect: outline;");
10588
10616
  if(font.shadow) style.push("text-shadow: auto;");
10589
10617
  intro.push('<span style="' + style.join("") + '">');
@@ -10608,7 +10636,7 @@ var rs_to_html = (function parse_rs_factory() {
10608
10636
 
10609
10637
  if(r.s) parse_rpr2(r.s, terms[0], terms[2]);
10610
10638
 
10611
- return terms[0].join("") + terms[1].replace(nlregex,'<br/>') + terms[2].join("");
10639
+ return terms[0].join("") + escapehtml(terms[1]) + terms[2].join("");
10612
10640
  }
10613
10641
 
10614
10642
  return function parse_rs(rs) {
@@ -11342,6 +11370,15 @@ function style_font_family(style) {
11342
11370
  var font = style && style.font || {};
11343
11371
  return font.name || "Calibri";
11344
11372
  }
11373
+ function css_string_escape(value, quote) {
11374
+ var str = String(value), out = [];
11375
+ for(var i = 0; i < str.length; ++i) {
11376
+ var cc = str.charCodeAt(i), ch = str.charAt(i);
11377
+ if(ch == quote || ch == "\\" || cc < 32 || cc == 127 || ch == "<" || ch == ">" || ch == "&") out.push("\\" + cc.toString(16) + " ");
11378
+ else out.push(ch);
11379
+ }
11380
+ return out.join("");
11381
+ }
11345
11382
  function css_font_from_style(style) {
11346
11383
  var font = style && style.font || {};
11347
11384
  var parts = [];
@@ -11349,7 +11386,8 @@ function css_font_from_style(style) {
11349
11386
  if(font.bold) parts.push("bold");
11350
11387
  parts.push(style_font_size_pt(style) + "pt");
11351
11388
  var name = style_font_family(style);
11352
- if(/[,\s'"]/.test(name)) name = '"' + String(name).replace(/"/g, '\\"') + '"';
11389
+ if(/[,\s'"]/.test(name)) name = '"' + css_string_escape(name, '"') + '"';
11390
+ else name = css_string_escape(name, '"');
11353
11391
  parts.push(name);
11354
11392
  return parts.join(" ");
11355
11393
  }
@@ -13330,7 +13368,7 @@ function parse_drawing_anchor(data) {
13330
13368
  function parse_drawing_text(data) {
13331
13369
  var out = [];
13332
13370
  (data.match(/<a:t\b[^>]*>[\s\S]*?<\/a:t>/g)||[]).forEach(function(t) {
13333
- out.push(unescapexml(t.replace(/<[^>]*>/g, "")));
13371
+ out.push(unescapexml(strip_xml_tags(t)));
13334
13372
  });
13335
13373
  return out.join("");
13336
13374
  }
@@ -16710,7 +16748,25 @@ var mergecregex = /<(?:\w+:)?mergeCell ref=["'][A-Z0-9:]+['"]\s*[\/]?>/g;
16710
16748
  var hlinkregex = /<(?:\w+:)?hyperlink [^<>]*>/mg;
16711
16749
  var dimregex = /"(\w*:\w*)"/;
16712
16750
  var colregex = /<(?:\w+:)?col\b[^<>]*[\/]?>/g;
16713
- var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g;
16751
+ function match_ws_xml_autofilter(data) {
16752
+ var paired = str_match_xml_ns(data, "autoFilter");
16753
+ if(paired) return paired[0];
16754
+ var start = 0;
16755
+ while((start = data.indexOf("<", start)) != -1) {
16756
+ var end = data.indexOf(">", start + 1);
16757
+ if(end == -1) return null;
16758
+ var tag = data.slice(start + 1, end), p = 0;
16759
+ while(p < tag.length && tag.charCodeAt(p) <= 32) ++p;
16760
+ var nameEnd = p;
16761
+ while(nameEnd < tag.length && tag.charCodeAt(nameEnd) > 32 && tag.charAt(nameEnd) != "/") ++nameEnd;
16762
+ var name = tag.slice(p, nameEnd), colon = name.indexOf(":");
16763
+ if(colon != -1) name = name.slice(colon + 1);
16764
+ var tail = tag.slice(nameEnd).trim();
16765
+ if(name == "autoFilter" && tail.charAt(tail.length - 1) == "/") return data.slice(start, end + 1);
16766
+ start = end + 1;
16767
+ }
16768
+ return null;
16769
+ }
16714
16770
  var marginregex= /<(?:\w+:)?pageMargins[^<>]*\/>/g;
16715
16771
  var sheetprregex = /<(?:\w+:)?sheetPr\b[^<>]*?\/>/;
16716
16772
 
@@ -16759,8 +16815,8 @@ function parse_ws_xml(data, opts, idx, rels, wb, themes, styles) {
16759
16815
  if(mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles, wb);
16760
16816
 
16761
16817
  /* 18.3.1.2 autoFilter CT_AutoFilter */
16762
- var afilter = data2.match(afregex);
16763
- if(afilter) s['!autofilter'] = parse_ws_xml_autofilter(afilter[0]);
16818
+ var afilter = match_ws_xml_autofilter(data2);
16819
+ if(afilter) s['!autofilter'] = parse_ws_xml_autofilter(afilter);
16764
16820
 
16765
16821
  /* 18.3.1.55 mergeCells CT_MergeCells */
16766
16822
  var merges = [];
@@ -17285,7 +17341,7 @@ function write_ws_xml(idx, opts, wb, rels) {
17285
17341
  'xmlns:r': XMLNS.r
17286
17342
  })];
17287
17343
  var s = wb.SheetNames[idx], sidx = 0, rdata = "";
17288
- var ws = wb.Sheets[s];
17344
+ var ws = sheet_map_get(wb.Sheets, s);
17289
17345
  if(ws == null) ws = {};
17290
17346
  var ref = ws['!ref'] || 'A1';
17291
17347
  var range = safe_decode_range(ref);
@@ -18398,7 +18454,7 @@ function write_SHEETPROTECT(ba, ws) {
18398
18454
 
18399
18455
  function write_ws_bin(idx, opts, wb, rels) {
18400
18456
  var ba = buf_array();
18401
- var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
18457
+ var s = wb.SheetNames[idx], ws = sheet_map_get(wb.Sheets, s) || {};
18402
18458
  var c = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
18403
18459
  var r = safe_decode_range(ws['!ref'] || "A1");
18404
18460
  if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
@@ -18466,7 +18522,7 @@ function parse_Cache(data) {
18466
18522
  /* 21.2.2.71 formatCode CT_Xstring */
18467
18523
  var nf = unescapexml((str_match_xml(data, "c:formatCode") || ["","General"])[1]);
18468
18524
 
18469
- (str_match_ng(data, "<c:f>", "</c:f>")||[]).forEach(function(F) { f = F.replace(/<[^<>]*>/g,""); });
18525
+ (str_match_ng(data, "<c:f>", "</c:f>")||[]).forEach(function(F) { f = strip_xml_tags(F); });
18470
18526
 
18471
18527
  return [col, nf, f];
18472
18528
  }
@@ -18483,7 +18539,7 @@ function parse_chart_cache(data) {
18483
18539
  return {values:s[0], formatCode:s[1], formula:s[2]};
18484
18540
  }
18485
18541
  var f = (str_match_ng(data, "<c:f>", "</c:f>")||[])[0];
18486
- return {values:[], formula:f ? f.replace(/<[^<>]*>/g,"") : void 0};
18542
+ return {values:[], formula:f ? strip_xml_tags(f) : void 0};
18487
18543
  }
18488
18544
 
18489
18545
  function parse_chart_tx(data) {
@@ -18515,7 +18571,7 @@ function parse_chart_title(data) {
18515
18571
  var title = str_match_xml_ns(data, "title");
18516
18572
  if(!title) return "";
18517
18573
  var out = [];
18518
- (title[0].match(/<a:t\b[^>]*>[\s\S]*?<\/a:t>/g)||[]).forEach(function(t) { out.push(unescapexml(t.replace(/<[^>]*>/g, ""))); });
18574
+ (title[0].match(/<a:t\b[^>]*>[\s\S]*?<\/a:t>/g)||[]).forEach(function(t) { out.push(unescapexml(strip_xml_tags(t))); });
18519
18575
  return out.join("");
18520
18576
  }
18521
18577
 
@@ -18820,9 +18876,13 @@ function check_wb(wb) {
18820
18876
  if(!wb.SheetNames.length) throw new Error("Workbook is empty");
18821
18877
  var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
18822
18878
  check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
18823
- for(var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
18879
+ for(var i = 0; i < wb.SheetNames.length; ++i) {
18880
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
18881
+ if(!ws) throw new Error("Missing worksheet |" + wb.SheetNames[i] + "|");
18882
+ check_ws(ws, wb.SheetNames[i], i);
18883
+ }
18824
18884
  wb.SheetNames.forEach(function(n, i) {
18825
- var ws = wb.Sheets[n];
18885
+ var ws = sheet_map_get(wb.Sheets, n);
18826
18886
  if(!ws || !ws["!autofilter"]) return;
18827
18887
  var DN;
18828
18888
  if(!wb.Workbook) wb.Workbook = {};
@@ -19607,7 +19667,7 @@ function parse_xlml_data(xml, ss, data, cell, base, styles, csty, row, arrayf, o
19607
19667
  break;
19608
19668
  case 'String':
19609
19669
  cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml));
19610
- cell.v = (xml.indexOf("<") > -1 ? unescapexml(ss||xml).replace(/<[^<>]*>/g, "") : cell.r); // todo: BR etc
19670
+ cell.v = (xml.indexOf("<") > -1 ? strip_xml_tags(unescapexml(ss||xml)) : cell.r); // todo: BR etc
19611
19671
  break;
19612
19672
  case 'DateTime':
19613
19673
  if(xml.slice(-1) != "Z") xml += "Z";
@@ -19702,7 +19762,7 @@ function parse_xlml_xml(d, _opts) {
19702
19762
  var Rn;
19703
19763
  var state = [], tmp;
19704
19764
  if(DENSE != null && opts.dense == null) opts.dense = DENSE;
19705
- var sheets = {}, sheetnames = [], cursheet = ({}), sheetname = ""; if(opts.dense) cursheet["!data"] = [];
19765
+ var sheets = sheet_map_new(), sheetnames = [], cursheet = ({}), sheetname = ""; if(opts.dense) cursheet["!data"] = [];
19706
19766
  var cell = ({}), row = {};// eslint-disable-line no-unused-vars
19707
19767
  var dtag = xlml_parsexmltag('<Data ss:Type="String">'), didx = 0;
19708
19768
  var c = 0, r = 0;
@@ -19808,7 +19868,7 @@ for(var cma = c; cma <= cc; ++cma) {
19808
19868
  if(merges.length) cursheet["!merges"] = merges;
19809
19869
  if(cstys.length > 0) cursheet["!cols"] = cstys;
19810
19870
  if(rowinfo.length > 0) cursheet["!rows"] = rowinfo;
19811
- sheets[sheetname] = cursheet;
19871
+ sheet_map_set(sheets, sheetname, cursheet);
19812
19872
  } else {
19813
19873
  refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
19814
19874
  r = c = 0;
@@ -20709,7 +20769,7 @@ function write_ws_xlml_table(ws, opts, idx, wb) {
20709
20769
  function write_ws_xlml(idx, opts, wb) {
20710
20770
  var o = [];
20711
20771
  var s = wb.SheetNames[idx];
20712
- var ws = wb.Sheets[s];
20772
+ var ws = sheet_map_get(wb.Sheets, s);
20713
20773
 
20714
20774
  var t = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
20715
20775
  if(t.length > 0) o.push("<Names>" + t + "</Names>");
@@ -20941,7 +21001,7 @@ var parse_BIFFSurface = make_BIFFChartType("surfaceChart");
20941
21001
  // 2.3.2
20942
21002
  function parse_workbook(blob, options) {
20943
21003
  var wb = ({opts:{}});
20944
- var Sheets = {};
21004
+ var Sheets = sheet_map_new();
20945
21005
  if(DENSE != null && options.dense == null) options.dense = DENSE;
20946
21006
  var out = ({}); if(options.dense) out["!data"] = [];
20947
21007
  var Directory = {};
@@ -21382,7 +21442,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
21382
21442
  finalize_sheet_visuals(out);
21383
21443
  Workbook.Sheets.push(wsprops);
21384
21444
  }
21385
- if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
21445
+ if(cur_sheet === "") Preamble = out; else sheet_map_set(Sheets, cur_sheet, out);
21386
21446
  out = ({}); if(options.dense) out["!data"] = [];
21387
21447
  } break;
21388
21448
  case 0x0009: case 0x0209: case 0x0409: case 0x0809 /* BOF */: {
@@ -21681,10 +21741,13 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook";
21681
21741
  if(!wb.SheetNames.length && Preamble["!ref"]) {
21682
21742
  wb.SheetNames.push("Sheet1");
21683
21743
  /*jshint -W069 */
21684
- if(wb.Sheets) wb.Sheets["Sheet1"] = Preamble;
21744
+ if(wb.Sheets) sheet_map_set(wb.Sheets, "Sheet1", Preamble);
21685
21745
  /*jshint +W069 */
21686
21746
  } else wb.Preamble=Preamble;
21687
- if(wb.Sheets) FilterDatabases.forEach(function(r,i) { wb.Sheets[wb.SheetNames[i]]['!autofilter'] = r; });
21747
+ if(wb.Sheets) FilterDatabases.forEach(function(r,i) {
21748
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
21749
+ if(ws) ws['!autofilter'] = r;
21750
+ });
21688
21751
  wb.Strings = sst;
21689
21752
  wb.SSF = dup(table_fmt);
21690
21753
  if(opts.enc) wb.Encryption = opts.enc;
@@ -23309,7 +23372,7 @@ function write_biff2_buf(wb, opts) {
23309
23372
  o.cellXfs = [{numFmtId: 0}];
23310
23373
  o._BIFF2FmtTable = ["General"]; o._Fonts = [];
23311
23374
  var body = buf_array();
23312
- write_ws_biff2(body, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
23375
+ write_ws_biff2(body, sheet_map_get(wb.Sheets, wb.SheetNames[idx]), idx, o, wb);
23313
23376
 
23314
23377
  o._BIFF2FmtTable.forEach(function(f) {
23315
23378
  if(o.biff <= 3) write_biff_rec(ba, 0x001E, write_BIFF2Format(f));
@@ -23719,7 +23782,7 @@ function write_ws_biff8_cell(ba, cell, R, C, opts, date1904) {
23719
23782
  /* [MS-XLS] 2.1.7.20.5 */
23720
23783
  function write_ws_biff8(idx, opts, wb) {
23721
23784
  var ba = buf_array();
23722
- var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
23785
+ var s = wb.SheetNames[idx], ws = sheet_map_get(wb.Sheets, s) || {};
23723
23786
  var _WB = ((wb||{}).Workbook||{});
23724
23787
  var _sheet = ((_WB.Sheets||[])[idx]||{});
23725
23788
  var dense = ws["!data"] != null;
@@ -23918,7 +23981,7 @@ function write_biff8_buf(wb, opts) {
23918
23981
 
23919
23982
  function write_biff_buf(wb, opts) {
23920
23983
  for(var i = 0; i <= wb.SheetNames.length; ++i) {
23921
- var ws = wb.Sheets[wb.SheetNames[i]];
23984
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
23922
23985
  if(!ws || !ws["!ref"]) continue;
23923
23986
  var range = decode_range(ws["!ref"]);
23924
23987
  if(range.e.c > 255) { // note: 255 is IV
@@ -24000,15 +24063,66 @@ function html_to_sheet(str, _opts) {
24000
24063
  return ws;
24001
24064
  }
24002
24065
 
24003
- function cssesc(x) { return escapexml(String(x).replace(/"/g, "'")); }
24004
24066
  function css_color(color) {
24005
24067
  if(!color) return "";
24006
- if(color.rgb) return "#" + String(color.rgb).slice(-6);
24068
+ if(color.rgb && /^[0-9A-Fa-f]{6}(?:[0-9A-Fa-f]{2})?$/.test(String(color.rgb))) return "#" + String(color.rgb).slice(-6);
24007
24069
  return "";
24008
24070
  }
24009
24071
  function css_font_family(name) {
24010
24072
  if(!name) return "";
24011
- return "'" + cssesc(name).replace(/'/g, "\\'") + "'";
24073
+ return "'" + css_string_escape(name, "'") + "'";
24074
+ }
24075
+
24076
+ function html_attr_escape(value) {
24077
+ return String(value).replace(/[&<>"']/g, function(ch) {
24078
+ return ch == "&" ? "&amp;" : ch == "<" ? "&lt;" : ch == ">" ? "&gt;" : ch == '"' ? "&quot;" : "&#39;";
24079
+ });
24080
+ }
24081
+ function html_writextag(tag, content, attrs) {
24082
+ var out = ["<", tag];
24083
+ if(attrs) keys(attrs).forEach(function(key) { out.push(" ", key, '="', html_attr_escape(attrs[key]), '"'); });
24084
+ if(content == null) { out.push("/>"); return out.join(""); }
24085
+ out.push(">", content, "</", tag, ">");
24086
+ return out.join("");
24087
+ }
24088
+ function safe_html_href(value) {
24089
+ var href = String(value == null ? "" : value).trim();
24090
+ if(!href || href.slice(0, 2) == "//") return null;
24091
+ var colon = href.indexOf(":"), prefix = colon == -1 ? "" : href.slice(0, colon), compact = "";
24092
+ for(var i = 0; i < prefix.length; ++i) if(prefix.charCodeAt(i) > 32 && prefix.charCodeAt(i) != 127) compact += prefix.charAt(i);
24093
+ if(colon != -1 && !/^(?:https?|mailto|tel)$/i.test(compact)) return null;
24094
+ return href;
24095
+ }
24096
+ function safe_html_image_src(value) {
24097
+ var src = String(value == null ? "" : value);
24098
+ return /^data:image\/[A-Za-z0-9.+-]+;base64,[A-Za-z0-9+/=\r\n]+$/.test(src) ? src : null;
24099
+ }
24100
+ function sanitize_cell_html(value) {
24101
+ var html = String(value == null ? "" : value), out = [], pos = 0;
24102
+ while(pos < html.length) {
24103
+ var start = html.indexOf("<", pos);
24104
+ if(start == -1) { out.push(html.slice(pos)); break; }
24105
+ out.push(html.slice(pos, start));
24106
+ var end = html.indexOf(">", start + 1);
24107
+ if(end == -1) { out.push("&lt;", html.slice(start + 1)); break; }
24108
+ var raw = html.slice(start + 1, end).trim(), lower = raw.toLowerCase();
24109
+ if(/^(?:\/?(?:b|i|s|sup|sub)|br\s*\/?)$/.test(lower)) out.push("<", lower == "br" ? "br/" : lower, ">");
24110
+ else if(lower == "/span") out.push("</span>");
24111
+ else if(lower.slice(0, 12) == 'span style="' && raw.charAt(raw.length - 1) == '"') {
24112
+ var declarations = raw.slice(12, -1).split(";"), safe = [];
24113
+ declarations.forEach(function(decl) {
24114
+ var colon = decl.indexOf(":"), key = colon == -1 ? "" : decl.slice(0, colon).trim().toLowerCase(), val = colon == -1 ? "" : decl.slice(colon + 1).trim().toLowerCase();
24115
+ if(key == "text-decoration" && val == "underline") safe.push("text-decoration:underline");
24116
+ else if(key == "text-underline-style" && /^(?:single|double|single-accounting|double-accounting)$/.test(val)) safe.push("text-underline-style:" + val);
24117
+ else if(key == "font-size" && /^\d+(?:\.\d+)?pt$/.test(val)) safe.push("font-size:" + val);
24118
+ else if(key == "text-effect" && val == "outline") safe.push("text-effect:outline");
24119
+ else if(key == "text-shadow" && val == "auto") safe.push("text-shadow:auto");
24120
+ });
24121
+ out.push('<span style="', safe.join(";"), safe.length ? ";" : "", '">');
24122
+ } else out.push(html_attr_escape(html.slice(start, end + 1)));
24123
+ pos = end + 1;
24124
+ }
24125
+ return out.join("");
24012
24126
  }
24013
24127
  function html_border_style(style) {
24014
24128
  switch(style) {
@@ -24037,7 +24151,8 @@ function html_cell_style(cell, opts) {
24037
24151
  var s = cell.s, css = [];
24038
24152
  var font = s.font || {};
24039
24153
  if(font.name) css.push("font-family:" + css_font_family(font.name));
24040
- if(font.sz) css.push("font-size:" + font.sz + "pt");
24154
+ var fontSize = +font.sz;
24155
+ if(isFinite(fontSize) && fontSize > 0) css.push("font-size:" + Math.min(fontSize, 409) + "pt");
24041
24156
  if(font.bold) css.push("font-weight:bold");
24042
24157
  if(font.italic) css.push("font-style:italic");
24043
24158
  var deco = [];
@@ -24050,8 +24165,9 @@ function html_cell_style(cell, opts) {
24050
24165
  if(fill.patternType != "none" && fill.patternType != "gray125") fillColor = css_color(fill.fgColor) || css_color(fill.bgColor);
24051
24166
  if(fillColor) css.push("background-color:" + fillColor);
24052
24167
  var alignment = s.alignment || {};
24053
- if(alignment.horizontal) css.push("text-align:" + alignment.horizontal);
24054
- if(alignment.vertical) css.push("vertical-align:" + alignment.vertical);
24168
+ if(/^(?:left|right|center|justify|fill|distributed)$/.test(alignment.horizontal || "")) css.push("text-align:" + alignment.horizontal);
24169
+ var vertical = alignment.vertical == "center" ? "middle" : alignment.vertical;
24170
+ if(/^(?:top|middle|bottom|baseline)$/.test(vertical || "")) css.push("vertical-align:" + vertical);
24055
24171
  if(alignment.textRotation != null && alignment.textRotation !== 0) {
24056
24172
  var deg = alignment.textRotation == 255 ? 90 : alignment.textRotation > 90 ? 90 - alignment.textRotation : alignment.textRotation;
24057
24173
  css.push("transform:rotate(" + deg + "deg)");
@@ -24130,7 +24246,7 @@ function make_html_row(ws, r, R, o) {
24130
24246
  }
24131
24247
  }
24132
24248
  /* TODO: html entities */
24133
- var w = (cell && cell.v != null) && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
24249
+ var w = (cell && cell.v != null) && (cell.h ? sanitize_cell_html(cell.h) : escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
24134
24250
  sp = ({});
24135
24251
  if(RS > 1) sp.rowspan = RS;
24136
24252
  if(CS > 1) sp.colspan = CS;
@@ -24138,17 +24254,18 @@ function make_html_row(ws, r, R, o) {
24138
24254
  else if(cell) {
24139
24255
  sp["data-t"] = cell && cell.t || 'z';
24140
24256
  // note: data-v is unaffected by the timezone interpretation
24141
- if(cell.v != null) sp["data-v"] = escapehtml(cell.v instanceof Date ? cell.v.toISOString() : cell.v);
24257
+ if(cell.v != null) sp["data-v"] = cell.v instanceof Date ? cell.v.toISOString() : cell.v;
24142
24258
  if(cell.z != null) sp["data-z"] = cell.z;
24143
- if(cell.f != null) sp["data-f"] = escapehtml(cell.f);
24144
- if(cell.l && (cell.l.Target || "#").charAt(0) != "#" && (!o.sanitizeLinks || (cell.l.Target || "").slice(0, 11).toLowerCase() != 'javascript:')) w = '<a href="' + escapehtml(cell.l.Target) +'">' + w + '</a>';
24259
+ if(cell.f != null) sp["data-f"] = cell.f;
24260
+ var href = cell.l && safe_html_href(cell.l.Target);
24261
+ if(href) w = '<a href="' + html_attr_escape(href) +'">' + w + '</a>';
24145
24262
  }
24146
24263
  var cstyle = html_cell_style(stylecell, o);
24147
24264
  var lstyle = html_cell_layout_style(stylecell, o, C, CS, cols);
24148
24265
  if(lstyle) cstyle = cstyle ? cstyle + ";" + lstyle : lstyle;
24149
24266
  if(cstyle) sp.style = cstyle;
24150
24267
  sp.id = (o.id || "sjs") + "-" + coord;
24151
- oo.push(writextag('td', w, sp));
24268
+ oo.push(html_writextag('td', w, sp));
24152
24269
  }
24153
24270
  var rsp = ({}), rstyle = [];
24154
24271
  if(row) {
@@ -24156,7 +24273,7 @@ function make_html_row(ws, r, R, o) {
24156
24273
  if(o.browserPixels) rstyle.push("height:" + html_row_height(row) + "px");
24157
24274
  }
24158
24275
  if(rstyle.length) rsp.style = rstyle.join(";");
24159
- return writextag('tr', oo.join(""), rsp);
24276
+ return html_writextag('tr', oo.join(""), rsp);
24160
24277
  }
24161
24278
 
24162
24279
  var HTML_BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
@@ -24292,8 +24409,10 @@ function render_html_drawings(ws, opts) {
24292
24409
  var out = [], drawings = ws["!drawings"] || {}, charts = ws["!charts"] || [];
24293
24410
  if(opts && opts.drawings && drawings.images) drawings.images.forEach(function(img) {
24294
24411
  if(!img || !img.dataURI) return;
24412
+ var src = safe_html_image_src(img.dataURI);
24413
+ if(!src) return;
24295
24414
  var pos = html_anchor_pos(ws, img.anchor, opts);
24296
- out.push('<img class="sjs-drawing-image" src="' + img.dataURI + '" style="' + html_abs_style(pos) + '"/>');
24415
+ out.push('<img class="sjs-drawing-image" src="' + html_attr_escape(src) + '" style="' + html_abs_style(pos) + '"/>');
24297
24416
  });
24298
24417
  if(opts && opts.charts) charts.forEach(function(chart) {
24299
24418
  var pos = html_anchor_pos(ws, chart.anchor, opts);
@@ -24308,7 +24427,7 @@ function make_html_preamble(ws, R, o) {
24308
24427
  if(o && o.id) tattr.id = o.id;
24309
24428
  if(o && (o.browserPixels || o.autoFit)) tstyle.push("border-collapse:collapse;table-layout:fixed");
24310
24429
  if(tstyle.length) tattr.style = tstyle.join(";");
24311
- var table = writextag("table", "", tattr).replace(/<\/table>$/, "");
24430
+ var table = html_writextag("table", "", tattr).replace(/<\/table>$/, "");
24312
24431
  var cols = o && o._htmlCols || ws["!cols"];
24313
24432
  if(o && (o.browserPixels || o.autoFit) && cols) {
24314
24433
  out.push("<colgroup>");
@@ -24316,7 +24435,7 @@ function make_html_preamble(ws, R, o) {
24316
24435
  var col = cols[C], style = [];
24317
24436
  style.push("width:" + html_col_width(col) + "px");
24318
24437
  if(col && col.hidden) style.push("display:none");
24319
- out.push(writextag("col", null, {style:style.join(";")}));
24438
+ out.push(html_writextag("col", null, {style:style.join(";")}));
24320
24439
  }
24321
24440
  out.push("</colgroup>");
24322
24441
  }
@@ -24483,7 +24602,7 @@ function parse_text_p(text) {
24483
24602
  .replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1,10)+1).join(" "); })
24484
24603
  .replace(/<text:tab[^<>]*\/>/g,"\t")
24485
24604
  .replace(/<text:line-break\/>/g,"\n");
24486
- var v = unescapexml(fixed.replace(/<[^<>]*>/g,""));
24605
+ var v = unescapexml(strip_xml_tags(fixed));
24487
24606
 
24488
24607
  return [v];
24489
24608
  }
@@ -24720,7 +24839,7 @@ function parse_content_xml(d, _opts, _nfm) {
24720
24839
  var nfidx, NF = "", pidx = 0;
24721
24840
  var sheetag;
24722
24841
  var rowtag;
24723
- var Sheets = {}, SheetNames = [];
24842
+ var Sheets = sheet_map_new(), SheetNames = [];
24724
24843
  var ws = ({}); if(opts.dense) ws["!data"] = [];
24725
24844
  var Rn, q;
24726
24845
  var ctag = ({value:""}), ctag2 = ({});
@@ -24757,7 +24876,7 @@ function parse_content_xml(d, _opts, _nfm) {
24757
24876
  sheetag.name = sheetag['名称'] || sheetag.name;
24758
24877
  if(typeof JSON !== 'undefined') JSON.stringify(sheetag);
24759
24878
  SheetNames.push(sheetag.name);
24760
- Sheets[sheetag.name] = ws;
24879
+ sheet_map_set(Sheets, sheetag.name, ws);
24761
24880
  WB.Sheets.push({
24762
24881
  /* TODO: CodeName */
24763
24882
  Hidden: (tstyles[sheetag["style-name"]] && tstyles[sheetag["style-name"]]["display"] ? (parsexmlbool(tstyles[sheetag["style-name"]]["display"]) ? 0 : 1) : 0)
@@ -25113,7 +25232,9 @@ function parse_content_xml(d, _opts, _nfm) {
25113
25232
  if(Rn[1]==='/') break;
25114
25233
  try {
25115
25234
  _Ref = ods_to_csf_3D(parsexmltag(Rn[0])['target-range-address']);
25116
- Sheets[_Ref[0]]['!autofilter'] = { ref:_Ref[1] };
25235
+ if(Object.prototype.hasOwnProperty.call(Sheets, _Ref[0]) && Sheets[_Ref[0]]) {
25236
+ Sheets[_Ref[0]]['!autofilter'] = { ref:_Ref[1] };
25237
+ }
25117
25238
  } catch(e) {/* empty */}
25118
25239
  break;
25119
25240
 
@@ -25623,7 +25744,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25623
25744
 
25624
25745
  /* column styles */
25625
25746
  var cidx = 0;
25626
- wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
25747
+ wb.SheetNames.map(function(n) { return sheet_map_get(wb.Sheets, n); }).forEach(function(ws) {
25627
25748
  if(!ws) return;
25628
25749
  if(ws["!cols"]) {
25629
25750
  for(var C = 0; C < ws["!cols"].length; ++C) if(ws["!cols"][C]) {
@@ -25642,7 +25763,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25642
25763
 
25643
25764
  /* row styles */
25644
25765
  var ridx = 0;
25645
- wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
25766
+ wb.SheetNames.map(function(n) { return sheet_map_get(wb.Sheets, n); }).forEach(function(ws) {
25646
25767
  if(!ws) return;
25647
25768
  if(ws["!rows"]) {
25648
25769
  for(var R = 0; R < ws["!rows"].length; ++R) if(ws["!rows"][R]) {
@@ -25675,7 +25796,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25675
25796
  /* number formats, table cells, text */
25676
25797
  var nfs = {};
25677
25798
  var nfi = 69;
25678
- wb.SheetNames.map(function(n) { return wb.Sheets[n]; }).forEach(function(ws) {
25799
+ wb.SheetNames.map(function(n) { return sheet_map_get(wb.Sheets, n); }).forEach(function(ws) {
25679
25800
  if(!ws) return;
25680
25801
  var dense = (ws["!data"] != null);
25681
25802
  if(!ws["!ref"]) return;
@@ -25758,7 +25879,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25758
25879
  o.push(' <office:body>\n');
25759
25880
  o.push(' <office:spreadsheet>\n');
25760
25881
  if(((wb.Workbook||{}).WBProps||{}).date1904) o.push(' <table:calculation-settings table:case-sensitive="false" table:search-criteria-must-apply-to-whole-cell="true" table:use-wildcards="true" table:use-regular-expressions="false" table:automatic-find-labels="false">\n <table:null-date table:date-value="1904-01-01"/>\n </table:calculation-settings>\n');
25761
- for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts, nfs, ((wb.Workbook||{}).WBProps||{}).date1904));
25882
+ for(var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(sheet_map_get(wb.Sheets, wb.SheetNames[i]), wb, i, opts, nfs, ((wb.Workbook||{}).WBProps||{}).date1904));
25762
25883
  if((wb.Workbook||{}).Names) o.push(write_names_ods(wb.Workbook.Names, wb.SheetNames, -1));
25763
25884
  o.push(' </office:spreadsheet>\n');
25764
25885
  o.push(' </office:body>\n');
@@ -25810,7 +25931,6 @@ function write_ods(wb, opts) {
25810
25931
 
25811
25932
  return zip;
25812
25933
  }
25813
-
25814
25934
  /*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
25815
25935
  var subarray = function() {
25816
25936
  try {
@@ -27328,7 +27448,7 @@ function write_numbers_iwa(wb, opts) {
27328
27448
  docroot = numbers_iwa_find(cfb, deps, 1);
27329
27449
  sheetrefs = mappa(parse_shallow(docroot.messages[0].data)[1], parse_TSP_Reference);
27330
27450
  }
27331
- write_numbers_ws(cfb, deps, wb.Sheets[name], name, idx, sheetrefs[idx]);
27451
+ write_numbers_ws(cfb, deps, sheet_map_get(wb.Sheets, name), name, idx, sheetrefs[idx]);
27332
27452
  });
27333
27453
  return cfb;
27334
27454
  }
@@ -28246,7 +28366,7 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st
28246
28366
  case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
28247
28367
  default: throw new Error("Unrecognized sheet type " + stype);
28248
28368
  }
28249
- sheets[sheet] = _ws;
28369
+ sheet_map_set(sheets, sheet, _ws);
28250
28370
 
28251
28371
  /* scan rels for comments and threaded comments */
28252
28372
  var comments = [], tcomments = [];
@@ -28369,7 +28489,7 @@ function parse_zip(zip, opts) {
28369
28489
  if(opts.bookSheets && typeof sheets !== 'undefined') out.SheetNames = sheets;
28370
28490
  if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
28371
28491
  }
28372
- sheets = {};
28492
+ sheets = sheet_map_new();
28373
28493
 
28374
28494
  var deps = {};
28375
28495
  if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, strip_front_slash(dir.calcchain)),dir.calcchain,opts);
@@ -28569,7 +28689,7 @@ f = "docProps/app.xml";
28569
28689
 
28570
28690
  for(rId=1;rId <= wb.SheetNames.length; ++rId) {
28571
28691
  var wsrels = {'!id':{}};
28572
- var ws = wb.Sheets[wb.SheetNames[rId-1]];
28692
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[rId-1]);
28573
28693
  var _type = (ws || {})["!type"] || "sheet";
28574
28694
  switch(_type) {
28575
28695
  case "chart":
@@ -28724,7 +28844,7 @@ f = "docProps/app.xml";
28724
28844
 
28725
28845
  for(rId=1;rId <= wb.SheetNames.length; ++rId) {
28726
28846
  var wsrels = {'!id':{}};
28727
- var ws = wb.Sheets[wb.SheetNames[rId-1]];
28847
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[rId-1]);
28728
28848
  var _type = (ws || {})["!type"] || "sheet";
28729
28849
  switch(_type) {
28730
28850
  case "chart":
@@ -28820,7 +28940,6 @@ f = "docProps/app.xml";
28820
28940
  delete opts.revssf; delete opts.ssf;
28821
28941
  return zip;
28822
28942
  }
28823
-
28824
28943
  function firstbyte(f,o) {
28825
28944
  var x = "";
28826
28945
  switch((o||{}).type || "base64") {
@@ -29089,18 +29208,18 @@ function writeSync(wb, opts) {
29089
29208
  case 'xml':
29090
29209
  case 'xlml': return write_string_type(write_xlml(wb, o), o);
29091
29210
  case 'slk':
29092
- case 'sylk': return write_string_type(SYLK.from_sheet(wb.Sheets[wb.SheetNames[idx]], o, wb), o);
29211
+ case 'sylk': return write_string_type(SYLK.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o, wb), o);
29093
29212
  case 'htm':
29094
- case 'html': return write_string_type(sheet_to_html(wb.Sheets[wb.SheetNames[idx]], o), o);
29095
- case 'txt': return write_stxt_type(sheet_to_txt(wb.Sheets[wb.SheetNames[idx]], o), o);
29096
- case 'csv': return write_string_type(sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o), o, "\ufeff");
29097
- case 'dif': return write_string_type(DIF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29098
- case 'dbf': return write_binary_type(DBF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29099
- case 'prn': return write_string_type(PRN.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29100
- case 'rtf': return write_string_type(sheet_to_rtf(wb.Sheets[wb.SheetNames[idx]], o), o);
29101
- case 'eth': return write_string_type(ETH.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29213
+ case 'html': return write_string_type(sheet_to_html(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29214
+ case 'txt': return write_stxt_type(sheet_to_txt(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29215
+ case 'csv': return write_string_type(sheet_to_csv(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o, "\ufeff");
29216
+ case 'dif': return write_string_type(DIF.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29217
+ case 'dbf': return write_binary_type(DBF.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29218
+ case 'prn': return write_string_type(PRN.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29219
+ case 'rtf': return write_string_type(sheet_to_rtf(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29220
+ case 'eth': return write_string_type(ETH.from_sheet(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29102
29221
  case 'fods': return write_string_type(write_ods(wb, o), o);
29103
- case 'wk1': return write_binary_type(WK_.sheet_to_wk1(wb.Sheets[wb.SheetNames[idx]], o), o);
29222
+ case 'wk1': return write_binary_type(WK_.sheet_to_wk1(sheet_map_get(wb.Sheets, wb.SheetNames[idx]), o), o);
29104
29223
  case 'wk3': return write_binary_type(WK_.book_to_wk3(wb, o), o);
29105
29224
  case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
29106
29225
  case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
@@ -29360,6 +29479,7 @@ function sheet_add_json(_ws, js, opts) {
29360
29479
  var _origin = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
29361
29480
  _R = _origin.r; _C = _origin.c;
29362
29481
  }
29482
+ if(!isFinite(_R) || _R !== Math.floor(_R) || _R < -1 || !isFinite(_C) || _C !== Math.floor(_C) || _C < 0) throw new Error("Invalid origin");
29363
29483
  }
29364
29484
  var range = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}});
29365
29485
  if(ws['!ref']) {
@@ -29451,7 +29571,7 @@ function wb_sheet_idx(wb, sh) {
29451
29571
 
29452
29572
  /* simple blank or single-sheet workbook object */
29453
29573
  function book_new(ws, wsname) {
29454
- var wb = { SheetNames: [], Sheets: {} };
29574
+ var wb = { SheetNames: [], Sheets: sheet_map_new() };
29455
29575
  if(ws) book_append_sheet(wb, ws, wsname || "Sheet1");
29456
29576
  return wb;
29457
29577
  }
@@ -29471,7 +29591,7 @@ function book_append_sheet(wb, ws, name, roll) {
29471
29591
  if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!");
29472
29592
 
29473
29593
  wb.SheetNames.push(name);
29474
- wb.Sheets[name] = ws;
29594
+ sheet_map_set(wb.Sheets, name, ws);
29475
29595
  return name;
29476
29596
  }
29477
29597
 
@@ -29538,7 +29658,6 @@ function sheet_set_array_formula(ws, range, formula, dynamic) {
29538
29658
  ws["!ref"] = encode_range(wsr);
29539
29659
  return ws;
29540
29660
  }
29541
-
29542
29661
  var utils = {
29543
29662
  encode_col: encode_col,
29544
29663
  encode_row: encode_row,
@@ -29695,7 +29814,7 @@ function write_json_stream(sheet, opts) {
29695
29814
  if ((rowinfo[R]||{}).hidden) {
29696
29815
  ++R;
29697
29816
  continue;
29698
- };
29817
+ }
29699
29818
  var row = make_json_row(sheet, r, R, cols, header, hdr, o);
29700
29819
  ++R;
29701
29820
  if((row.isempty === false) || (header === 1 ? o.blankrows !== false : !!o.blankrows)) {
@@ -29724,7 +29843,7 @@ function write_xlml_stream(wb, o) {
29724
29843
 
29725
29844
  /* do one pass to determine styles since they must be added before tables */
29726
29845
  wb.SheetNames.forEach(function(n) {
29727
- var ws = wb.Sheets[n];
29846
+ var ws = sheet_map_get(wb.Sheets, n);
29728
29847
  if(!ws || !ws["!ref"]) return;
29729
29848
  var range = decode_range(ws["!ref"]);
29730
29849
  var dense = ws["!data"] != null;
@@ -29744,7 +29863,7 @@ function write_xlml_stream(wb, o) {
29744
29863
  });
29745
29864
  var sty = write_sty_xlml(wb, opts);
29746
29865
 
29747
- var stage = 0, wsidx = 0, ws = wb.Sheets[wb.SheetNames[wsidx]], range = safe_decode_range(ws), R = -1, T = false;
29866
+ var stage = 0, wsidx = 0, ws = sheet_map_get(wb.Sheets, wb.SheetNames[wsidx]), range = safe_decode_range(ws), R = -1, T = false;
29748
29867
 
29749
29868
  var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
29750
29869
 
@@ -29784,7 +29903,7 @@ function write_xlml_stream(wb, o) {
29784
29903
 
29785
29904
  stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
29786
29905
 
29787
- ws = wb.Sheets[wb.SheetNames[wsidx]];
29906
+ ws = sheet_map_get(wb.Sheets, wb.SheetNames[wsidx]);
29788
29907
  if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
29789
29908
 
29790
29909
  var names = write_ws_xlml_names(ws, opts, wsidx, wb);