version bump 0.20.2

see https://regexide.com for more details
This commit is contained in:
SheetJS 2024-04-04 21:20:28 -04:00
parent 0941ff97a3
commit a0bed2a97d
44 changed files with 9720 additions and 8896 deletions

View File

@ -6,6 +6,7 @@ changes may not be included if they are not expected to break existing code.
## v0.20.2
* Reworked parsing methods to avoid slow regexes (CVE-2024-22363)
* HTML properly encode data-v attribute
* SYLK read and write error cells

View File

@ -1 +1 @@
XLSX.version = '0.20.1';
XLSX.version = '0.20.2';

View File

@ -408,7 +408,7 @@ function write_num_f2(r/*:Array<string>*/, aval/*:number*/, sign/*:string*/)/*:s
return sign + (aval === 0 ? "" : ""+aval) + fill(" ", r[1].length + 2 + r[4].length);
}
var dec1 = /^#*0*\.([0#]+)/;
var closeparen = /\).*[0#]/;
var closeparen = /\)[^)]*[0#]/;
var phone = /\(###\) ###\\?-####/;
function hashq(str/*:string*/)/*:string*/ {
var o = "", cc;

View File

@ -1683,7 +1683,7 @@ function parse_mime(cfb/*:CFBContainer*/, data/*:Array<string>*/, root/*:string*
for(;di < 10; ++di) {
var line = data[di];
if(!line || line.match(/^\s*$/)) break;
var m = line.match(/^(.*?):\s*([^\s].*)$/);
var m = line.match(/^([^:]*?):\s*([^\s].*)$/);
if(m) switch(m[1].toLowerCase()) {
case "content-location": fname = m[2].trim(); break;
case "content-type": ctype = m[2].trim(); break;

View File

@ -87,7 +87,7 @@ function parseDate(str/*:string*/, date1904/*:boolean*/)/*:Date*/ {
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], 0, 0, 0, 0));
/* TODO: 1900-02-29T00:00:00.000 should return a flag to treat as a date code (affects xlml) */
m = str.match(pdre3);
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt(m[7].slice(1), 10))||0)));
if(m) return new Date(Date.UTC(+m[1], +m[2]-1, +m[3], +m[4], +m[5], ((m[6] && parseInt(m[6].slice(1), 10))|| 0), ((m[7] && parseInt((m[7] + "0000").slice(1,4), 10))||0)));
var d = new Date(str);
return d;
}
@ -154,7 +154,7 @@ function fuzzynum(s/*:string*/)/*:number*/ {
var wt = 1;
var ss = s.replace(/([\d]),([\d])/g,"$1$2").replace(/[$]/g,"").replace(/[%]/g, function() { wt *= 100; return "";});
if(!isNaN(v = Number(ss))) return v / wt;
ss = ss.replace(/[(](.*)[)]/,function($$, $1) { wt = -wt; return $1;});
ss = ss.replace(/[(]([^()]*)[)]/,function($$, $1) { wt = -wt; return $1;});
if(!isNaN(v = Number(ss))) return v / wt;
return v;
}
@ -224,6 +224,15 @@ function local_to_utc(local) {
return new Date(Date.UTC(local.getFullYear(), local.getMonth(), local.getDate(), local.getHours(), local.getMinutes(), local.getSeconds(), local.getMilliseconds()));
}
function remove_doctype(str) {
var preamble = str.slice(0, 1024);
var si = preamble.indexOf("<!DOCTYPE");
if(si == -1) return str;
var m = str.match(/<[\w]/);
if(!m) return str;
return str.slice(0, si) + str.slice(m.index);
}
/* str.match(/<!--[\s\S]*?-->/g) --> str_match_ng(str, "<!--", "-->") */
function str_match_ng(str, s, e) {
var out = [];
@ -257,11 +266,13 @@ function str_remove_ng(str, s, e) {
return out.join("");
}
/* str.match(/<tag[^>]*?>([\s\S]*?)</tag>/) --> str_match_xml(str, "tag") */
/* str.match(/<tag\b[^>]*?>([\s\S]*?)</tag>/) --> str_match_xml(str, "tag") */
var xml_boundary = { " ": 1, "\t": 1, "\r": 1, "\n": 1, ">": 1 };
function str_match_xml(str, tag) {
var si = str.indexOf('<' + tag);
var si = str.indexOf('<' + tag), w = tag.length + 1, L = str.length;
while(si >= 0 && si <= L - w && !xml_boundary[str.charAt(si + w)]) si = str.indexOf('<' + tag, si+1);
if(si === -1) return null;
var sf = str.indexOf(">", si);
var sf = str.indexOf(">", si + tag.length);
if(sf === -1) return null;
var et = "</" + tag + ">";
var ei = str.indexOf(et, sf);
@ -269,12 +280,13 @@ function str_match_xml(str, tag) {
return [str.slice(si, ei + et.length), str.slice(sf + 1, ei)];
}
/* str.match(/<(?:\w+:)?tag\b[^<>]*?>([\s\S]*?)<\/(?:\w+:)?tag>/) --> str_match_xml(str, "tag") */
var str_match_xml_ns = /*#__PURE__*/(function() {
var str_match_xml_ns_cache = {};
return function str_match_xml_ns(str, tag) {
var res = str_match_xml_ns_cache[tag];
if(!res) str_match_xml_ns_cache[tag] = res = [
new RegExp('<(?:\\w+:)?'+tag+'[^>]*>', "g"),
new RegExp('<(?:\\w+:)?'+tag+'\\b[^<>]*>', "g"),
new RegExp('</(?:\\w+:)?'+tag+'>', "g")
];
res[0].lastIndex = res[1].lastIndex = 0;
@ -291,24 +303,74 @@ var str_match_xml_ns = /*#__PURE__*/(function() {
};
})();
/* str.match(/<(?:\w+:)?tag\b[^<>]*?>([\s\S]*?)<\/(?:\w+:)?tag>/g) --> str_match_xml_ns_g(str, "tag") */
var str_match_xml_ns_g = /*#__PURE__*/(function() {
var str_match_xml_ns_cache = {};
return function str_match_xml_ns(str, tag) {
var out = [];
var res = str_match_xml_ns_cache[tag];
if(!res) str_match_xml_ns_cache[tag] = res = [
new RegExp('<(?:\\w+:)?'+tag+'[^>]*>', "g"),
new RegExp('<(?:\\w+:)?'+tag+'\\b[^<>]*>', "g"),
new RegExp('</(?:\\w+:)?'+tag+'>', "g")
];
res[0].lastIndex = res[1].lastIndex = 0;
var m;
while((m = res[0].exec(str))) {
var si = m.index;
var sf = res[0].lastIndex;
res[1].lastIndex = res[0].lastIndex;
m = res[1].exec(str);
if(!m) return null;
var ei = m.index;
var ef = res[1].lastIndex;
out.push(str.slice(si, ef));
res[0].lastIndex = res[1].lastIndex;
}
return out.length == 0 ? null : out;
};
})();
var str_remove_xml_ns_g = /*#__PURE__*/(function() {
var str_remove_xml_ns_cache = {};
return function str_remove_xml_ns_g(str, tag) {
var out = [];
var res = str_remove_xml_ns_cache[tag];
if(!res) str_remove_xml_ns_cache[tag] = res = [
new RegExp('<(?:\\w+:)?'+tag+'\\b[^<>]*>', "g"),
new RegExp('</(?:\\w+:)?'+tag+'>', "g")
];
res[0].lastIndex = res[1].lastIndex = 0;
var m;
var si = 0, ef = 0;
while((m = res[0].exec(str))) {
si = m.index;
out.push(str.slice(ef, si));
ef = si;
res[1].lastIndex = res[0].lastIndex;
m = res[1].exec(str);
if(!m) return null;
ef = res[1].lastIndex;
res[0].lastIndex = res[1].lastIndex;
}
out.push(str.slice(ef));
return out.length == 0 ? "" : out.join("");
};
})();
/* str.match(/<(?:\w+:)?tag\b[^>]*?>([\s\S]*?)<\/(?:\w+:)?tag>/gi) --> str_match_xml_ns_ig(str, "tag") */
var str_match_xml_ig = /*#__PURE__*/(function() {
var str_match_xml_ns_cache = {};
return function str_match_xml_ns(str, tag) {
var out = [];
var res = str_match_xml_ns_cache[tag];
if(!res) str_match_xml_ns_cache[tag] = res = [
new RegExp('<'+tag+'\\b[^<>]*>', "ig"),
new RegExp('</'+tag+'>', "ig")
];
res[0].lastIndex = res[1].lastIndex = 0;
var m;
while((m = res[0].exec(str))) {
var si = m.index;
res[1].lastIndex = res[0].lastIndex;
m = res[1].exec(str);
if(!m) return null;
var ef = res[1].lastIndex;
out.push(str.slice(si, ef));
res[0].lastIndex = res[1].lastIndex;

View File

@ -1,6 +1,6 @@
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
var attregexg=/([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex1=/<[\/\?]?[a-zA-Z0-9:_-]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s*[\/\?]?>/mg, tagregex2 = /<[^>]*>/g;
var attregexg=/\s([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex1=/<[\/\?]?[a-zA-Z0-9:_-]+(?:\s+[^"\s?<>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'"<>\s=]+))*\s*[\/\?]?>/mg, tagregex2 = /<[^<>]*>/g;
var tagregex = /*#__PURE__*/XML_HEADER.match(tagregex1) ? tagregex1 : tagregex2;
var nsregex=/<\w*:/, nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*/)/*:any*/ {
@ -11,7 +11,7 @@ function parsexmltag(tag/*:string*/, skip_root/*:?boolean*/, skip_LC/*:?boolean*
if(eq === tag.length) return z;
var m = tag.match(attregexg), j=0, v="", i=0, q="", cc="", quot = 1;
if(m) for(i = 0; i != m.length; ++i) {
cc = m[i];
cc = m[i].slice(1);
for(c=0; c != cc.length; ++c) if(cc.charCodeAt(c) === 61) break;
q = cc.slice(0,c).trim();
while(cc.charCodeAt(c+1) == 32) ++c;
@ -171,21 +171,21 @@ var htmldecode/*:{(s:string):string}*/ = /*#__PURE__*/(function() {
// Remove new lines and spaces from start of content
.replace(/^[\t\n\r ]+/, "")
// Remove new lines and spaces from end of content
.replace(/[\t\n\r ]+$/,"")
.replace(/(^|[^\t\n\r ])[\t\n\r ]+$/,"$1")
// Added line which removes any white space characters after and before html tags
.replace(/>\s+/g,">").replace(/\s+</g,"<")
.replace(/>\s+/g,">").replace(/\b\s+</g,"<")
// Replace remaining new lines and spaces with space
.replace(/[\t\n\r ]+/g, " ")
// Replace <br> tags with new lines
.replace(/<\s*[bB][rR]\s*\/?>/g,"\n")
// Strip HTML elements
.replace(/<[^>]*>/g,"");
.replace(/<[^<>]*>/g,"");
for(var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
return o;
};
})();
var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</;
var vtvregex = /<\/?(?:vt:)?variant>/g, vtmregex = /<(?:vt:)([^<"'>]*)>([\s\S]*)</;
function parseVector(data/*:string*/, opts)/*:Array<{v:string,t:string}>*/ {
var h = parsexmltag(data);
@ -230,9 +230,8 @@ function xlml_normalize(d)/*:string*/ {
if(typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
throw new Error("Bad input format: expected Buffer or string");
}
/* UOS uses CJK in tags */
var xlmlregex = /<(\/?)([^\s?><!\/:]*:|)([^\s?<>:\/]+)(?:[\s?:\/](?:[^>=]|="[^"]*?")*)?>/mg;
//var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;
/* UOS uses CJK in tags, ODS uses invalid XML */
var xlmlregex = /<([\/]?)([^\s?><!\/:"]*:|)([^\s?<>:\/"]+)(?:\s+[^<>=?"'\s]+="[^"]*?")*\s*[\/]?>/mg;
var XMLNS = ({
CORE_PROPS: 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties',

View File

@ -128,22 +128,24 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
var _origin/*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
_R = _origin.r; _C = _origin.c;
}
if(!ws["!ref"]) ws["!ref"] = "A1:A1";
}
var range/*:Range*/ = ({s: {c:10000000, r:10000000}, e: {c:0, r:0}}/*:any*/);
if(ws['!ref']) {
if(ws["!ref"]){
var _range = safe_decode_range(ws['!ref']);
range.s.c = _range.s.c;
range.s.r = _range.s.r;
range.e.c = Math.max(range.e.c, _range.e.c);
range.e.r = Math.max(range.e.r, _range.e.r);
if(_R == -1) range.e.r = _R = _range.e.r + 1;
if(_R == -1) range.e.r = _R = (ws["!ref"] ? _range.e.r + 1 : 0);
} else {
range.s.c = range.e.c = range.s.r = range.e.r = 0;
}
var row = [];
var row = [], seen = false;
for(var R = 0; R != data.length; ++R) {
if(!data[R]) continue;
if(!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
var __R = _R + R, __Rstr = "" + (__R + 1);
//console.log("!!", R, _R, __R);
if(dense) {
if(!ws["!data"][__R]) ws["!data"][__R] = [];
row = ws["!data"][__R];
@ -156,6 +158,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
if(range.s.c > __C) range.s.c = __C;
if(range.e.r < __R) range.e.r = __R;
if(range.e.c < __C) range.e.c = __C;
seen = true;
if(data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];
else {
if(Array.isArray(cell.v)) { cell.f = data[R][C][1]; cell.v = cell.v[0]; }
@ -185,7 +188,7 @@ function sheet_add_aoa(_ws/*:?Worksheet*/, data/*:AOA*/, opts/*:?any*/)/*:Worksh
}
}
}
if(range.s.c < 10000000) ws['!ref'] = encode_range(range);
if(seen && range.s.c < 10400000) ws['!ref'] = encode_range(range);
return ws;
}
function aoa_to_sheet(data/*:AOA*/, opts/*:?any*/)/*:Worksheet*/ { return sheet_add_aoa(null, data, opts); }

View File

@ -1,5 +1,5 @@
/* 15.2.12.2 Custom File Properties Part */
var custregex = /<[^>]+>[^<]*/g;
var custregex = /<[^<>]+>[^<]*/g;
function parse_cust_props(data/*:string*/, opts) {
var p = {}, name = "";
var m = data.match(custregex);

View File

@ -233,8 +233,8 @@ function parse_PropertySet(blob, PIDSI) {
/* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
switch(blob[blob.l]) {
case 0x41 /*VT_BLOB*/: blob.l += 4; val = parse_BLOB(blob); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/\u0000+$/,""); break;
case 0x1E /*VT_LPSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x1F /*VT_LPWSTR*/: blob.l += 4; val = parse_VtString(blob, blob[blob.l-4]).replace(/(^|[^\u0000])\u0000+$/,"$1"); break;
case 0x03 /*VT_I4*/: blob.l += 4; val = blob.read_shift(4, 'i'); break;
case 0x13 /*VT_UI4*/: blob.l += 4; val = blob.read_shift(4); break;
case 0x05 /*VT_R8*/: blob.l += 4; val = blob.read_shift(8, 'f'); break;

View File

@ -118,7 +118,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
var ww = l7 ? 32 : 11;
while(d.l < hend && d[d.l] != 0x0d) {
field = ({}/*:any*/);
field.name = (typeof $cptable !== "undefined" ? $cptable.utils.decode(current_cp, d.slice(d.l, d.l+ww)) : a2s(d.slice(d.l, d.l + ww))).replace(/[\u0000\r\n].*$/g,"");
field.name = (typeof $cptable !== "undefined" ? $cptable.utils.decode(current_cp, d.slice(d.l, d.l+ww)) : a2s(d.slice(d.l, d.l + ww))).replace(/[\u0000\r\n][\S\s]*$/g,"");
d.l += ww;
field.type = String.fromCharCode(d.read_shift(1));
if(ft != 0x02 && !l7) field.offset = d.read_shift(4);
@ -176,7 +176,7 @@ function dbf_to_aoa(buf, opts)/*:AOA*/ {
switch(fields[C].type) {
case 'C':
// NOTE: it is conventional to write ' / / ' for empty dates
if(s.trim().length) out[R][C] = s.replace(/\s+$/,"");
if(s.trim().length) out[R][C] = s.replace(/([^\s])\s+$/,"$1");
break;
case 'D':
if(s.length === 8) {
@ -1121,7 +1121,7 @@ function read_wb_ID(d, opts) {
return out;
} catch(e) {
o.WTF = OLD_WTF;
if(!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e;
if((e.message.indexOf("SYLK bad record ID") == -1) && OLD_WTF) throw e;
return PRN.to_workbook(d, opts);
}
}

View File

@ -4,7 +4,7 @@ function parse_rpr(rpr) {
var pass = false;
if(m) for(;i!=m.length; ++i) {
var y = parsexmltag(m[i]);
switch(y[0].replace(/\w*:/g,"")) {
switch(y[0].replace(/<\w*:/g,"<")) {
/* 18.8.12 condense CT_BooleanProperty */
/* ** not required . */
case '<condense': break;
@ -167,8 +167,7 @@ var rs_to_html = /*#__PURE__*/(function parse_rs_factory() {
})();
/* 18.4.8 si CT_Rst */
var sitregex = /<(?:\w+:)?t[^>]*>([^<]*)<\/(?:\w+:)?t>/g, sirregex = /<(?:\w+:)?r\b[^>]*>/;
var sirphregex = /<(?:\w+:)?rPh.*?>([\s\S]*?)<\/(?:\w+:)?rPh>/g;
var sitregex = /<(?:\w+:)?t\b[^<>]*>([^<]*)<\/(?:\w+:)?t>/g, sirregex = /<(?:\w+:)?r\b[^<>]*>/;
function parse_si(x, opts) {
var html = opts ? opts.cellHTML : true;
var z = {};
@ -184,7 +183,7 @@ function parse_si(x, opts) {
/* 18.4.4 r CT_RElt (Rich Text Run) */
else if((/*y = */x.match(sirregex))) {
z.r = utf8read(x);
z.t = unescapexml(utf8read((x.replace(sirphregex, '').match(sitregex)||[]).join("").replace(tagregex,"")), true);
z.t = unescapexml(utf8read((str_remove_xml_ns_g(x, "rPh").match(sitregex)||[]).join("").replace(tagregex,"")), true);
if(html) z.h = rs_to_html(parse_rs(z.r));
}
/* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
@ -193,21 +192,20 @@ function parse_si(x, opts) {
}
/* 18.4 Shared String Table */
var sstr0 = /<(?:\w+:)?sst([^>]*)>([\s\S]*)<\/(?:\w+:)?sst>/;
var sstr1 = /<(?:\w+:)?(?:si|sstItem)>/g;
var sstr2 = /<\/(?:\w+:)?(?:si|sstItem)>/;
function parse_sst_xml(data/*:string*/, opts)/*:SST*/ {
var s/*:SST*/ = ([]/*:any*/), ss = "";
if(!data) return s;
/* 18.4.9 sst CT_Sst */
var sst = data.match(sstr0);
var sst = str_match_xml_ns(data, "sst");
if(sst) {
ss = sst[2].replace(sstr1,"").split(sstr2);
ss = sst[1].replace(sstr1,"").split(sstr2);
for(var i = 0; i != ss.length; ++i) {
var o = parse_si(ss[i].trim(), opts);
if(o != null) s[s.length] = o;
}
sst = parsexmltag(sst[1]); s.Count = sst.count; s.Unique = sst.uniqueCount;
sst = parsexmltag(sst[0].slice(0, sst[0].indexOf(">"))); s.Count = sst.count; s.Unique = sst.uniqueCount;
}
return s;
}

View File

@ -3,7 +3,7 @@ function parse_borders(t, styles, themes, opts) {
styles.Borders = [];
var border = {};
var pass = false;
(t[0].match(tagregex)||[]).forEach(function(x) {
(t.match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<borders': case '<borders>': case '</borders>': break;
@ -78,7 +78,7 @@ function parse_fills(t, styles, themes, opts) {
styles.Fills = [];
var fill = {};
var pass = false;
(t[0].match(tagregex)||[]).forEach(function(x) {
(t.match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fills': case '<fills>': case '</fills>': break;
@ -144,7 +144,7 @@ function parse_fonts(t, styles, themes, opts) {
styles.Fonts = [];
var font = {};
var pass = false;
(t[0].match(tagregex)||[]).forEach(function(x) {
(t.match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x);
switch(strip_ns(y[0])) {
case '<fonts': case '<fonts>': case '</fonts>': break;
@ -264,7 +264,7 @@ function parse_numFmts(t, styles, opts) {
styles.NumberFmt = [];
var k/*Array<number>*/ = (keys(table_fmt)/*:any*/);
for(var i=0; i < k.length; ++i) styles.NumberFmt[k[i]] = table_fmt[k[i]];
var m = t[0].match(tagregex);
var m = t.match(tagregex);
if(!m) return;
for(i=0; i < m.length; ++i) {
var y = parsexmltag(m[i]);
@ -305,7 +305,7 @@ function parse_cellXfs(t, styles, opts) {
styles.CellXf = [];
var xf;
var pass = false;
(t[0].match(tagregex)||[]).forEach(function(x) {
(t.match(tagregex)||[]).forEach(function(x) {
var y = parsexmltag(x), i = 0;
switch(strip_ns(y[0])) {
case '<cellXfs': case '<cellXfs>': case '<cellXfs/>': case '</cellXfs>': break;
@ -370,36 +370,31 @@ function write_cellXfs(cellXfs)/*:string*/ {
/* 18.8 Styles CT_Stylesheet*/
var parse_sty_xml= /*#__PURE__*/(function make_pstyx() {
var numFmtRegex = /<(?:\w+:)?numFmts([^>]*)>[\S\s]*?<\/(?:\w+:)?numFmts>/;
var cellXfRegex = /<(?:\w+:)?cellXfs([^>]*)>[\S\s]*?<\/(?:\w+:)?cellXfs>/;
var fillsRegex = /<(?:\w+:)?fills([^>]*)>[\S\s]*?<\/(?:\w+:)?fills>/;
var fontsRegex = /<(?:\w+:)?fonts([^>]*)>[\S\s]*?<\/(?:\w+:)?fonts>/;
var bordersRegex = /<(?:\w+:)?borders([^>]*)>[\S\s]*?<\/(?:\w+:)?borders>/;
return function parse_sty_xml(data, themes, opts) {
var styles = {};
if(!data) return styles;
data = str_remove_ng(data, "<!--", "-->").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
data = remove_doctype(str_remove_ng(data, "<!--", "-->"));
/* 18.8.39 styleSheet CT_Stylesheet */
var t;
/* 18.8.31 numFmts CT_NumFmts ? */
if((t=data.match(numFmtRegex))) parse_numFmts(t, styles, opts);
if((t=str_match_xml_ns(data, "numFmts"))) parse_numFmts(t[0], styles, opts);
/* 18.8.23 fonts CT_Fonts ? */
if((t=data.match(fontsRegex))) parse_fonts(t, styles, themes, opts);
if((t=str_match_xml_ns(data, "fonts"))) parse_fonts(t[0], styles, themes, opts);
/* 18.8.21 fills CT_Fills ? */
if((t=data.match(fillsRegex))) parse_fills(t, styles, themes, opts);
if((t=str_match_xml_ns(data, "fills"))) parse_fills(t[0], styles, themes, opts);
/* 18.8.5 borders CT_Borders ? */
if((t=data.match(bordersRegex))) parse_borders(t, styles, themes, opts);
if((t=str_match_xml_ns(data, "borders"))) parse_borders(t[0], styles, themes, opts);
/* 18.8.9 cellStyleXfs CT_CellStyleXfs ? */
/* 18.8.8 cellStyles CT_CellStyles ? */
/* 18.8.10 cellXfs CT_CellXfs ? */
if((t=data.match(cellXfRegex))) parse_cellXfs(t, styles, opts);
if((t=str_match_xml_ns(data, "cellXfs"))) parse_cellXfs(t[0], styles, opts);
/* 18.8.15 dxfs CT_Dxfs ? */
/* 18.8.42 tableStyles CT_TableStyles ? */

View File

@ -70,30 +70,24 @@ function parse_fontScheme(/*::t, themes, opts*/) { }
/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */
function parse_fmtScheme(/*::t, themes, opts*/) { }
var clrsregex = /<a:clrScheme([^>]*)>[\s\S]*<\/a:clrScheme>/;
var fntsregex = /<a:fontScheme([^>]*)>[\s\S]*<\/a:fontScheme>/;
var fmtsregex = /<a:fmtScheme([^>]*)>[\s\S]*<\/a:fmtScheme>/;
/* 20.1.6.10 themeElements CT_BaseStyles */
function parse_themeElements(data, themes, opts) {
themes.themeElements = {};
var t;
[
/* clrScheme CT_ColorScheme */
['clrScheme', clrsregex, parse_clrScheme],
/* fontScheme CT_FontScheme */
['fontScheme', fntsregex, parse_fontScheme],
/* fmtScheme CT_StyleMatrix */
['fmtScheme', fmtsregex, parse_fmtScheme]
].forEach(function(m) {
if(!(t=data.match(m[1]))) throw new Error(m[0] + ' not found in themeElements');
m[2](t, themes, opts);
});
}
/* clrScheme CT_ColorScheme */
if(!(t=str_match_xml(data, "a:clrScheme"))) throw new Error('clrScheme not found in themeElements');
parse_clrScheme(t, themes, opts);
var themeltregex = /<a:themeElements([^>]*)>[\s\S]*<\/a:themeElements>/;
/* fontScheme CT_FontScheme */
if(!(t=str_match_xml(data, "a:fontScheme"))) throw new Error('fontScheme not found in themeElements');
parse_fontScheme(t, themes, opts);
/* fmtScheme CT_StyleMatrix */
if(!(t=str_match_xml(data, "a:fmtScheme"))) throw new Error('fmtScheme not found in themeElements');
parse_fmtScheme(t, themes, opts);
}
/* 14.2.7 Theme Part */
function parse_theme_xml(data/*:string*/, opts) {
@ -104,7 +98,7 @@ function parse_theme_xml(data/*:string*/, opts) {
var themes = {};
/* themeElements CT_BaseStyles */
if(!(t=data.match(themeltregex))) throw new Error('themeElements not found in theme');
if(!(t=str_match_xml(data, "a:themeElements"))) throw new Error('themeElements not found in theme');
parse_themeElements(t[0], themes, opts);
themes.raw = data;
return themes;

View File

@ -1,8 +1,7 @@
/* L.5.5.2 SpreadsheetML Comments + VML Schema */
var shapevmlregex = /<(?:\w+:)?shape(?:[^\w][^>]*)?>([\s\S]*?)<\/(?:\w+:)?shape>/g;
function parse_vml(data/*:string*/, sheet, comments) {
var cidx = 0;
(data.match(shapevmlregex)||[]).forEach(function(m) {
(str_match_xml_ns_g(data, "shape")||[]).forEach(function(m) {
var type = "";
var hidden = true;
var aidx = -1;

View File

@ -4,22 +4,22 @@ function parse_comments_xml(data/*:string*/, opts)/*:Array<RawComment>*/ {
if(data.match(/<(?:\w+:)?comments *\/>/)) return [];
var authors/*:Array<string>*/ = [];
var commentList/*:Array<RawComment>*/ = [];
var authtag = data.match(/<(?:\w+:)?authors>([\s\S]*)<\/(?:\w+:)?authors>/);
var authtag = str_match_xml_ns(data, "authors");
if(authtag && authtag[1]) authtag[1].split(/<\/\w*:?author>/).forEach(function(x) {
if(x === "" || x.trim() === "") return;
var a = x.match(/<(?:\w+:)?author[^>]*>(.*)/);
var a = x.match(/<(?:\w+:)?author[^<>]*>(.*)/);
if(a) authors.push(a[1]);
});
var cmnttag = data.match(/<(?:\w+:)?commentList>([\s\S]*)<\/(?:\w+:)?commentList>/);
var cmnttag = str_match_xml_ns(data, "commentList");
if(cmnttag && cmnttag[1]) cmnttag[1].split(/<\/\w*:?comment>/).forEach(function(x) {
if(x === "" || x.trim() === "") return;
var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
var cm = x.match(/<(?:\w+:)?comment[^<>]*>/);
if(!cm) return;
var y = parsexmltag(cm[0]);
var comment/*:RawComment*/ = ({ author: y.authorId && authors[y.authorId] || "sheetjsghost", ref: y.ref, guid: y.guid }/*:any*/);
var cell = decode_cell(y.ref);
if(opts.sheetRows && opts.sheetRows <= cell.r) return;
var textMatch = x.match(/<(?:\w+:)?text>([\s\S]*)<\/(?:\w+:)?text>/);
var textMatch = str_match_xml_ns(x, "text");
var rt = !!textMatch && !!textMatch[1] && parse_si(textMatch[1]) || {r:"",t:"",h:""};
comment.r = rt.r;
if(rt.r == "<t></t>") rt.t = rt.h = "";

View File

@ -13,7 +13,7 @@ function fill_vba_xls(cfb, vba) {
vba.FullPaths.forEach(function(p, i) {
if (i == 0)
return;
var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
var newpath = p.replace(/^[\/]*[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
if (newpath.slice(-1) !== "/")
CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
});

View File

@ -2,16 +2,13 @@ function parse_ws_xml_dim(ws/*:Worksheet*/, s/*:string*/) {
var d = safe_decode_range(s);
if(d.s.r<=d.e.r && d.s.c<=d.e.c && d.s.r>=0 && d.s.c>=0) ws["!ref"] = encode_range(d);
}
var mergecregex = /<(?:\w:)?mergeCell ref=["'][A-Z0-9:]+['"]\s*[\/]?>/g;
var sheetdataregex = /<(?:\w+:)?sheetData[^>]*>([\s\S]*)<\/(?:\w+:)?sheetData>/;
var hlinkregex = /<(?:\w:)?hyperlink [^>]*>/mg;
var mergecregex = /<(?:\w+:)?mergeCell ref=["'][A-Z0-9:]+['"]\s*[\/]?>/g;
var hlinkregex = /<(?:\w+:)?hyperlink [^<>]*>/mg;
var dimregex = /"(\w*:\w*)"/;
var colregex = /<(?:\w:)?col\b[^>]*[\/]?>/g;
var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g;
var marginregex= /<(?:\w:)?pageMargins[^>]*\/>/g;
var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
var sheetprregex2= /<(?:\w:)?sheetPr[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetPr)>/;
var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;
var colregex = /<(?:\w+:)?col\b[^<>]*[\/]?>/g;
var afregex = /<(?:\w+:)?autoFilter[^>]*/g;
var marginregex= /<(?:\w+:)?pageMargins[^<>]*\/>/g;
var sheetprregex = /<(?:\w+:)?sheetPr\b[^<>]*?\/>/;
/* 18.3 Worksheets */
function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBProps*/, themes, styles)/*:Worksheet*/ {
@ -24,7 +21,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
var refguess/*:Range*/ = ({s: {r:2000000, c:2000000}, e: {r:0, c:0} }/*:any*/);
var data1 = "", data2 = "";
var mtch/*:?any*/ = data.match(sheetdataregex);
var mtch/*:?any*/ = str_match_xml_ns(data, "sheetData");
if(mtch) {
data1 = data.slice(0, mtch.index);
data2 = data.slice(mtch.index + mtch[0].length);
@ -33,7 +30,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
/* 18.3.1.82 sheetPr CT_SheetPr */
var sheetPr = data1.match(sheetprregex);
if(sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);
else if((sheetPr = data1.match(sheetprregex2))) parse_ws_xml_sheetpr2(sheetPr[0], sheetPr[1]||"", s, wb, idx, styles, themes);
else if((sheetPr = str_match_xml_ns(data1, "sheetPr"))) parse_ws_xml_sheetpr2(sheetPr[0], sheetPr[1]||"", s, wb, idx, styles, themes);
/* 18.3.1.35 dimension CT_SheetDimension */
var ridx = (data1.match(/<(?:\w*:)?dimension/)||{index:-1}).index;
@ -43,7 +40,7 @@ function parse_ws_xml(data/*:?string*/, opts, idx/*:number*/, rels, wb/*:WBWBPro
}
/* 18.3.1.88 sheetViews CT_SheetViews */
var svs = data1.match(svsregex);
var svs = str_match_xml_ns(data1, "sheetViews");
if(svs && svs[1]) parse_ws_xml_sheetviews(svs[1], wb);
/* 18.3.1.17 cols CT_Cols */
@ -242,7 +239,7 @@ function write_ws_xml_autofilter(data, ws, wb, idx)/*:string*/ {
/* 18.3.1.88 sheetViews CT_SheetViews */
/* 18.3.1.87 sheetView CT_SheetView */
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/g;
var sviewregex = /<(?:\w:)?sheetView(?:[^<>a-z][^<>]*)?\/?>/g;
function parse_ws_xml_sheetviews(data, wb/*:WBWBProps*/) {
if(!wb.Views) wb.Views = [{}];
(data.match(sviewregex)||[]).forEach(function(r/*:string*/, i/*:number*/) {
@ -321,7 +318,7 @@ function write_ws_xml_cell(cell/*:Cell*/, ref, ws, opts, idx, wb, date1904)/*:st
var parse_ws_xml_data = /*#__PURE__*/(function() {
var cellregex = /<(?:\w+:)?c[ \/>]/, rowregex = /<\/(?:\w+:)?row>/;
var rregex = /r=["']([^"']*)["']/, isregex = /<(?:\w+:)?is>([\S\s]*?)<\/(?:\w+:)?is>/;
var rregex = /r=["']([^"']*)["']/;
var refregex = /ref=["']([^"']*)["']/;
return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, themes, styles, wb) {
@ -425,7 +422,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
sharedf[parseInt(ftag.si, 10)] = [ftag, ___f, tag.r];
}
}
} else if((cref=d.match(/<f[^>]*\/>/))) {
} else if((cref=d.match(/<f[^<>]*\/>/))) {
ftag = parsexmltag(cref[0]);
if(sharedf[ftag.si]) p.f = shift_formula_xlsx(sharedf[ftag.si][1], sharedf[ftag.si][2]/*[0].ref*/, tag.r);
}
@ -471,7 +468,7 @@ return function parse_ws_xml_data(sdata/*:string*/, s, opts, guess/*:Range*/, th
if(opts.cellHTML) p.h = escapehtml(p.v);
break;
case 'inlineStr':
cref = d.match(isregex);
cref = str_match_xml_ns(d, "is");
p.t = 's';
if(cref != null && (sstr = parse_si(cref[1]))) {
p.v = sstr.t;
@ -636,7 +633,7 @@ function write_ws_xml(idx/*:number*/, opts, wb/*:Workbook*/, rels)/*:string*/ {
if(!l[1].Target) return;
rel = ({"ref":l[0]}/*:any*/);
if(l[1].Target.charAt(0) != "#") {
rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#.*$/, ""), RELS.HLINK);
rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#[\s\S]*$/, ""), RELS.HLINK);
rel["r:id"] = "rId"+rId;
}
if((relc = l[1].Target.indexOf("#")) > -1) rel.location = escapexml(l[1].Target.slice(relc+1));

View File

@ -924,7 +924,7 @@ function write_HLINKS(ba, ws/*:Worksheet*/, rels) {
/* *BrtHLink */
ws['!links'].forEach(function(l) {
if(!l[1].Target) return;
var rId = add_rels(rels, -1, l[1].Target.replace(/#.*$/, ""), RELS.HLINK);
var rId = add_rels(rels, -1, l[1].Target.replace(/#[\s\S]*$/, ""), RELS.HLINK);
write_record(ba, 0x01EE /* BrtHLink */, write_BrtHLink(l, rId));
});
delete ws['!links'];

View File

@ -4,16 +4,16 @@ function parse_Cache(data/*:string*/)/*:[Array<number|string>, string, ?string]*
var f;
/* 21.2.2.150 pt CT_NumVal */
(data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg)||[]).forEach(function(pt) {
var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
(data.match(/<c:pt idx="(\d*)"[^<>\/]*><c:v>([^<])<\/c:v><\/c:pt>/mg)||[]).forEach(function(pt) {
var q = pt.match(/<c:pt idx="(\d*)"[^<>\/]*><c:v>([^<]*)<\/c:v><\/c:pt>/);
if(!q) return;
col[+q[1]] = num ? +q[2] : q[2];
});
/* 21.2.2.71 formatCode CT_Xstring */
var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["","General"])[1]);
var nf = unescapexml((str_match_xml(data, "c:formatCode") || ["","General"])[1]);
(data.match(/<c:f>(.*?)<\/c:f>/mg)||[]).forEach(function(F) { f = F.replace(/<.*?>/g,""); });
(str_match_ng(data, "<c:f>", "</c:f>")||[]).forEach(function(F) { f = F.replace(/<[^<>]*>/g,""); });
return [col, nf, f];
}
@ -28,7 +28,7 @@ function parse_chart(data/*:?string*/, name/*:string*/, opts, rels, wb, csheet)
var refguess = {s: {r:2000000, c:2000000}, e: {r:0, c:0} };
/* 21.2.2.120 numCache CT_NumData */
(data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm)||[]).forEach(function(nc) {
(str_match_ng(data, "<c:numCache>", "</c:numCache>")||[]).forEach(function(nc) {
var cache = parse_Cache(nc);
refguess.s.r = refguess.s.c = 0;
refguess.e.c = C;

View File

@ -1,5 +1,5 @@
var attregexg2=/([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
var attregex2=/([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
var attregexg2=/\b((?:\w+:)?[\w]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
var attregex2=/\b((?:\w+:)?[\w]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
function xlml_parsexmltag(tag/*:string*/, skip_root/*:?boolean*/) {
var words = tag.split(/\s+/);
var z/*:any*/ = ([]/*:any*/); if(!skip_root) z[0] = words[0];
@ -112,7 +112,7 @@ function parse_xlml_data(xml, ss, data, cell/*:any*/, base, styles, csty, row, a
break;
case 'String':
cell.t = 's'; cell.r = xlml_fixstr(unescapexml(xml));
cell.v = (xml.indexOf("<") > -1 ? unescapexml(ss||xml).replace(/<.*?>/g, "") : cell.r); // todo: BR etc
cell.v = (xml.indexOf("<") > -1 ? unescapexml(ss||xml).replace(/<[^<>]*>/g, "") : cell.r); // todo: BR etc
break;
case 'DateTime':
if(xml.slice(-1) != "Z") xml += "Z";

View File

@ -8,7 +8,7 @@ function html_to_sheet(str/*:string*/, _opts)/*:Workbook*/ {
if(!mtch) throw new Error("Invalid HTML: could not find <table>");
var mtch2/*:any*/ = str.match(/<\/table/i);
var i/*:number*/ = mtch.index, j/*:number*/ = mtch2 && mtch2.index || str.length;
var rows = split_regex(str.slice(i, j), /(:?<tr[^>]*>)/i, "<tr>");
var rows = split_regex(str.slice(i, j), /(:?<tr[^<>]*>)/i, "<tr>");
var R = -1, C = 0, RS = 0, CS = 0;
var range/*:Range*/ = {s:{r:10000000, c:10000000},e:{r:0,c:0}};
var merges/*:Array<Range>*/ = [];
@ -99,7 +99,7 @@ var HTML_BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export
var HTML_END = '</body></html>';
function html_to_workbook(str/*:string*/, opts)/*:Workbook*/ {
var mtch = str.match(/<table[\s\S]*?>[\s\S]*?<\/table>/gi);
var mtch = str_match_xml_ig(str, "table");
if(!mtch || mtch.length == 0) throw new Error("Invalid HTML: could not find <table>");
if(mtch.length == 1) {
var w = sheet_to_workbook(html_to_sheet(mtch[0], opts), opts);

View File

@ -5,9 +5,9 @@ function parse_text_p(text/*:string*//*::, tag*/)/*:Array<any>*/ {
.replace(/[\t\r\n]/g, " ").trim().replace(/ +/g, " ")
.replace(/<text:s\/>/g," ")
.replace(/<text:s text:c="(\d+)"\/>/g, function($$,$1) { return Array(parseInt($1,10)+1).join(" "); })
.replace(/<text:tab[^>]*\/>/g,"\t")
.replace(/<text:tab[^<>]*\/>/g,"\t")
.replace(/<text:line-break\/>/g,"\n");
var v = unescapexml(fixed.replace(/<[^>]*>/g,""));
var v = unescapexml(fixed.replace(/<[^<>]*>/g,""));
return [v];
}
@ -17,10 +17,10 @@ function parse_ods_styles(d/*:string*/, _opts, _nfm) {
var number_format_map = _nfm || {};
var str = xlml_normalize(d);
xlmlregex.lastIndex = 0;
str = str_remove_ng(str, "<!--", "-->").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
str = remove_doctype(str_remove_ng(str, "<!--", "-->"));
var Rn, NFtag, NF = "", tNF = "", y, etpos = 0, tidx = -1, infmt = false, payload = "";
while((Rn = xlmlregex.exec(str))) {
switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
switch((Rn[3]=Rn[3].replace(/_[\s\S]*$/,""))) {
/* Number Format Definitions */
case 'number-style': // <number:number-style> 16.29.2
case 'currency-style': // <number:currency-style> 16.29.8
@ -264,8 +264,8 @@ function parse_content_xml(d/*:string*/, _opts, _nfm)/*:Workbook*/ {
var isstub = false, intable = false;
var i = 0;
xlmlregex.lastIndex = 0;
str = str_remove_ng(str, "<!--", "-->").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm,"");
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_.*$/,""))) {
str = remove_doctype(str_remove_ng(str, "<!--", "-->"));
while((Rn = xlmlregex.exec(str))) switch((Rn[3]=Rn[3].replace(/_[\s\S]*$/,""))) {
case 'table': case '工作表': // 9.1.2 <table:table>
if(Rn[1]==='/') {

View File

@ -67,7 +67,7 @@ function write_number_format_ods(nf/*:string*/, nfidx/*:string*/)/*:string*/ {
if((t=nf.match(/# (\?+)\/(\d+)/))) { payload += writextag("number:fraction", null, {"number:min-integer-digits":0, "number:min-numerator-digits": t[1].length, "number:denominator-value": +t[2]}); break j; }
/* percentages */
if((t=nf.match(/(\d+)(|\.\d+)%/))) { type = "percentage"; payload += writextag("number:number", null, {"number:decimal-places": t[2] && t.length - 1 || 0, "number:min-decimal-places": t[2] && t.length - 1 || 0, "number:min-integer-digits": t[1].length }) + "<number:text>%</number:text>"; break j; }
if((t=nf.match(/\b(\d+)(|\.\d+)%/))) { type = "percentage"; payload += writextag("number:number", null, {"number:decimal-places": t[2] && t.length - 1 || 0, "number:min-decimal-places": t[2] && t.length - 1 || 0, "number:min-integer-digits": t[1].length }) + "<number:text>%</number:text>"; break j; }
/* datetime */
var has_time = false;
@ -196,7 +196,7 @@ function write_names_ods(Names, SheetNames, idx) {
return " " + writextag("table:named-range", null, {
"table:name": name.Name,
"table:cell-range-address": odsref,
"table:base-cell-address": odsref.replace(/[\.]?[^\.]*$/, ".$A$1")
"table:base-cell-address": odsref.replace(/[\.][^\.]*$/, ".$A$1")
});
}).join("\n") + "\n </table:named-expressions>\n";
}
@ -436,7 +436,7 @@ var write_content_ods/*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */(function
if(opts.bookType == "fods") {
o.push('<office:document' + attr + fods + '>\n');
o.push(write_meta_ods().replace(/<office:document-meta.*?>/, "").replace(/<\/office:document-meta>/, "") + "\n");
o.push(write_meta_ods().replace(/<office:document-meta[^<>]*?>/, "").replace(/<\/office:document-meta>/, "") + "\n");
// TODO: settings (equiv of settings.xml for ODS)
} else o.push('<office:document-content' + attr + '>\n');
// o.push(' <office:scripts/>\n');

View File

@ -1512,7 +1512,7 @@ function numbers_add_meta(mlist, newid, newloc) {
mlist[3].push({ type: 2, data: write_shallow([
[],
[{ type: 0, data: write_varint49(newid) }],
[{ type: 2, data: stru8(newloc.replace(/-.*$/, "")) }],
[{ type: 2, data: stru8(newloc.replace(/-[\s\S]*$/, "")) }],
[{ type: 2, data: stru8(newloc) }],
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],

View File

@ -204,7 +204,7 @@ function parse_zip(zip/*:ZIP*/, opts/*:?ParseOpts*/)/*:Workbook*/ {
if(wbrels && wbrels[i]) {
path = 'xl/' + (wbrels[i][1]).replace(/[\/]?xl\//, "");
if(!safegetzipfile(zip, path)) path = wbrels[i][1];
if(!safegetzipfile(zip, path)) path = wbrelsfile.replace(/_rels\/.*$/,"") + wbrels[i][1];
if(!safegetzipfile(zip, path)) path = wbrelsfile.replace(/_rels\/[\S\s]*$/,"") + wbrels[i][1];
stype = wbrels[i][2];
} else {
path = 'xl/worksheets/sheet'+(i+1-nmode)+"." + wbext;

View File

@ -309,9 +309,9 @@ function book_append_sheet(wb/*:Workbook*/, ws/*:Worksheet*/, name/*:?string*/,
if(!name) for(; i <= 0xFFFF; ++i, name = undefined) if(wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break;
if(!name || wb.SheetNames.length >= 0xFFFF) throw new Error("Too many worksheets");
if(roll && wb.SheetNames.indexOf(name) >= 0 && name.length < 32) {
var m = name.match(/(^.*?)(\d+)$/);
i = m && +m[2] || 0;
var root = m && m[1] || name;
var m = name.match(/\d+$/); // at this point, name length is capped at 32
i = m && +m[0] || 0;
var root = m && name.slice(0, m.index) || name;
for(++i; i <= 0xFFFF; ++i) if(wb.SheetNames.indexOf(name = root + i) == -1) break;
}
check_ws_name(name);

32
dist/xlsx.core.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.core.min.map generated vendored

File diff suppressed because one or more lines are too long

4129
dist/xlsx.extendscript.js generated vendored

File diff suppressed because it is too large Load Diff

34
dist/xlsx.full.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.full.min.map generated vendored

File diff suppressed because one or more lines are too long

18
dist/xlsx.mini.min.js generated vendored

File diff suppressed because one or more lines are too long

2
dist/xlsx.mini.min.map generated vendored

File diff suppressed because one or more lines are too long

View File

@ -60,9 +60,9 @@ function Base64_decode(input: string): string {
var o = "";
var c1=0, c2=0, c3=0, e1=0, e2=0, e3=0, e4=0;
if(input.slice(0,5) == "data:") {
var i = input.slice(0, 1024).indexOf(";base64,");
if(i > -1) input = input.slice(i+8);
}
var i = input.slice(0, 1024).indexOf(";base64,");
if(i > -1) input = input.slice(i+8);
}
input = input.replace(/[^\w\+\/\=]/g, "");
for(var i = 0; i < input.length;) {
e1 = Base64_map.indexOf(input.charAt(i++));

View File

@ -13,7 +13,7 @@ function fill_vba_xls(cfb, vba) {
vba.FullPaths.forEach(function(p, i) {
if (i == 0)
return;
var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
var newpath = p.replace(/^[\/]*[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
if (newpath.slice(-1) !== "/")
CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
});

View File

@ -16,7 +16,7 @@ function make_vba_xls(cfb: CFBModule.CFB$Container) {
function fill_vba_xls(cfb: CFBModule.CFB$Container, vba: CFBModule.CFB$Container): void {
vba.FullPaths.forEach(function(p, i) {
if(i == 0) return;
var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
var newpath = p.replace(/^[\/]*[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
if(newpath.slice(-1) !== "/") CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
});
}

View File

@ -1512,7 +1512,7 @@ function numbers_add_meta(mlist, newid, newloc) {
mlist[3].push({ type: 2, data: write_shallow([
[],
[{ type: 0, data: write_varint49(newid) }],
[{ type: 2, data: stru8(newloc.replace(/-.*$/, "")) }],
[{ type: 2, data: stru8(newloc.replace(/-[\s\S]*$/, "")) }],
[{ type: 2, data: stru8(newloc) }],
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],
[{ type: 2, data: new Uint8Array([2, 0, 0]) }],

View File

@ -1281,7 +1281,7 @@ function numbers_iwa_find(cfb: CFB$Container, deps: Dependents, id: number) {
function numbers_add_meta(mlist: ProtoMessage, newid: number, newloc: string) {
mlist[3].push({type: 2, data: write_shallow([ [],
[{type: 0, data: write_varint49(newid)}],
[{type: 2, data: stru8(newloc.replace(/-.*$/, "")) }],
[{type: 2, data: stru8(newloc.replace(/-[\s\S]*$/, "")) }],
[{type: 2, data: stru8(newloc)}],
[{type: 2, data: new Uint8Array([2, 0, 0])}],
[{type: 2, data: new Uint8Array([2, 0, 0])}],

File diff suppressed because it is too large Load Diff

24
xlsx.full.min.js vendored Normal file

File diff suppressed because one or more lines are too long

4129
xlsx.js generated

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

4129
xlsx.mjs generated

File diff suppressed because it is too large Load Diff