From efb96a2c2c0bd9cfde952aa20555991344ec5c9e Mon Sep 17 00:00:00 2001 From: Ross Johnson Date: Sun, 5 Sep 2021 13:24:57 -0400 Subject: [PATCH] Use Buffer.copy() if available to write file contents to final CFB Buf --- bits/05_buf.js | 2 +- bits/67_stream.js | 10 ++++++++-- bits/68_mini.js | 17 ++++++++++++++--- cfb.flow.js | 29 +++++++++++++++++++++++------ cfb.js | 29 +++++++++++++++++++++++------ xlscfb.flow.js | 27 ++++++++++++++++++++++----- xlscfb.js | 27 ++++++++++++++++++++++----- 7 files changed, 113 insertions(+), 28 deletions(-) diff --git a/bits/05_buf.js b/bits/05_buf.js index 217e5ac..378e99b 100644 --- a/bits/05_buf.js +++ b/bits/05_buf.js @@ -7,7 +7,7 @@ if(typeof Buffer !== 'undefined') { if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; } Buffer_from = /*::((*/nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer)/*::) :any)*/; // $FlowIgnore - if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; + if(!Buffer.alloc) Buffer.alloc = function(n) { var b = new Buffer(n); b.fill(0); return b; }; // $FlowIgnore if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); }; } diff --git a/bits/67_stream.js b/bits/67_stream.js index cdb26ce..932a29b 100644 --- a/bits/67_stream.js +++ b/bits/67_stream.js @@ -3,7 +3,13 @@ /*:: if(!file.content) throw new Error("unreachable"); */ if(file.size >= 0x1000) { o.l = (file.start+1) << 9; - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x1FF; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 511) & -512; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x1FF; ++j) o.write_shift(1, 0); + } } } diff --git a/bits/68_mini.js b/bits/68_mini.js index 9b080b2..fad30a9 100644 --- a/bits/68_mini.js +++ b/bits/68_mini.js @@ -2,8 +2,19 @@ file = cfb.FileIndex[i]; /*:: if(!file.content) throw new Error("unreachable"); */ if(file.size > 0 && file.size < 0x1000) { - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x3F; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 63) & -64; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x3F; ++j) o.write_shift(1, 0); + } } } - while(o.l < o.length) o.write_shift(1, 0); + if (has_buf) { + o.l = o.length; + } else { + // When using Buffer, already 0-filled + while(o.l < o.length) o.write_shift(1, 0); + } diff --git a/cfb.flow.js b/cfb.flow.js index d884851..3cc8e23 100644 --- a/cfb.flow.js +++ b/cfb.flow.js @@ -57,7 +57,7 @@ if(typeof Buffer !== 'undefined') { if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; } Buffer_from = /*::((*/nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer)/*::) :any)*/; // $FlowIgnore - if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; + if(!Buffer.alloc) Buffer.alloc = function(n) { var b = new Buffer(n); b.fill(0); return b; }; // $FlowIgnore if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); }; } @@ -936,19 +936,36 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|strin /*:: if(!file.content) throw new Error("unreachable"); */ if(file.size >= 0x1000) { o.l = (file.start+1) << 9; - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x1FF; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 511) & -512; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x1FF; ++j) o.write_shift(1, 0); + } } } for(i = 1; i < cfb.FileIndex.length; ++i) { file = cfb.FileIndex[i]; /*:: if(!file.content) throw new Error("unreachable"); */ if(file.size > 0 && file.size < 0x1000) { - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x3F; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 63) & -64; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x3F; ++j) o.write_shift(1, 0); + } } } - while(o.l < o.length) o.write_shift(1, 0); + if (has_buf) { + o.l = o.length; + } else { + // When using Buffer, already 0-filled + while(o.l < o.length) o.write_shift(1, 0); + } return o; } /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ diff --git a/cfb.js b/cfb.js index a3b5550..c4267b2 100644 --- a/cfb.js +++ b/cfb.js @@ -57,7 +57,7 @@ if(typeof Buffer !== 'undefined') { if(!nbfs) try { Buffer.from("foo", "utf8"); } catch(e) { nbfs = true; } Buffer_from = nbfs ? function(buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); } : Buffer.from.bind(Buffer); // $FlowIgnore - if(!Buffer.alloc) Buffer.alloc = function(n) { return new Buffer(n); }; + if(!Buffer.alloc) Buffer.alloc = function(n) { var b = new Buffer(n); b.fill(0); return b; }; // $FlowIgnore if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n) { return new Buffer(n); }; } @@ -914,18 +914,35 @@ flen = file.content.length; file = cfb.FileIndex[i]; if(file.size >= 0x1000) { o.l = (file.start+1) << 9; - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x1FF; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 511) & -512; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x1FF; ++j) o.write_shift(1, 0); + } } } for(i = 1; i < cfb.FileIndex.length; ++i) { file = cfb.FileIndex[i]; if(file.size > 0 && file.size < 0x1000) { - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x3F; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 63) & -64; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x3F; ++j) o.write_shift(1, 0); + } } } - while(o.l < o.length) o.write_shift(1, 0); + if (has_buf) { + o.l = o.length; + } else { + // When using Buffer, already 0-filled + while(o.l < o.length) o.write_shift(1, 0); + } return o; } /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ diff --git a/xlscfb.flow.js b/xlscfb.flow.js index 9991d94..1eb3a01 100644 --- a/xlscfb.flow.js +++ b/xlscfb.flow.js @@ -784,19 +784,36 @@ function _write(cfb/*:CFBContainer*/, options/*:CFBWriteOpts*/)/*:RawBytes|strin /*:: if(!file.content) throw new Error("unreachable"); */ if(file.size >= 0x1000) { o.l = (file.start+1) << 9; - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x1FF; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 511) & -512; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x1FF; ++j) o.write_shift(1, 0); + } } } for(i = 1; i < cfb.FileIndex.length; ++i) { file = cfb.FileIndex[i]; /*:: if(!file.content) throw new Error("unreachable"); */ if(file.size > 0 && file.size < 0x1000) { - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x3F; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 63) & -64; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x3F; ++j) o.write_shift(1, 0); + } } } - while(o.l < o.length) o.write_shift(1, 0); + if (has_buf) { + o.l = o.length; + } else { + // When using Buffer, already 0-filled + while(o.l < o.length) o.write_shift(1, 0); + } return o; } /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */ diff --git a/xlscfb.js b/xlscfb.js index ba81cd4..6ec3b27 100644 --- a/xlscfb.js +++ b/xlscfb.js @@ -746,18 +746,35 @@ flen = file.content.length; file = cfb.FileIndex[i]; if(file.size >= 0x1000) { o.l = (file.start+1) << 9; - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x1FF; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 511) & -512; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x1FF; ++j) o.write_shift(1, 0); + } } } for(i = 1; i < cfb.FileIndex.length; ++i) { file = cfb.FileIndex[i]; if(file.size > 0 && file.size < 0x1000) { - for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); - for(; j & 0x3F; ++j) o.write_shift(1, 0); + if (has_buf && Buffer.isBuffer(file.content)) { + file.content.copy(o, o.l, 0, file.size); + // o is a 0-filled Buffer so just set next offset + o.l += (file.size + 63) & -64; + } else { + for(j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]); + for(; j & 0x3F; ++j) o.write_shift(1, 0); + } } } - while(o.l < o.length) o.write_shift(1, 0); + if (has_buf) { + o.l = o.length; + } else { + // When using Buffer, already 0-filled + while(o.l < o.length) o.write_shift(1, 0); + } return o; } /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */