styled-exceljs 0.21.1 → 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.1';
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) {
@@ -11266,7 +11294,7 @@ function resolve_style_obj_color(obj, themes) {
11266
11294
 
11267
11295
  /* 18.3.1.13 width calculations */
11268
11296
  /* [MS-OI29500] 2.1.595 Column Width & Formatting */
11269
- var DEF_MDW = 6, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
11297
+ var DEF_MDW = 7, MAX_MDW = 15, MIN_MDW = 1, MDW = DEF_MDW;
11270
11298
  function width2px(width) { return Math.floor(( width + (Math.round(128/MDW))/256 )* MDW ); }
11271
11299
  function px2char(px) { return (Math.floor((px - 5)/MDW * 100 + 0.5))/100; }
11272
11300
  function char2width(chr) { return (Math.round((chr * MDW + 5)/MDW*256))/256; }
@@ -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 = [];
@@ -16913,7 +16969,8 @@ function parse_ws_xml_cols(columns, cols) {
16913
16969
  var colm=parseInt(coll.min, 10)-1, colM=parseInt(coll.max,10)-1;
16914
16970
  if(coll.outlineLevel) coll.level = (+coll.outlineLevel || 0);
16915
16971
  delete coll.min; delete coll.max; coll.width = +coll.width;
16916
- if(!seencol && coll.width) { seencol = true; find_mdw_colw(coll.width); }
16972
+ /* OOXML widths share the workbook Normal-font MDW; do not infer a different scale per sheet. */
16973
+ if(!seencol && coll.width) { seencol = true; MDW = DEF_MDW; }
16917
16974
  process_col(coll);
16918
16975
  while(colm <= colM) columns[colm++] = dup(coll);
16919
16976
  }
@@ -17284,7 +17341,7 @@ function write_ws_xml(idx, opts, wb, rels) {
17284
17341
  'xmlns:r': XMLNS.r
17285
17342
  })];
17286
17343
  var s = wb.SheetNames[idx], sidx = 0, rdata = "";
17287
- var ws = wb.Sheets[s];
17344
+ var ws = sheet_map_get(wb.Sheets, s);
17288
17345
  if(ws == null) ws = {};
17289
17346
  var ref = ws['!ref'] || 'A1';
17290
17347
  var range = safe_decode_range(ref);
@@ -18083,7 +18140,7 @@ function parse_ws_bin(data, _opts, idx, rels, wb, themes, styles) {
18083
18140
  if(!opts.cellStyles) break;
18084
18141
  while(val.e >= val.s) {
18085
18142
  colinfo[val.e--] = { width: val.w/256, hidden: !!(val.flags & 0x01), level: val.level };
18086
- if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
18143
+ if(!seencol) { seencol = true; MDW = DEF_MDW; }
18087
18144
  process_col(colinfo[val.e+1]);
18088
18145
  }
18089
18146
  break;
@@ -18397,7 +18454,7 @@ function write_SHEETPROTECT(ba, ws) {
18397
18454
 
18398
18455
  function write_ws_bin(idx, opts, wb, rels) {
18399
18456
  var ba = buf_array();
18400
- var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
18457
+ var s = wb.SheetNames[idx], ws = sheet_map_get(wb.Sheets, s) || {};
18401
18458
  var c = s; try { if(wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c; } catch(e) {}
18402
18459
  var r = safe_decode_range(ws['!ref'] || "A1");
18403
18460
  if(r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
@@ -18465,7 +18522,7 @@ function parse_Cache(data) {
18465
18522
  /* 21.2.2.71 formatCode CT_Xstring */
18466
18523
  var nf = unescapexml((str_match_xml(data, "c:formatCode") || ["","General"])[1]);
18467
18524
 
18468
- (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); });
18469
18526
 
18470
18527
  return [col, nf, f];
18471
18528
  }
@@ -18482,7 +18539,7 @@ function parse_chart_cache(data) {
18482
18539
  return {values:s[0], formatCode:s[1], formula:s[2]};
18483
18540
  }
18484
18541
  var f = (str_match_ng(data, "<c:f>", "</c:f>")||[])[0];
18485
- return {values:[], formula:f ? f.replace(/<[^<>]*>/g,"") : void 0};
18542
+ return {values:[], formula:f ? strip_xml_tags(f) : void 0};
18486
18543
  }
18487
18544
 
18488
18545
  function parse_chart_tx(data) {
@@ -18514,7 +18571,7 @@ function parse_chart_title(data) {
18514
18571
  var title = str_match_xml_ns(data, "title");
18515
18572
  if(!title) return "";
18516
18573
  var out = [];
18517
- (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))); });
18518
18575
  return out.join("");
18519
18576
  }
18520
18577
 
@@ -18819,9 +18876,13 @@ function check_wb(wb) {
18819
18876
  if(!wb.SheetNames.length) throw new Error("Workbook is empty");
18820
18877
  var Sheets = (wb.Workbook && wb.Workbook.Sheets) || [];
18821
18878
  check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
18822
- 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
+ }
18823
18884
  wb.SheetNames.forEach(function(n, i) {
18824
- var ws = wb.Sheets[n];
18885
+ var ws = sheet_map_get(wb.Sheets, n);
18825
18886
  if(!ws || !ws["!autofilter"]) return;
18826
18887
  var DN;
18827
18888
  if(!wb.Workbook) wb.Workbook = {};
@@ -19606,7 +19667,7 @@ function parse_xlml_data(xml, ss, data, cell, base, styles, csty, row, arrayf, o
19606
19667
  break;
19607
19668
  case 'String':
19608
19669
  cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml));
19609
- 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
19610
19671
  break;
19611
19672
  case 'DateTime':
19612
19673
  if(xml.slice(-1) != "Z") xml += "Z";
@@ -19701,7 +19762,7 @@ function parse_xlml_xml(d, _opts) {
19701
19762
  var Rn;
19702
19763
  var state = [], tmp;
19703
19764
  if(DENSE != null && opts.dense == null) opts.dense = DENSE;
19704
- var sheets = {}, sheetnames = [], cursheet = ({}), sheetname = ""; if(opts.dense) cursheet["!data"] = [];
19765
+ var sheets = sheet_map_new(), sheetnames = [], cursheet = ({}), sheetname = ""; if(opts.dense) cursheet["!data"] = [];
19705
19766
  var cell = ({}), row = {};// eslint-disable-line no-unused-vars
19706
19767
  var dtag = xlml_parsexmltag('<Data ss:Type="String">'), didx = 0;
19707
19768
  var c = 0, r = 0;
@@ -19807,7 +19868,7 @@ for(var cma = c; cma <= cc; ++cma) {
19807
19868
  if(merges.length) cursheet["!merges"] = merges;
19808
19869
  if(cstys.length > 0) cursheet["!cols"] = cstys;
19809
19870
  if(rowinfo.length > 0) cursheet["!rows"] = rowinfo;
19810
- sheets[sheetname] = cursheet;
19871
+ sheet_map_set(sheets, sheetname, cursheet);
19811
19872
  } else {
19812
19873
  refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
19813
19874
  r = c = 0;
@@ -20708,7 +20769,7 @@ function write_ws_xlml_table(ws, opts, idx, wb) {
20708
20769
  function write_ws_xlml(idx, opts, wb) {
20709
20770
  var o = [];
20710
20771
  var s = wb.SheetNames[idx];
20711
- var ws = wb.Sheets[s];
20772
+ var ws = sheet_map_get(wb.Sheets, s);
20712
20773
 
20713
20774
  var t = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
20714
20775
  if(t.length > 0) o.push("<Names>" + t + "</Names>");
@@ -20940,7 +21001,7 @@ var parse_BIFFSurface = make_BIFFChartType("surfaceChart");
20940
21001
  // 2.3.2
20941
21002
  function parse_workbook(blob, options) {
20942
21003
  var wb = ({opts:{}});
20943
- var Sheets = {};
21004
+ var Sheets = sheet_map_new();
20944
21005
  if(DENSE != null && options.dense == null) options.dense = DENSE;
20945
21006
  var out = ({}); if(options.dense) out["!data"] = [];
20946
21007
  var Directory = {};
@@ -21381,7 +21442,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
21381
21442
  finalize_sheet_visuals(out);
21382
21443
  Workbook.Sheets.push(wsprops);
21383
21444
  }
21384
- if(cur_sheet === "") Preamble = out; else Sheets[cur_sheet] = out;
21445
+ if(cur_sheet === "") Preamble = out; else sheet_map_set(Sheets, cur_sheet, out);
21385
21446
  out = ({}); if(options.dense) out["!data"] = [];
21386
21447
  } break;
21387
21448
  case 0x0009: case 0x0209: case 0x0409: case 0x0809 /* BOF */: {
@@ -21623,7 +21684,7 @@ wb.opts.Date1904 = Workbook.WBProps.date1904 = val; break;
21623
21684
  while(val.e >= val.s) {
21624
21685
  colinfo[val.e--] = { width: val.w/256, level: (val.level || 0), hidden: !!(val.flags & 1) };
21625
21686
  if(val.ixfe != null && XFs[val.ixfe]) colinfo[val.e+1].s = resolve_xls_style(XFs[val.ixfe], val.ixfe);
21626
- if(!seencol) { seencol = true; find_mdw_colw(val.w/256); }
21687
+ if(!seencol) { seencol = true; MDW = DEF_MDW; }
21627
21688
  process_col(colinfo[val.e+1]);
21628
21689
  }
21629
21690
  } break;
@@ -21680,10 +21741,13 @@ if(!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook";
21680
21741
  if(!wb.SheetNames.length && Preamble["!ref"]) {
21681
21742
  wb.SheetNames.push("Sheet1");
21682
21743
  /*jshint -W069 */
21683
- if(wb.Sheets) wb.Sheets["Sheet1"] = Preamble;
21744
+ if(wb.Sheets) sheet_map_set(wb.Sheets, "Sheet1", Preamble);
21684
21745
  /*jshint +W069 */
21685
21746
  } else wb.Preamble=Preamble;
21686
- 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
+ });
21687
21751
  wb.Strings = sst;
21688
21752
  wb.SSF = dup(table_fmt);
21689
21753
  if(opts.enc) wb.Encryption = opts.enc;
@@ -23308,7 +23372,7 @@ function write_biff2_buf(wb, opts) {
23308
23372
  o.cellXfs = [{numFmtId: 0}];
23309
23373
  o._BIFF2FmtTable = ["General"]; o._Fonts = [];
23310
23374
  var body = buf_array();
23311
- 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);
23312
23376
 
23313
23377
  o._BIFF2FmtTable.forEach(function(f) {
23314
23378
  if(o.biff <= 3) write_biff_rec(ba, 0x001E, write_BIFF2Format(f));
@@ -23718,7 +23782,7 @@ function write_ws_biff8_cell(ba, cell, R, C, opts, date1904) {
23718
23782
  /* [MS-XLS] 2.1.7.20.5 */
23719
23783
  function write_ws_biff8(idx, opts, wb) {
23720
23784
  var ba = buf_array();
23721
- var s = wb.SheetNames[idx], ws = wb.Sheets[s] || {};
23785
+ var s = wb.SheetNames[idx], ws = sheet_map_get(wb.Sheets, s) || {};
23722
23786
  var _WB = ((wb||{}).Workbook||{});
23723
23787
  var _sheet = ((_WB.Sheets||[])[idx]||{});
23724
23788
  var dense = ws["!data"] != null;
@@ -23917,7 +23981,7 @@ function write_biff8_buf(wb, opts) {
23917
23981
 
23918
23982
  function write_biff_buf(wb, opts) {
23919
23983
  for(var i = 0; i <= wb.SheetNames.length; ++i) {
23920
- var ws = wb.Sheets[wb.SheetNames[i]];
23984
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[i]);
23921
23985
  if(!ws || !ws["!ref"]) continue;
23922
23986
  var range = decode_range(ws["!ref"]);
23923
23987
  if(range.e.c > 255) { // note: 255 is IV
@@ -23999,15 +24063,66 @@ function html_to_sheet(str, _opts) {
23999
24063
  return ws;
24000
24064
  }
24001
24065
 
24002
- function cssesc(x) { return escapexml(String(x).replace(/"/g, "'")); }
24003
24066
  function css_color(color) {
24004
24067
  if(!color) return "";
24005
- 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);
24006
24069
  return "";
24007
24070
  }
24008
24071
  function css_font_family(name) {
24009
24072
  if(!name) return "";
24010
- 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("");
24011
24126
  }
24012
24127
  function html_border_style(style) {
24013
24128
  switch(style) {
@@ -24036,7 +24151,8 @@ function html_cell_style(cell, opts) {
24036
24151
  var s = cell.s, css = [];
24037
24152
  var font = s.font || {};
24038
24153
  if(font.name) css.push("font-family:" + css_font_family(font.name));
24039
- 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");
24040
24156
  if(font.bold) css.push("font-weight:bold");
24041
24157
  if(font.italic) css.push("font-style:italic");
24042
24158
  var deco = [];
@@ -24049,8 +24165,9 @@ function html_cell_style(cell, opts) {
24049
24165
  if(fill.patternType != "none" && fill.patternType != "gray125") fillColor = css_color(fill.fgColor) || css_color(fill.bgColor);
24050
24166
  if(fillColor) css.push("background-color:" + fillColor);
24051
24167
  var alignment = s.alignment || {};
24052
- if(alignment.horizontal) css.push("text-align:" + alignment.horizontal);
24053
- 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);
24054
24171
  if(alignment.textRotation != null && alignment.textRotation !== 0) {
24055
24172
  var deg = alignment.textRotation == 255 ? 90 : alignment.textRotation > 90 ? 90 - alignment.textRotation : alignment.textRotation;
24056
24173
  css.push("transform:rotate(" + deg + "deg)");
@@ -24129,7 +24246,7 @@ function make_html_row(ws, r, R, o) {
24129
24246
  }
24130
24247
  }
24131
24248
  /* TODO: html entities */
24132
- 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) || "")) || "";
24133
24250
  sp = ({});
24134
24251
  if(RS > 1) sp.rowspan = RS;
24135
24252
  if(CS > 1) sp.colspan = CS;
@@ -24137,17 +24254,18 @@ function make_html_row(ws, r, R, o) {
24137
24254
  else if(cell) {
24138
24255
  sp["data-t"] = cell && cell.t || 'z';
24139
24256
  // note: data-v is unaffected by the timezone interpretation
24140
- 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;
24141
24258
  if(cell.z != null) sp["data-z"] = cell.z;
24142
- if(cell.f != null) sp["data-f"] = escapehtml(cell.f);
24143
- 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>';
24144
24262
  }
24145
24263
  var cstyle = html_cell_style(stylecell, o);
24146
24264
  var lstyle = html_cell_layout_style(stylecell, o, C, CS, cols);
24147
24265
  if(lstyle) cstyle = cstyle ? cstyle + ";" + lstyle : lstyle;
24148
24266
  if(cstyle) sp.style = cstyle;
24149
24267
  sp.id = (o.id || "sjs") + "-" + coord;
24150
- oo.push(writextag('td', w, sp));
24268
+ oo.push(html_writextag('td', w, sp));
24151
24269
  }
24152
24270
  var rsp = ({}), rstyle = [];
24153
24271
  if(row) {
@@ -24155,7 +24273,7 @@ function make_html_row(ws, r, R, o) {
24155
24273
  if(o.browserPixels) rstyle.push("height:" + html_row_height(row) + "px");
24156
24274
  }
24157
24275
  if(rstyle.length) rsp.style = rstyle.join(";");
24158
- return writextag('tr', oo.join(""), rsp);
24276
+ return html_writextag('tr', oo.join(""), rsp);
24159
24277
  }
24160
24278
 
24161
24279
  var HTML_BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
@@ -24291,8 +24409,10 @@ function render_html_drawings(ws, opts) {
24291
24409
  var out = [], drawings = ws["!drawings"] || {}, charts = ws["!charts"] || [];
24292
24410
  if(opts && opts.drawings && drawings.images) drawings.images.forEach(function(img) {
24293
24411
  if(!img || !img.dataURI) return;
24412
+ var src = safe_html_image_src(img.dataURI);
24413
+ if(!src) return;
24294
24414
  var pos = html_anchor_pos(ws, img.anchor, opts);
24295
- 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) + '"/>');
24296
24416
  });
24297
24417
  if(opts && opts.charts) charts.forEach(function(chart) {
24298
24418
  var pos = html_anchor_pos(ws, chart.anchor, opts);
@@ -24307,7 +24427,7 @@ function make_html_preamble(ws, R, o) {
24307
24427
  if(o && o.id) tattr.id = o.id;
24308
24428
  if(o && (o.browserPixels || o.autoFit)) tstyle.push("border-collapse:collapse;table-layout:fixed");
24309
24429
  if(tstyle.length) tattr.style = tstyle.join(";");
24310
- var table = writextag("table", "", tattr).replace(/<\/table>$/, "");
24430
+ var table = html_writextag("table", "", tattr).replace(/<\/table>$/, "");
24311
24431
  var cols = o && o._htmlCols || ws["!cols"];
24312
24432
  if(o && (o.browserPixels || o.autoFit) && cols) {
24313
24433
  out.push("<colgroup>");
@@ -24315,7 +24435,7 @@ function make_html_preamble(ws, R, o) {
24315
24435
  var col = cols[C], style = [];
24316
24436
  style.push("width:" + html_col_width(col) + "px");
24317
24437
  if(col && col.hidden) style.push("display:none");
24318
- out.push(writextag("col", null, {style:style.join(";")}));
24438
+ out.push(html_writextag("col", null, {style:style.join(";")}));
24319
24439
  }
24320
24440
  out.push("</colgroup>");
24321
24441
  }
@@ -24482,7 +24602,7 @@ function parse_text_p(text) {
24482
24602
  .replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1,10)+1).join(" "); })
24483
24603
  .replace(/<text:tab[^<>]*\/>/g,"\t")
24484
24604
  .replace(/<text:line-break\/>/g,"\n");
24485
- var v = unescapexml(fixed.replace(/<[^<>]*>/g,""));
24605
+ var v = unescapexml(strip_xml_tags(fixed));
24486
24606
 
24487
24607
  return [v];
24488
24608
  }
@@ -24719,7 +24839,7 @@ function parse_content_xml(d, _opts, _nfm) {
24719
24839
  var nfidx, NF = "", pidx = 0;
24720
24840
  var sheetag;
24721
24841
  var rowtag;
24722
- var Sheets = {}, SheetNames = [];
24842
+ var Sheets = sheet_map_new(), SheetNames = [];
24723
24843
  var ws = ({}); if(opts.dense) ws["!data"] = [];
24724
24844
  var Rn, q;
24725
24845
  var ctag = ({value:""}), ctag2 = ({});
@@ -24756,7 +24876,7 @@ function parse_content_xml(d, _opts, _nfm) {
24756
24876
  sheetag.name = sheetag['名称'] || sheetag.name;
24757
24877
  if(typeof JSON !== 'undefined') JSON.stringify(sheetag);
24758
24878
  SheetNames.push(sheetag.name);
24759
- Sheets[sheetag.name] = ws;
24879
+ sheet_map_set(Sheets, sheetag.name, ws);
24760
24880
  WB.Sheets.push({
24761
24881
  /* TODO: CodeName */
24762
24882
  Hidden: (tstyles[sheetag["style-name"]] && tstyles[sheetag["style-name"]]["display"] ? (parsexmlbool(tstyles[sheetag["style-name"]]["display"]) ? 0 : 1) : 0)
@@ -25112,7 +25232,9 @@ function parse_content_xml(d, _opts, _nfm) {
25112
25232
  if(Rn[1]==='/') break;
25113
25233
  try {
25114
25234
  _Ref = ods_to_csf_3D(parsexmltag(Rn[0])['target-range-address']);
25115
- 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
+ }
25116
25238
  } catch(e) {/* empty */}
25117
25239
  break;
25118
25240
 
@@ -25622,7 +25744,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25622
25744
 
25623
25745
  /* column styles */
25624
25746
  var cidx = 0;
25625
- 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) {
25626
25748
  if(!ws) return;
25627
25749
  if(ws["!cols"]) {
25628
25750
  for(var C = 0; C < ws["!cols"].length; ++C) if(ws["!cols"][C]) {
@@ -25641,7 +25763,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25641
25763
 
25642
25764
  /* row styles */
25643
25765
  var ridx = 0;
25644
- 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) {
25645
25767
  if(!ws) return;
25646
25768
  if(ws["!rows"]) {
25647
25769
  for(var R = 0; R < ws["!rows"].length; ++R) if(ws["!rows"][R]) {
@@ -25674,7 +25796,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25674
25796
  /* number formats, table cells, text */
25675
25797
  var nfs = {};
25676
25798
  var nfi = 69;
25677
- 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) {
25678
25800
  if(!ws) return;
25679
25801
  var dense = (ws["!data"] != null);
25680
25802
  if(!ws["!ref"]) return;
@@ -25757,7 +25879,7 @@ var write_content_ods = /* @__PURE__ */(function() {
25757
25879
  o.push(' <office:body>\n');
25758
25880
  o.push(' <office:spreadsheet>\n');
25759
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');
25760
- 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));
25761
25883
  if((wb.Workbook||{}).Names) o.push(write_names_ods(wb.Workbook.Names, wb.SheetNames, -1));
25762
25884
  o.push(' </office:spreadsheet>\n');
25763
25885
  o.push(' </office:body>\n');
@@ -25809,7 +25931,6 @@ function write_ods(wb, opts) {
25809
25931
 
25810
25932
  return zip;
25811
25933
  }
25812
-
25813
25934
  /*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
25814
25935
  var subarray = function() {
25815
25936
  try {
@@ -26267,7 +26388,8 @@ var numbers_lut_new = function() {
26267
26388
  function numbers_format_cell(cell, t, flags, ofmt, nfmt) {
26268
26389
  var _a, _b, _c, _d;
26269
26390
  var ctype = t & 255, ver = t >> 8;
26270
- var fmt = ver >= 5 ? nfmt : ofmt;
26391
+ /* Missing legacy/new format tables mean the default format. */
26392
+ var fmt = (ver >= 5 ? nfmt : ofmt) || [];
26271
26393
  dur:
26272
26394
  if (flags & (ver > 4 ? 8 : 4) && cell.t == "n" && ctype == 7) {
26273
26395
  var dstyle = ((_a = fmt[7]) == null ? void 0 : _a[0]) ? varint_to_i32(fmt[7][0].data) : -1;
@@ -27326,7 +27448,7 @@ function write_numbers_iwa(wb, opts) {
27326
27448
  docroot = numbers_iwa_find(cfb, deps, 1);
27327
27449
  sheetrefs = mappa(parse_shallow(docroot.messages[0].data)[1], parse_TSP_Reference);
27328
27450
  }
27329
- 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]);
27330
27452
  });
27331
27453
  return cfb;
27332
27454
  }
@@ -28182,6 +28304,7 @@ function drawing_mime(path) {
28182
28304
  case "bmp": return "image/bmp";
28183
28305
  case "svg": return "image/svg+xml";
28184
28306
  case "jpg": case "jpeg": return "image/jpeg";
28307
+ case "tif": case "tiff": return "image/tiff";
28185
28308
  default: return "application/octet-stream";
28186
28309
  }
28187
28310
  }
@@ -28197,7 +28320,9 @@ function parse_sheet_drawing(sheet, type, zip, path, idx, opts, wb) {
28197
28320
  if(!img || !img.target) return;
28198
28321
  var ipath = resolve_path(img.target, dfile);
28199
28322
  var ibin = getzipbin(zip, ipath, true);
28200
- if(ibin) img.dataURI = "data:" + drawing_mime(ipath) + ";base64," + Base64_encode_arr(ibin);
28323
+ var contentType = drawing_mime(ipath);
28324
+ if(ibin) img.dataURI = "data:" + contentType + ";base64," + Base64_encode_arr(ibin);
28325
+ img.contentType = contentType;
28201
28326
  img.path = ipath;
28202
28327
  });
28203
28328
  if(opts.charts && draw.charts && draw.charts.length) {
@@ -28241,7 +28366,7 @@ function safe_parse_sheet(zip, path, relsPath, sheet, idx, sheetRels, sheets, st
28241
28366
  case 'dialog': _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles); break;
28242
28367
  default: throw new Error("Unrecognized sheet type " + stype);
28243
28368
  }
28244
- sheets[sheet] = _ws;
28369
+ sheet_map_set(sheets, sheet, _ws);
28245
28370
 
28246
28371
  /* scan rels for comments and threaded comments */
28247
28372
  var comments = [], tcomments = [];
@@ -28364,7 +28489,7 @@ function parse_zip(zip, opts) {
28364
28489
  if(opts.bookSheets && typeof sheets !== 'undefined') out.SheetNames = sheets;
28365
28490
  if(opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
28366
28491
  }
28367
- sheets = {};
28492
+ sheets = sheet_map_new();
28368
28493
 
28369
28494
  var deps = {};
28370
28495
  if(opts.bookDeps && dir.calcchain) deps=parse_cc(getzipdata(zip, strip_front_slash(dir.calcchain)),dir.calcchain,opts);
@@ -28564,7 +28689,7 @@ f = "docProps/app.xml";
28564
28689
 
28565
28690
  for(rId=1;rId <= wb.SheetNames.length; ++rId) {
28566
28691
  var wsrels = {'!id':{}};
28567
- var ws = wb.Sheets[wb.SheetNames[rId-1]];
28692
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[rId-1]);
28568
28693
  var _type = (ws || {})["!type"] || "sheet";
28569
28694
  switch(_type) {
28570
28695
  case "chart":
@@ -28719,7 +28844,7 @@ f = "docProps/app.xml";
28719
28844
 
28720
28845
  for(rId=1;rId <= wb.SheetNames.length; ++rId) {
28721
28846
  var wsrels = {'!id':{}};
28722
- var ws = wb.Sheets[wb.SheetNames[rId-1]];
28847
+ var ws = sheet_map_get(wb.Sheets, wb.SheetNames[rId-1]);
28723
28848
  var _type = (ws || {})["!type"] || "sheet";
28724
28849
  switch(_type) {
28725
28850
  case "chart":
@@ -28815,7 +28940,6 @@ f = "docProps/app.xml";
28815
28940
  delete opts.revssf; delete opts.ssf;
28816
28941
  return zip;
28817
28942
  }
28818
-
28819
28943
  function firstbyte(f,o) {
28820
28944
  var x = "";
28821
28945
  switch((o||{}).type || "base64") {
@@ -29084,18 +29208,18 @@ function writeSync(wb, opts) {
29084
29208
  case 'xml':
29085
29209
  case 'xlml': return write_string_type(write_xlml(wb, o), o);
29086
29210
  case 'slk':
29087
- 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);
29088
29212
  case 'htm':
29089
- case 'html': return write_string_type(sheet_to_html(wb.Sheets[wb.SheetNames[idx]], o), o);
29090
- case 'txt': return write_stxt_type(sheet_to_txt(wb.Sheets[wb.SheetNames[idx]], o), o);
29091
- case 'csv': return write_string_type(sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o), o, "\ufeff");
29092
- case 'dif': return write_string_type(DIF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29093
- case 'dbf': return write_binary_type(DBF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29094
- case 'prn': return write_string_type(PRN.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
29095
- case 'rtf': return write_string_type(sheet_to_rtf(wb.Sheets[wb.SheetNames[idx]], o), o);
29096
- 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);
29097
29221
  case 'fods': return write_string_type(write_ods(wb, o), o);
29098
- 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);
29099
29223
  case 'wk3': return write_binary_type(WK_.book_to_wk3(wb, o), o);
29100
29224
  case 'biff2': if(!o.biff) o.biff = 2; /* falls through */
29101
29225
  case 'biff3': if(!o.biff) o.biff = 3; /* falls through */
@@ -29355,6 +29479,7 @@ function sheet_add_json(_ws, js, opts) {
29355
29479
  var _origin = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
29356
29480
  _R = _origin.r; _C = _origin.c;
29357
29481
  }
29482
+ if(!isFinite(_R) || _R !== Math.floor(_R) || _R < -1 || !isFinite(_C) || _C !== Math.floor(_C) || _C < 0) throw new Error("Invalid origin");
29358
29483
  }
29359
29484
  var range = ({s: {c:0, r:0}, e: {c:_C, r:_R + js.length - 1 + offset}});
29360
29485
  if(ws['!ref']) {
@@ -29446,7 +29571,7 @@ function wb_sheet_idx(wb, sh) {
29446
29571
 
29447
29572
  /* simple blank or single-sheet workbook object */
29448
29573
  function book_new(ws, wsname) {
29449
- var wb = { SheetNames: [], Sheets: {} };
29574
+ var wb = { SheetNames: [], Sheets: sheet_map_new() };
29450
29575
  if(ws) book_append_sheet(wb, ws, wsname || "Sheet1");
29451
29576
  return wb;
29452
29577
  }
@@ -29466,7 +29591,7 @@ function book_append_sheet(wb, ws, name, roll) {
29466
29591
  if(wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!");
29467
29592
 
29468
29593
  wb.SheetNames.push(name);
29469
- wb.Sheets[name] = ws;
29594
+ sheet_map_set(wb.Sheets, name, ws);
29470
29595
  return name;
29471
29596
  }
29472
29597
 
@@ -29533,7 +29658,6 @@ function sheet_set_array_formula(ws, range, formula, dynamic) {
29533
29658
  ws["!ref"] = encode_range(wsr);
29534
29659
  return ws;
29535
29660
  }
29536
-
29537
29661
  var utils = {
29538
29662
  encode_col: encode_col,
29539
29663
  encode_row: encode_row,
@@ -29690,7 +29814,7 @@ function write_json_stream(sheet, opts) {
29690
29814
  if ((rowinfo[R]||{}).hidden) {
29691
29815
  ++R;
29692
29816
  continue;
29693
- };
29817
+ }
29694
29818
  var row = make_json_row(sheet, r, R, cols, header, hdr, o);
29695
29819
  ++R;
29696
29820
  if((row.isempty === false) || (header === 1 ? o.blankrows !== false : !!o.blankrows)) {
@@ -29719,7 +29843,7 @@ function write_xlml_stream(wb, o) {
29719
29843
 
29720
29844
  /* do one pass to determine styles since they must be added before tables */
29721
29845
  wb.SheetNames.forEach(function(n) {
29722
- var ws = wb.Sheets[n];
29846
+ var ws = sheet_map_get(wb.Sheets, n);
29723
29847
  if(!ws || !ws["!ref"]) return;
29724
29848
  var range = decode_range(ws["!ref"]);
29725
29849
  var dense = ws["!data"] != null;
@@ -29739,7 +29863,7 @@ function write_xlml_stream(wb, o) {
29739
29863
  });
29740
29864
  var sty = write_sty_xlml(wb, opts);
29741
29865
 
29742
- 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;
29743
29867
 
29744
29868
  var marr = [], mi = 0, dense = false, darr = [], addr = {r:0,c:0};
29745
29869
 
@@ -29779,7 +29903,7 @@ function write_xlml_stream(wb, o) {
29779
29903
 
29780
29904
  stream.push("<Worksheet" + wxt_helper({ "ss:Name": escapexml(wb.SheetNames[wsidx])}) + ">");
29781
29905
 
29782
- ws = wb.Sheets[wb.SheetNames[wsidx]];
29906
+ ws = sheet_map_get(wb.Sheets, wb.SheetNames[wsidx]);
29783
29907
  if(!ws) { stream.push("</Worksheet>"); return void ++wsidx; }
29784
29908
 
29785
29909
  var names = write_ws_xlml_names(ws, opts, wsidx, wb);