mirror of
https://github.com/PrivateBin/PrivateBin.git
synced 2025-08-07 22:12:35 -04:00
drop legacy paste format support
remove support for ZeroBin & v1 pastes and base64 & rawinflate libraries
This commit is contained in:
parent
03e0c81fbf
commit
6d5323e351
14 changed files with 18 additions and 1272 deletions
|
@ -1,7 +1,9 @@
|
||||||
# PrivateBin version history
|
# PrivateBin version history
|
||||||
|
|
||||||
## 2.0.0 (not yet released)
|
## 2.0.0 (not yet released)
|
||||||
* CHANGED: Remove page template (#265)
|
* CHANGED: Removed page template (#265)
|
||||||
|
* CHANGED: Removed support for ZeroBin & v1 pastes - since release 1.3 the v2 format is used (#551)
|
||||||
|
* CHANGED: Removed use of base64 & rawinflate libraries (#551)
|
||||||
* FIXED: Name mismatches in attached files (#1584)
|
* FIXED: Name mismatches in attached files (#1584)
|
||||||
* FIXED: Unable to paste attachments from clipboard (#1589)
|
* FIXED: Unable to paste attachments from clipboard (#1589)
|
||||||
|
|
||||||
|
|
|
@ -12,9 +12,7 @@ Data is encrypted and decrypted in the browser using 256bit AES in
|
||||||
This is a fork of ZeroBin, originally developed by
|
This is a fork of ZeroBin, originally developed by
|
||||||
[Sébastien Sauvage](https://github.com/sebsauvage/ZeroBin). PrivateBin was
|
[Sébastien Sauvage](https://github.com/sebsauvage/ZeroBin). PrivateBin was
|
||||||
refactored to allow easier and cleaner extensions and has many additional
|
refactored to allow easier and cleaner extensions and has many additional
|
||||||
features. It is, however, still fully compatible to the original ZeroBin 0.19
|
features.
|
||||||
data storage scheme. Therefore, such installations can be upgraded to PrivateBin
|
|
||||||
without losing any data.
|
|
||||||
|
|
||||||
## What PrivateBin provides
|
## What PrivateBin provides
|
||||||
|
|
||||||
|
|
|
@ -124,11 +124,6 @@ languageselection = false
|
||||||
; The recommended and default used CSP is:
|
; The recommended and default used CSP is:
|
||||||
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; frame-src blob:; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads"
|
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'wasm-unsafe-eval'; style-src 'self'; font-src 'self'; frame-ancestors 'none'; frame-src blob:; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads"
|
||||||
|
|
||||||
; stay compatible with PrivateBin Alpha 0.19, less secure
|
|
||||||
; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
|
|
||||||
; sha256 in HMAC for the deletion token
|
|
||||||
; zerobincompatibility = false
|
|
||||||
|
|
||||||
; Enable or disable the warning message when the site is served over an insecure
|
; Enable or disable the warning message when the site is served over an insecure
|
||||||
; connection (insecure HTTP instead of HTTPS), defaults to true.
|
; connection (insecure HTTP instead of HTTPS), defaults to true.
|
||||||
; Secure transport methods like Tor and I2P domains are automatically whitelisted.
|
; Secure transport methods like Tor and I2P domains are automatically whitelisted.
|
||||||
|
|
237
js/base64-1.7.js
237
js/base64-1.7.js
|
@ -1,237 +0,0 @@
|
||||||
/*
|
|
||||||
* $Id: base64.js,v 1.7 2012/08/23 10:30:18 dankogai Exp dankogai $
|
|
||||||
*
|
|
||||||
* Licensed under the MIT license.
|
|
||||||
* https://www.opensource.org/licenses/mit-license.php
|
|
||||||
*
|
|
||||||
* References:
|
|
||||||
* https://en.wikipedia.org/wiki/Base64
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(global){
|
|
||||||
|
|
||||||
var b64chars
|
|
||||||
= 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
||||||
|
|
||||||
var b64charcodes = function(){
|
|
||||||
var a = [];
|
|
||||||
var codeA = 'A'.charCodeAt(0);
|
|
||||||
var codea = 'a'.charCodeAt(0);
|
|
||||||
var code0 = '0'.charCodeAt(0);
|
|
||||||
for (var i = 0; i < 26; i ++) a.push(codeA + i);
|
|
||||||
for (var i = 0; i < 26; i ++) a.push(codea + i);
|
|
||||||
for (var i = 0; i < 10; i ++) a.push(code0 + i);
|
|
||||||
a.push('+'.charCodeAt(0));
|
|
||||||
a.push('/'.charCodeAt(0));
|
|
||||||
return a;
|
|
||||||
}();
|
|
||||||
|
|
||||||
var b64tab = function(bin){
|
|
||||||
var t = {};
|
|
||||||
for (var i = 0, l = bin.length; i < l; i++) t[bin.charAt(i)] = i;
|
|
||||||
return t;
|
|
||||||
}(b64chars);
|
|
||||||
|
|
||||||
var stringToArray = function(s){
|
|
||||||
var a = [];
|
|
||||||
for (var i = 0, l = s.length; i < l; i ++) a[i] = s.charCodeAt(i);
|
|
||||||
return a;
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF8ArrayToBase64 = function(bin){
|
|
||||||
var padlen = 0;
|
|
||||||
while (bin.length % 3){
|
|
||||||
bin.push(0);
|
|
||||||
padlen++;
|
|
||||||
};
|
|
||||||
var b64 = [];
|
|
||||||
for (var i = 0, l = bin.length; i < l; i += 3){
|
|
||||||
var c0 = bin[i], c1 = bin[i+1], c2 = bin[i+2];
|
|
||||||
if (c0 >= 256 || c1 >= 256 || c2 >= 256)
|
|
||||||
throw 'unsupported character found';
|
|
||||||
var n = (c0 << 16) | (c1 << 8) | c2;
|
|
||||||
b64.push(
|
|
||||||
b64charcodes[ n >>> 18],
|
|
||||||
b64charcodes[(n >>> 12) & 63],
|
|
||||||
b64charcodes[(n >>> 6) & 63],
|
|
||||||
b64charcodes[ n & 63]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
while (padlen--) b64[b64.length - padlen - 1] = '='.charCodeAt(0);
|
|
||||||
return chunkStringFromCharCodeApply(b64);
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertBase64ToUTF8Array = function(b64){
|
|
||||||
b64 = b64.replace(/[^A-Za-z0-9+\/]+/g, '');
|
|
||||||
var bin = [];
|
|
||||||
var padlen = b64.length % 4;
|
|
||||||
for (var i = 0, l = b64.length; i < l; i += 4){
|
|
||||||
var n = ((b64tab[b64.charAt(i )] || 0) << 18)
|
|
||||||
| ((b64tab[b64.charAt(i+1)] || 0) << 12)
|
|
||||||
| ((b64tab[b64.charAt(i+2)] || 0) << 6)
|
|
||||||
| ((b64tab[b64.charAt(i+3)] || 0));
|
|
||||||
bin.push(
|
|
||||||
( n >> 16 ),
|
|
||||||
( (n >> 8) & 0xff ),
|
|
||||||
( n & 0xff )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
bin.length -= [0,0,2,1][padlen];
|
|
||||||
return bin;
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF16ArrayToUTF8Array = function(uni){
|
|
||||||
var bin = [];
|
|
||||||
for (var i = 0, l = uni.length; i < l; i++){
|
|
||||||
var n = uni[i];
|
|
||||||
if (n < 0x80)
|
|
||||||
bin.push(n);
|
|
||||||
else if (n < 0x800)
|
|
||||||
bin.push(
|
|
||||||
0xc0 | (n >>> 6),
|
|
||||||
0x80 | (n & 0x3f));
|
|
||||||
else
|
|
||||||
bin.push(
|
|
||||||
0xe0 | ((n >>> 12) & 0x0f),
|
|
||||||
0x80 | ((n >>> 6) & 0x3f),
|
|
||||||
0x80 | (n & 0x3f));
|
|
||||||
}
|
|
||||||
return bin;
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF8ArrayToUTF16Array = function(bin){
|
|
||||||
var uni = [];
|
|
||||||
for (var i = 0, l = bin.length; i < l; i++){
|
|
||||||
var c0 = bin[i];
|
|
||||||
if (c0 < 0x80){
|
|
||||||
uni.push(c0);
|
|
||||||
}else{
|
|
||||||
var c1 = bin[++i];
|
|
||||||
if (c0 < 0xe0){
|
|
||||||
uni.push(((c0 & 0x1f) << 6) | (c1 & 0x3f));
|
|
||||||
}else{
|
|
||||||
var c2 = bin[++i];
|
|
||||||
uni.push(
|
|
||||||
((c0 & 0x0f) << 12) | ((c1 & 0x3f) << 6) | (c2 & 0x3f)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return uni;
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF8StringToBase64 = function(bin){
|
|
||||||
return convertUTF8ArrayToBase64(stringToArray(bin));
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertBase64ToUTF8String = function(b64){
|
|
||||||
return chunkStringFromCharCodeApply(convertBase64ToUTF8Array(b64));
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF8StringToUTF16Array = function(bin){
|
|
||||||
return convertUTF8ArrayToUTF16Array(stringToArray(bin));
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF8ArrayToUTF16String = function(bin){
|
|
||||||
return chunkStringFromCharCodeApply(convertUTF8ArrayToUTF16Array(bin));
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF8StringToUTF16String = function(bin){
|
|
||||||
return chunkStringFromCharCodeApply(
|
|
||||||
convertUTF8ArrayToUTF16Array(stringToArray(bin))
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF16StringToUTF8Array = function(uni){
|
|
||||||
return convertUTF16ArrayToUTF8Array(stringToArray(uni));
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF16ArrayToUTF8String = function(uni){
|
|
||||||
return chunkStringFromCharCodeApply(convertUTF16ArrayToUTF8Array(uni));
|
|
||||||
};
|
|
||||||
|
|
||||||
var convertUTF16StringToUTF8String = function(uni){
|
|
||||||
return chunkStringFromCharCodeApply(
|
|
||||||
convertUTF16ArrayToUTF8Array(stringToArray(uni))
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* String.fromCharCode.apply will only handle arrays as big as 65536,
|
|
||||||
* after that it'll return a truncated string with no warning.
|
|
||||||
*/
|
|
||||||
var chunkStringFromCharCodeApply = function(arr){
|
|
||||||
var strs = [], i;
|
|
||||||
for (i = 0; i < arr.length; i += 65536){
|
|
||||||
strs.push(String.fromCharCode.apply(String, arr.slice(i, i+65536)));
|
|
||||||
}
|
|
||||||
return strs.join('');
|
|
||||||
};
|
|
||||||
|
|
||||||
if (global.btoa){
|
|
||||||
var btoa = global.btoa;
|
|
||||||
var convertUTF16StringToBase64 = function (uni){
|
|
||||||
return btoa(convertUTF16StringToUTF8String(uni));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var btoa = convertUTF8StringToBase64;
|
|
||||||
var convertUTF16StringToBase64 = function (uni){
|
|
||||||
return convertUTF8ArrayToBase64(convertUTF16StringToUTF8Array(uni));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (global.atob){
|
|
||||||
var atob = global.atob;
|
|
||||||
var convertBase64ToUTF16String = function (b64){
|
|
||||||
return convertUTF8StringToUTF16String(atob(b64));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
var atob = convertBase64ToUTF8String;
|
|
||||||
var convertBase64ToUTF16String = function (b64){
|
|
||||||
return convertUTF8ArrayToUTF16String(convertBase64ToUTF8Array(b64));
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
global.Base64 = {
|
|
||||||
convertUTF8ArrayToBase64:convertUTF8ArrayToBase64,
|
|
||||||
convertByteArrayToBase64:convertUTF8ArrayToBase64,
|
|
||||||
convertBase64ToUTF8Array:convertBase64ToUTF8Array,
|
|
||||||
convertBase64ToByteArray:convertBase64ToUTF8Array,
|
|
||||||
convertUTF16ArrayToUTF8Array:convertUTF16ArrayToUTF8Array,
|
|
||||||
convertUTF16ArrayToByteArray:convertUTF16ArrayToUTF8Array,
|
|
||||||
convertUTF8ArrayToUTF16Array:convertUTF8ArrayToUTF16Array,
|
|
||||||
convertByteArrayToUTF16Array:convertUTF8ArrayToUTF16Array,
|
|
||||||
convertUTF8StringToBase64:convertUTF8StringToBase64,
|
|
||||||
convertBase64ToUTF8String:convertBase64ToUTF8String,
|
|
||||||
convertUTF8StringToUTF16Array:convertUTF8StringToUTF16Array,
|
|
||||||
convertUTF8ArrayToUTF16String:convertUTF8ArrayToUTF16String,
|
|
||||||
convertByteArrayToUTF16String:convertUTF8ArrayToUTF16String,
|
|
||||||
convertUTF8StringToUTF16String:convertUTF8StringToUTF16String,
|
|
||||||
convertUTF16StringToUTF8Array:convertUTF16StringToUTF8Array,
|
|
||||||
convertUTF16StringToByteArray:convertUTF16StringToUTF8Array,
|
|
||||||
convertUTF16ArrayToUTF8String:convertUTF16ArrayToUTF8String,
|
|
||||||
convertUTF16StringToUTF8String:convertUTF16StringToUTF8String,
|
|
||||||
convertUTF16StringToBase64:convertUTF16StringToBase64,
|
|
||||||
convertBase64ToUTF16String:convertBase64ToUTF16String,
|
|
||||||
fromBase64:convertBase64ToUTF8String,
|
|
||||||
toBase64:convertUTF8StringToBase64,
|
|
||||||
atob:atob,
|
|
||||||
btoa:btoa,
|
|
||||||
utob:convertUTF16StringToUTF8String,
|
|
||||||
btou:convertUTF8StringToUTF16String,
|
|
||||||
encode:convertUTF16StringToBase64,
|
|
||||||
encodeURI:function(u){
|
|
||||||
return convertUTF16StringToBase64(u).replace(/[+\/]/g, function(m0){
|
|
||||||
return m0 == '+' ? '-' : '_';
|
|
||||||
}).replace(/=+$/, '');
|
|
||||||
},
|
|
||||||
decode:function(a){
|
|
||||||
return convertBase64ToUTF16String(a.replace(/[-_]/g, function(m0){
|
|
||||||
return m0 == '-' ? '+' : '/';
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
})(this);
|
|
|
@ -10,7 +10,6 @@ global.WebCrypto = require('@peculiar/webcrypto').Crypto;
|
||||||
|
|
||||||
// application libraries to test
|
// application libraries to test
|
||||||
global.$ = global.jQuery = require('./jquery-3.7.1');
|
global.$ = global.jQuery = require('./jquery-3.7.1');
|
||||||
global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
|
|
||||||
global.zlib = require('./zlib-1.3.1-1').zlib;
|
global.zlib = require('./zlib-1.3.1-1').zlib;
|
||||||
require('./prettify');
|
require('./prettify');
|
||||||
global.prettyPrint = window.PR.prettyPrint;
|
global.prettyPrint = window.PR.prettyPrint;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* @namespace
|
* @namespace
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// global Base64, DOMPurify, FileReader, RawDeflate, history, navigator, prettyPrint, prettyPrintOne, showdown, kjua
|
// global Base64, DOMPurify, FileReader, history, navigator, prettyPrint, prettyPrintOne, showdown, kjua
|
||||||
|
|
||||||
jQuery.fn.draghover = function() {
|
jQuery.fn.draghover = function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -41,7 +41,7 @@ jQuery(document).ready(function() {
|
||||||
$.PrivateBin.Controller.init();
|
$.PrivateBin.Controller.init();
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery.PrivateBin = (function($, RawDeflate) {
|
jQuery.PrivateBin = (function($) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1119,39 +1119,17 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
*/
|
*/
|
||||||
async function decompress(data, mode, zlib)
|
async function decompress(data, mode, zlib)
|
||||||
{
|
{
|
||||||
if (mode === 'zlib' || mode === 'none') {
|
if (mode === 'zlib') {
|
||||||
if (mode === 'zlib') {
|
if (typeof zlib === 'undefined') {
|
||||||
if (typeof zlib === 'undefined') {
|
throw 'Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.'
|
||||||
throw 'Error decompressing paste, your browser does not support WebAssembly. Please use another browser to view this paste.'
|
|
||||||
}
|
|
||||||
data = zlib.inflate(
|
|
||||||
new Uint8Array(data)
|
|
||||||
).buffer;
|
|
||||||
}
|
}
|
||||||
return utf8To16(
|
data = zlib.inflate(
|
||||||
arraybufferToString(data)
|
new Uint8Array(data)
|
||||||
);
|
).buffer;
|
||||||
}
|
|
||||||
// detect presence of Base64.js, indicating legacy ZeroBin paste
|
|
||||||
if (typeof Base64 === 'undefined') {
|
|
||||||
return utf8To16(
|
|
||||||
RawDeflate.inflate(
|
|
||||||
utf8To16(
|
|
||||||
atob(
|
|
||||||
arraybufferToString(data)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return Base64.btou(
|
|
||||||
RawDeflate.inflate(
|
|
||||||
Base64.fromBase64(
|
|
||||||
arraybufferToString(data)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
return utf8To16(
|
||||||
|
arraybufferToString(data)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1191,19 +1169,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
{
|
{
|
||||||
let keyArray = stringToArraybuffer(key);
|
let keyArray = stringToArraybuffer(key);
|
||||||
if (password.length > 0) {
|
if (password.length > 0) {
|
||||||
// version 1 pastes did append the passwords SHA-256 hash in hex
|
|
||||||
if (spec[7] === 'rawdeflate') {
|
|
||||||
let passwordBuffer = await window.crypto.subtle.digest(
|
|
||||||
{name: 'SHA-256'},
|
|
||||||
stringToArraybuffer(
|
|
||||||
utf16To8(password)
|
|
||||||
)
|
|
||||||
).catch(Alert.showError);
|
|
||||||
password = Array.prototype.map.call(
|
|
||||||
new Uint8Array(passwordBuffer),
|
|
||||||
x => ('00' + x.toString(16)).slice(-2)
|
|
||||||
).join('');
|
|
||||||
}
|
|
||||||
let passwordArray = stringToArraybuffer(password),
|
let passwordArray = stringToArraybuffer(password),
|
||||||
newKeyArray = new Uint8Array(keyArray.length + passwordArray.length);
|
newKeyArray = new Uint8Array(keyArray.length + passwordArray.length);
|
||||||
newKeyArray.set(keyArray, 0);
|
newKeyArray.set(keyArray, 0);
|
||||||
|
@ -1337,21 +1302,6 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
// clone the array instead of passing the reference
|
// clone the array instead of passing the reference
|
||||||
spec = (data[1][0] instanceof Array ? data[1][0] : data[1]).slice();
|
spec = (data[1][0] instanceof Array ? data[1][0] : data[1]).slice();
|
||||||
cipherMessage = data[0];
|
cipherMessage = data[0];
|
||||||
} else if (typeof data === 'string') {
|
|
||||||
// version 1
|
|
||||||
let object = JSON.parse(data);
|
|
||||||
adataString = atob(object.adata);
|
|
||||||
spec = [
|
|
||||||
object.iv,
|
|
||||||
object.salt,
|
|
||||||
object.iter,
|
|
||||||
object.ks,
|
|
||||||
object.ts,
|
|
||||||
object.cipher,
|
|
||||||
object.mode,
|
|
||||||
'rawdeflate'
|
|
||||||
];
|
|
||||||
cipherMessage = object.ct;
|
|
||||||
} else {
|
} else {
|
||||||
throw 'unsupported message format';
|
throw 'unsupported message format';
|
||||||
}
|
}
|
||||||
|
@ -6043,4 +5993,4 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
CopyToClipboard: CopyToClipboard,
|
CopyToClipboard: CopyToClipboard,
|
||||||
Controller: Controller
|
Controller: Controller
|
||||||
};
|
};
|
||||||
})(jQuery, RawDeflate);
|
})(jQuery);
|
||||||
|
|
|
@ -1,755 +0,0 @@
|
||||||
/*
|
|
||||||
* $Id: rawinflate.js,v 0.3 2013/04/09 14:25:38 dankogai Exp dankogai $
|
|
||||||
*
|
|
||||||
* GNU General Public License, version 2 (GPL-2.0)
|
|
||||||
* https://opensource.org/licenses/GPL-2.0
|
|
||||||
* original:
|
|
||||||
* http://www.onicos.com/staff/iz/amuse/javascript/expert/inflate.txt
|
|
||||||
*/
|
|
||||||
|
|
||||||
(function(ctx){
|
|
||||||
|
|
||||||
/* Copyright (C) 1999 Masanao Izumo <iz@onicos.co.jp>
|
|
||||||
* Version: 1.0.0.1
|
|
||||||
* LastModified: Dec 25 1999
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Interface:
|
|
||||||
* data = zip_inflate(src);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* constant parameters */
|
|
||||||
var zip_WSIZE = 32768; // Sliding Window size
|
|
||||||
var zip_STORED_BLOCK = 0;
|
|
||||||
var zip_STATIC_TREES = 1;
|
|
||||||
var zip_DYN_TREES = 2;
|
|
||||||
|
|
||||||
/* for inflate */
|
|
||||||
var zip_lbits = 9; // bits in base literal/length lookup table
|
|
||||||
var zip_dbits = 6; // bits in base distance lookup table
|
|
||||||
var zip_INBUFSIZ = 32768; // Input buffer size
|
|
||||||
var zip_INBUF_EXTRA = 64; // Extra buffer
|
|
||||||
|
|
||||||
/* variables (inflate) */
|
|
||||||
var zip_slide;
|
|
||||||
var zip_wp; // current position in slide
|
|
||||||
var zip_fixed_tl = null; // inflate static
|
|
||||||
var zip_fixed_td; // inflate static
|
|
||||||
var zip_fixed_bl, fixed_bd; // inflate static
|
|
||||||
var zip_bit_buf; // bit buffer
|
|
||||||
var zip_bit_len; // bits in bit buffer
|
|
||||||
var zip_method;
|
|
||||||
var zip_eof;
|
|
||||||
var zip_copy_leng;
|
|
||||||
var zip_copy_dist;
|
|
||||||
var zip_tl, zip_td; // literal/length and distance decoder tables
|
|
||||||
var zip_bl, zip_bd; // number of bits decoded by tl and td
|
|
||||||
|
|
||||||
var zip_inflate_data;
|
|
||||||
var zip_inflate_pos;
|
|
||||||
|
|
||||||
|
|
||||||
/* constant tables (inflate) */
|
|
||||||
var zip_MASK_BITS = new Array(
|
|
||||||
0x0000,
|
|
||||||
0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
|
|
||||||
0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff);
|
|
||||||
// Tables for deflate from PKZIP's appnote.txt.
|
|
||||||
var zip_cplens = new Array( // Copy lengths for literal codes 257..285
|
|
||||||
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
|
|
||||||
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0);
|
|
||||||
/* note: see note #13 above about the 258 in this list. */
|
|
||||||
var zip_cplext = new Array( // Extra bits for literal codes 257..285
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
|
|
||||||
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 99, 99); // 99==invalid
|
|
||||||
var zip_cpdist = new Array( // Copy offsets for distance codes 0..29
|
|
||||||
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
|
|
||||||
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
|
|
||||||
8193, 12289, 16385, 24577);
|
|
||||||
var zip_cpdext = new Array( // Extra bits for distance codes
|
|
||||||
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
|
|
||||||
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
|
|
||||||
12, 12, 13, 13);
|
|
||||||
var zip_border = new Array( // Order of the bit length code lengths
|
|
||||||
16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
|
|
||||||
/* objects (inflate) */
|
|
||||||
|
|
||||||
var zip_HuftList = function() {
|
|
||||||
this.next = null;
|
|
||||||
this.list = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_HuftNode = function() {
|
|
||||||
this.e = 0; // number of extra bits or operation
|
|
||||||
this.b = 0; // number of bits in this code or subcode
|
|
||||||
|
|
||||||
// union
|
|
||||||
this.n = 0; // literal, length base, or distance base
|
|
||||||
this.t = null; // (zip_HuftNode) pointer to next level of table
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_HuftBuild = function(b, // code lengths in bits (all assumed <= BMAX)
|
|
||||||
n, // number of codes (assumed <= N_MAX)
|
|
||||||
s, // number of simple-valued codes (0..s-1)
|
|
||||||
d, // list of base values for non-simple codes
|
|
||||||
e, // list of extra bits for non-simple codes
|
|
||||||
mm // maximum lookup bits
|
|
||||||
) {
|
|
||||||
this.BMAX = 16; // maximum bit length of any code
|
|
||||||
this.N_MAX = 288; // maximum number of codes in any set
|
|
||||||
this.status = 0; // 0: success, 1: incomplete table, 2: bad input
|
|
||||||
this.root = null; // (zip_HuftList) starting table
|
|
||||||
this.m = 0; // maximum lookup bits, returns actual
|
|
||||||
|
|
||||||
/* Given a list of code lengths and a maximum table size, make a set of
|
|
||||||
tables to decode that set of codes. Return zero on success, one if
|
|
||||||
the given code set is incomplete (the tables are still built in this
|
|
||||||
case), two if the input is invalid (all zero length codes or an
|
|
||||||
oversubscribed set of lengths), and three if not enough memory.
|
|
||||||
The code with value 256 is special, and the tables are constructed
|
|
||||||
so that no bits beyond that code are fetched when that code is
|
|
||||||
decoded. */
|
|
||||||
{
|
|
||||||
var a; // counter for codes of length k
|
|
||||||
var c = new Array(this.BMAX+1); // bit length count table
|
|
||||||
var el; // length of EOB code (value 256)
|
|
||||||
var f; // i repeats in table every f entries
|
|
||||||
var g; // maximum code length
|
|
||||||
var h; // table level
|
|
||||||
var i; // counter, current code
|
|
||||||
var j; // counter
|
|
||||||
var k; // number of bits in current code
|
|
||||||
var lx = new Array(this.BMAX+1); // stack of bits per table
|
|
||||||
var p; // pointer into c[], b[], or v[]
|
|
||||||
var pidx; // index of p
|
|
||||||
var q; // (zip_HuftNode) points to current table
|
|
||||||
var r = new zip_HuftNode(); // table entry for structure assignment
|
|
||||||
var u = new Array(this.BMAX); // zip_HuftNode[BMAX][] table stack
|
|
||||||
var v = new Array(this.N_MAX); // values in order of bit length
|
|
||||||
var w;
|
|
||||||
var x = new Array(this.BMAX+1);// bit offsets, then code stack
|
|
||||||
var xp; // pointer into x or c
|
|
||||||
var y; // number of dummy codes added
|
|
||||||
var z; // number of entries in current table
|
|
||||||
var o;
|
|
||||||
var tail; // (zip_HuftList)
|
|
||||||
|
|
||||||
tail = this.root = null;
|
|
||||||
for(i = 0; i < c.length; i++)
|
|
||||||
c[i] = 0;
|
|
||||||
for(i = 0; i < lx.length; i++)
|
|
||||||
lx[i] = 0;
|
|
||||||
for(i = 0; i < u.length; i++)
|
|
||||||
u[i] = null;
|
|
||||||
for(i = 0; i < v.length; i++)
|
|
||||||
v[i] = 0;
|
|
||||||
for(i = 0; i < x.length; i++)
|
|
||||||
x[i] = 0;
|
|
||||||
|
|
||||||
// Generate counts for each bit length
|
|
||||||
el = n > 256 ? b[256] : this.BMAX; // set length of EOB code, if any
|
|
||||||
p = b; pidx = 0;
|
|
||||||
i = n;
|
|
||||||
do {
|
|
||||||
c[p[pidx]]++; // assume all entries <= BMAX
|
|
||||||
pidx++;
|
|
||||||
} while(--i > 0);
|
|
||||||
if(c[0] == n) { // null input--all zero length codes
|
|
||||||
this.root = null;
|
|
||||||
this.m = 0;
|
|
||||||
this.status = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find minimum and maximum length, bound *m by those
|
|
||||||
for(j = 1; j <= this.BMAX; j++)
|
|
||||||
if(c[j] != 0)
|
|
||||||
break;
|
|
||||||
k = j; // minimum code length
|
|
||||||
if(mm < j)
|
|
||||||
mm = j;
|
|
||||||
for(i = this.BMAX; i != 0; i--)
|
|
||||||
if(c[i] != 0)
|
|
||||||
break;
|
|
||||||
g = i; // maximum code length
|
|
||||||
if(mm > i)
|
|
||||||
mm = i;
|
|
||||||
|
|
||||||
// Adjust last length count to fill out codes, if needed
|
|
||||||
for(y = 1 << j; j < i; j++, y <<= 1)
|
|
||||||
if((y -= c[j]) < 0) {
|
|
||||||
this.status = 2; // bad input: more codes than bits
|
|
||||||
this.m = mm;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if((y -= c[i]) < 0) {
|
|
||||||
this.status = 2;
|
|
||||||
this.m = mm;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
c[i] += y;
|
|
||||||
|
|
||||||
// Generate starting offsets into the value table for each length
|
|
||||||
x[1] = j = 0;
|
|
||||||
p = c;
|
|
||||||
pidx = 1;
|
|
||||||
xp = 2;
|
|
||||||
while(--i > 0) // note that i == g from above
|
|
||||||
x[xp++] = (j += p[pidx++]);
|
|
||||||
|
|
||||||
// Make a table of values in order of bit lengths
|
|
||||||
p = b; pidx = 0;
|
|
||||||
i = 0;
|
|
||||||
do {
|
|
||||||
if((j = p[pidx++]) != 0)
|
|
||||||
v[x[j]++] = i;
|
|
||||||
} while(++i < n);
|
|
||||||
n = x[g]; // set n to length of v
|
|
||||||
|
|
||||||
// Generate the Huffman codes and for each, make the table entries
|
|
||||||
x[0] = i = 0; // first Huffman code is zero
|
|
||||||
p = v; pidx = 0; // grab values in bit order
|
|
||||||
h = -1; // no tables yet--level -1
|
|
||||||
w = lx[0] = 0; // no bits decoded yet
|
|
||||||
q = null; // ditto
|
|
||||||
z = 0; // ditto
|
|
||||||
|
|
||||||
// go through the bit lengths (k already is bits in shortest code)
|
|
||||||
for(; k <= g; k++) {
|
|
||||||
a = c[k];
|
|
||||||
while(a-- > 0) {
|
|
||||||
// here i is the Huffman code of length k bits for value p[pidx]
|
|
||||||
// make tables up to required level
|
|
||||||
while(k > w + lx[1 + h]) {
|
|
||||||
w += lx[1 + h]; // add bits already decoded
|
|
||||||
h++;
|
|
||||||
|
|
||||||
// compute minimum size table less than or equal to *m bits
|
|
||||||
z = (z = g - w) > mm ? mm : z; // upper limit
|
|
||||||
if((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table
|
|
||||||
// too few codes for k-w bit table
|
|
||||||
f -= a + 1; // deduct codes from patterns left
|
|
||||||
xp = k;
|
|
||||||
while(++j < z) { // try smaller tables up to z bits
|
|
||||||
if((f <<= 1) <= c[++xp])
|
|
||||||
break; // enough codes to use up j bits
|
|
||||||
f -= c[xp]; // else deduct codes from patterns
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(w + j > el && w < el)
|
|
||||||
j = el - w; // make EOB code end at table
|
|
||||||
z = 1 << j; // table entries for j-bit table
|
|
||||||
lx[1 + h] = j; // set table size in stack
|
|
||||||
|
|
||||||
// allocate and link in new table
|
|
||||||
q = new Array(z);
|
|
||||||
for(o = 0; o < z; o++) {
|
|
||||||
q[o] = new zip_HuftNode();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(tail == null)
|
|
||||||
tail = this.root = new zip_HuftList();
|
|
||||||
else
|
|
||||||
tail = tail.next = new zip_HuftList();
|
|
||||||
tail.next = null;
|
|
||||||
tail.list = q;
|
|
||||||
u[h] = q; // table starts after link
|
|
||||||
|
|
||||||
/* connect to last table, if there is one */
|
|
||||||
if(h > 0) {
|
|
||||||
x[h] = i; // save pattern for backing up
|
|
||||||
r.b = lx[h]; // bits to dump before this table
|
|
||||||
r.e = 16 + j; // bits in this table
|
|
||||||
r.t = q; // pointer to this table
|
|
||||||
j = (i & ((1 << w) - 1)) >> (w - lx[h]);
|
|
||||||
u[h-1][j].e = r.e;
|
|
||||||
u[h-1][j].b = r.b;
|
|
||||||
u[h-1][j].n = r.n;
|
|
||||||
u[h-1][j].t = r.t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set up table entry in r
|
|
||||||
r.b = k - w;
|
|
||||||
if(pidx >= n)
|
|
||||||
r.e = 99; // out of values--invalid code
|
|
||||||
else if(p[pidx] < s) {
|
|
||||||
r.e = (p[pidx] < 256 ? 16 : 15); // 256 is end-of-block code
|
|
||||||
r.n = p[pidx++]; // simple code is just the value
|
|
||||||
} else {
|
|
||||||
r.e = e[p[pidx] - s]; // non-simple--look up in lists
|
|
||||||
r.n = d[p[pidx++] - s];
|
|
||||||
}
|
|
||||||
|
|
||||||
// fill code-like entries with r //
|
|
||||||
f = 1 << (k - w);
|
|
||||||
for(j = i >> w; j < z; j += f) {
|
|
||||||
q[j].e = r.e;
|
|
||||||
q[j].b = r.b;
|
|
||||||
q[j].n = r.n;
|
|
||||||
q[j].t = r.t;
|
|
||||||
}
|
|
||||||
|
|
||||||
// backwards increment the k-bit code i
|
|
||||||
for(j = 1 << (k - 1); (i & j) != 0; j >>= 1)
|
|
||||||
i ^= j;
|
|
||||||
i ^= j;
|
|
||||||
|
|
||||||
// backup over finished tables
|
|
||||||
while((i & ((1 << w) - 1)) != x[h]) {
|
|
||||||
w -= lx[h]; // don't need to update q
|
|
||||||
h--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return actual size of base table */
|
|
||||||
this.m = lx[1];
|
|
||||||
|
|
||||||
/* Return true (1) if we were given an incomplete table */
|
|
||||||
this.status = ((y != 0 && g != 1) ? 1 : 0);
|
|
||||||
} /* end of constructor */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* routines (inflate) */
|
|
||||||
|
|
||||||
var zip_GET_BYTE = function() {
|
|
||||||
if(zip_inflate_data.length == zip_inflate_pos)
|
|
||||||
return -1;
|
|
||||||
return zip_inflate_data.charCodeAt(zip_inflate_pos++) & 0xff;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_NEEDBITS = function(n) {
|
|
||||||
while(zip_bit_len < n) {
|
|
||||||
zip_bit_buf |= zip_GET_BYTE() << zip_bit_len;
|
|
||||||
zip_bit_len += 8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_GETBITS = function(n) {
|
|
||||||
return zip_bit_buf & zip_MASK_BITS[n];
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_DUMPBITS = function(n) {
|
|
||||||
zip_bit_buf >>= n;
|
|
||||||
zip_bit_len -= n;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_inflate_codes = function(buff, off, size) {
|
|
||||||
/* inflate (decompress) the codes in a deflated (compressed) block.
|
|
||||||
Return an error code or zero if it all goes ok. */
|
|
||||||
var e; // table entry flag/number of extra bits
|
|
||||||
var t; // (zip_HuftNode) pointer to table entry
|
|
||||||
var n;
|
|
||||||
|
|
||||||
if(size == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// inflate the coded data
|
|
||||||
n = 0;
|
|
||||||
for(;;) { // do until end of block
|
|
||||||
zip_NEEDBITS(zip_bl);
|
|
||||||
t = zip_tl.list[zip_GETBITS(zip_bl)];
|
|
||||||
e = t.e;
|
|
||||||
while(e > 16) {
|
|
||||||
if(e == 99)
|
|
||||||
return -1;
|
|
||||||
zip_DUMPBITS(t.b);
|
|
||||||
e -= 16;
|
|
||||||
zip_NEEDBITS(e);
|
|
||||||
t = t.t[zip_GETBITS(e)];
|
|
||||||
e = t.e;
|
|
||||||
}
|
|
||||||
zip_DUMPBITS(t.b);
|
|
||||||
|
|
||||||
if(e == 16) { // then it's a literal
|
|
||||||
zip_wp &= zip_WSIZE - 1;
|
|
||||||
buff[off + n++] = zip_slide[zip_wp++] = t.n;
|
|
||||||
if(n == size)
|
|
||||||
return size;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// exit if end of block
|
|
||||||
if(e == 15)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// it's an EOB or a length
|
|
||||||
|
|
||||||
// get length of block to copy
|
|
||||||
zip_NEEDBITS(e);
|
|
||||||
zip_copy_leng = t.n + zip_GETBITS(e);
|
|
||||||
zip_DUMPBITS(e);
|
|
||||||
|
|
||||||
// decode distance of block to copy
|
|
||||||
zip_NEEDBITS(zip_bd);
|
|
||||||
t = zip_td.list[zip_GETBITS(zip_bd)];
|
|
||||||
e = t.e;
|
|
||||||
|
|
||||||
while(e > 16) {
|
|
||||||
if(e == 99)
|
|
||||||
return -1;
|
|
||||||
zip_DUMPBITS(t.b);
|
|
||||||
e -= 16;
|
|
||||||
zip_NEEDBITS(e);
|
|
||||||
t = t.t[zip_GETBITS(e)];
|
|
||||||
e = t.e;
|
|
||||||
}
|
|
||||||
zip_DUMPBITS(t.b);
|
|
||||||
zip_NEEDBITS(e);
|
|
||||||
zip_copy_dist = zip_wp - t.n - zip_GETBITS(e);
|
|
||||||
zip_DUMPBITS(e);
|
|
||||||
|
|
||||||
// do the copy
|
|
||||||
while(zip_copy_leng > 0 && n < size) {
|
|
||||||
zip_copy_leng--;
|
|
||||||
zip_copy_dist &= zip_WSIZE - 1;
|
|
||||||
zip_wp &= zip_WSIZE - 1;
|
|
||||||
buff[off + n++] = zip_slide[zip_wp++]
|
|
||||||
= zip_slide[zip_copy_dist++];
|
|
||||||
}
|
|
||||||
|
|
||||||
if(n == size)
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
zip_method = -1; // done
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_inflate_stored = function(buff, off, size) {
|
|
||||||
/* "decompress" an inflated type 0 (stored) block. */
|
|
||||||
var n;
|
|
||||||
|
|
||||||
// go to byte boundary
|
|
||||||
n = zip_bit_len & 7;
|
|
||||||
zip_DUMPBITS(n);
|
|
||||||
|
|
||||||
// get the length and its complement
|
|
||||||
zip_NEEDBITS(16);
|
|
||||||
n = zip_GETBITS(16);
|
|
||||||
zip_DUMPBITS(16);
|
|
||||||
zip_NEEDBITS(16);
|
|
||||||
if(n != ((~zip_bit_buf) & 0xffff))
|
|
||||||
return -1; // error in compressed data
|
|
||||||
zip_DUMPBITS(16);
|
|
||||||
|
|
||||||
// read and output the compressed data
|
|
||||||
zip_copy_leng = n;
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
while(zip_copy_leng > 0 && n < size) {
|
|
||||||
zip_copy_leng--;
|
|
||||||
zip_wp &= zip_WSIZE - 1;
|
|
||||||
zip_NEEDBITS(8);
|
|
||||||
buff[off + n++] = zip_slide[zip_wp++] =
|
|
||||||
zip_GETBITS(8);
|
|
||||||
zip_DUMPBITS(8);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(zip_copy_leng == 0)
|
|
||||||
zip_method = -1; // done
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_inflate_fixed = function(buff, off, size) {
|
|
||||||
/* decompress an inflated type 1 (fixed Huffman codes) block. We should
|
|
||||||
either replace this with a custom decoder, or at least precompute the
|
|
||||||
Huffman tables. */
|
|
||||||
|
|
||||||
// if first time, set up tables for fixed blocks
|
|
||||||
if(zip_fixed_tl == null) {
|
|
||||||
var i; // temporary variable
|
|
||||||
var l = new Array(288); // length list for huft_build
|
|
||||||
var h; // zip_HuftBuild
|
|
||||||
|
|
||||||
// literal table
|
|
||||||
for(i = 0; i < 144; i++)
|
|
||||||
l[i] = 8;
|
|
||||||
for(; i < 256; i++)
|
|
||||||
l[i] = 9;
|
|
||||||
for(; i < 280; i++)
|
|
||||||
l[i] = 7;
|
|
||||||
for(; i < 288; i++) // make a complete, but wrong code set
|
|
||||||
l[i] = 8;
|
|
||||||
zip_fixed_bl = 7;
|
|
||||||
|
|
||||||
h = new zip_HuftBuild(l, 288, 257, zip_cplens, zip_cplext,
|
|
||||||
zip_fixed_bl);
|
|
||||||
if(h.status != 0) {
|
|
||||||
alert("HufBuild error: "+h.status);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
zip_fixed_tl = h.root;
|
|
||||||
zip_fixed_bl = h.m;
|
|
||||||
|
|
||||||
// distance table
|
|
||||||
for(i = 0; i < 30; i++) // make an incomplete code set
|
|
||||||
l[i] = 5;
|
|
||||||
zip_fixed_bd = 5;
|
|
||||||
|
|
||||||
h = new zip_HuftBuild(l, 30, 0, zip_cpdist, zip_cpdext, zip_fixed_bd);
|
|
||||||
if(h.status > 1) {
|
|
||||||
zip_fixed_tl = null;
|
|
||||||
alert("HufBuild error: "+h.status);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
zip_fixed_td = h.root;
|
|
||||||
zip_fixed_bd = h.m;
|
|
||||||
}
|
|
||||||
|
|
||||||
zip_tl = zip_fixed_tl;
|
|
||||||
zip_td = zip_fixed_td;
|
|
||||||
zip_bl = zip_fixed_bl;
|
|
||||||
zip_bd = zip_fixed_bd;
|
|
||||||
return zip_inflate_codes(buff, off, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_inflate_dynamic = function(buff, off, size) {
|
|
||||||
// decompress an inflated type 2 (dynamic Huffman codes) block.
|
|
||||||
var i; // temporary variables
|
|
||||||
var j;
|
|
||||||
var l; // last length
|
|
||||||
var n; // number of lengths to get
|
|
||||||
var t; // (zip_HuftNode) literal/length code table
|
|
||||||
var nb; // number of bit length codes
|
|
||||||
var nl; // number of literal/length codes
|
|
||||||
var nd; // number of distance codes
|
|
||||||
var ll = new Array(286+30); // literal/length and distance code lengths
|
|
||||||
var h; // (zip_HuftBuild)
|
|
||||||
|
|
||||||
for(i = 0; i < ll.length; i++)
|
|
||||||
ll[i] = 0;
|
|
||||||
|
|
||||||
// read in table lengths
|
|
||||||
zip_NEEDBITS(5);
|
|
||||||
nl = 257 + zip_GETBITS(5); // number of literal/length codes
|
|
||||||
zip_DUMPBITS(5);
|
|
||||||
zip_NEEDBITS(5);
|
|
||||||
nd = 1 + zip_GETBITS(5); // number of distance codes
|
|
||||||
zip_DUMPBITS(5);
|
|
||||||
zip_NEEDBITS(4);
|
|
||||||
nb = 4 + zip_GETBITS(4); // number of bit length codes
|
|
||||||
zip_DUMPBITS(4);
|
|
||||||
if(nl > 286 || nd > 30)
|
|
||||||
return -1; // bad lengths
|
|
||||||
|
|
||||||
// read in bit-length-code lengths
|
|
||||||
for(j = 0; j < nb; j++)
|
|
||||||
{
|
|
||||||
zip_NEEDBITS(3);
|
|
||||||
ll[zip_border[j]] = zip_GETBITS(3);
|
|
||||||
zip_DUMPBITS(3);
|
|
||||||
}
|
|
||||||
for(; j < 19; j++)
|
|
||||||
ll[zip_border[j]] = 0;
|
|
||||||
|
|
||||||
// build decoding table for trees--single level, 7 bit lookup
|
|
||||||
zip_bl = 7;
|
|
||||||
h = new zip_HuftBuild(ll, 19, 19, null, null, zip_bl);
|
|
||||||
if(h.status != 0)
|
|
||||||
return -1; // incomplete code set
|
|
||||||
|
|
||||||
zip_tl = h.root;
|
|
||||||
zip_bl = h.m;
|
|
||||||
|
|
||||||
// read in literal and distance code lengths
|
|
||||||
n = nl + nd;
|
|
||||||
i = l = 0;
|
|
||||||
while(i < n) {
|
|
||||||
zip_NEEDBITS(zip_bl);
|
|
||||||
t = zip_tl.list[zip_GETBITS(zip_bl)];
|
|
||||||
j = t.b;
|
|
||||||
zip_DUMPBITS(j);
|
|
||||||
j = t.n;
|
|
||||||
if(j < 16) // length of code in bits (0..15)
|
|
||||||
ll[i++] = l = j; // save last length in l
|
|
||||||
else if(j == 16) { // repeat last length 3 to 6 times
|
|
||||||
zip_NEEDBITS(2);
|
|
||||||
j = 3 + zip_GETBITS(2);
|
|
||||||
zip_DUMPBITS(2);
|
|
||||||
if(i + j > n)
|
|
||||||
return -1;
|
|
||||||
while(j-- > 0)
|
|
||||||
ll[i++] = l;
|
|
||||||
} else if(j == 17) { // 3 to 10 zero length codes
|
|
||||||
zip_NEEDBITS(3);
|
|
||||||
j = 3 + zip_GETBITS(3);
|
|
||||||
zip_DUMPBITS(3);
|
|
||||||
if(i + j > n)
|
|
||||||
return -1;
|
|
||||||
while(j-- > 0)
|
|
||||||
ll[i++] = 0;
|
|
||||||
l = 0;
|
|
||||||
} else { // j == 18: 11 to 138 zero length codes
|
|
||||||
zip_NEEDBITS(7);
|
|
||||||
j = 11 + zip_GETBITS(7);
|
|
||||||
zip_DUMPBITS(7);
|
|
||||||
if(i + j > n)
|
|
||||||
return -1;
|
|
||||||
while(j-- > 0)
|
|
||||||
ll[i++] = 0;
|
|
||||||
l = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// build the decoding tables for literal/length and distance codes
|
|
||||||
zip_bl = zip_lbits;
|
|
||||||
h = new zip_HuftBuild(ll, nl, 257, zip_cplens, zip_cplext, zip_bl);
|
|
||||||
if(zip_bl == 0) // no literals or lengths
|
|
||||||
h.status = 1;
|
|
||||||
if(h.status != 0) {
|
|
||||||
if(h.status == 1)
|
|
||||||
;// **incomplete literal tree**
|
|
||||||
return -1; // incomplete code set
|
|
||||||
}
|
|
||||||
zip_tl = h.root;
|
|
||||||
zip_bl = h.m;
|
|
||||||
|
|
||||||
for(i = 0; i < nd; i++)
|
|
||||||
ll[i] = ll[i + nl];
|
|
||||||
zip_bd = zip_dbits;
|
|
||||||
h = new zip_HuftBuild(ll, nd, 0, zip_cpdist, zip_cpdext, zip_bd);
|
|
||||||
zip_td = h.root;
|
|
||||||
zip_bd = h.m;
|
|
||||||
|
|
||||||
if(zip_bd == 0 && nl > 257) { // lengths but no distances
|
|
||||||
// **incomplete distance tree**
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(h.status == 1) {
|
|
||||||
;// **incomplete distance tree**
|
|
||||||
}
|
|
||||||
if(h.status != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// decompress until an end-of-block code
|
|
||||||
return zip_inflate_codes(buff, off, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_inflate_start = function() {
|
|
||||||
var i;
|
|
||||||
|
|
||||||
if(zip_slide == null)
|
|
||||||
zip_slide = new Array(2 * zip_WSIZE);
|
|
||||||
zip_wp = 0;
|
|
||||||
zip_bit_buf = 0;
|
|
||||||
zip_bit_len = 0;
|
|
||||||
zip_method = -1;
|
|
||||||
zip_eof = false;
|
|
||||||
zip_copy_leng = zip_copy_dist = 0;
|
|
||||||
zip_tl = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_inflate_internal = function(buff, off, size) {
|
|
||||||
// decompress an inflated entry
|
|
||||||
var n, i;
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
while(n < size) {
|
|
||||||
if(zip_eof && zip_method == -1)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
if(zip_copy_leng > 0) {
|
|
||||||
if(zip_method != zip_STORED_BLOCK) {
|
|
||||||
// STATIC_TREES or DYN_TREES
|
|
||||||
while(zip_copy_leng > 0 && n < size) {
|
|
||||||
zip_copy_leng--;
|
|
||||||
zip_copy_dist &= zip_WSIZE - 1;
|
|
||||||
zip_wp &= zip_WSIZE - 1;
|
|
||||||
buff[off + n++] = zip_slide[zip_wp++] =
|
|
||||||
zip_slide[zip_copy_dist++];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while(zip_copy_leng > 0 && n < size) {
|
|
||||||
zip_copy_leng--;
|
|
||||||
zip_wp &= zip_WSIZE - 1;
|
|
||||||
zip_NEEDBITS(8);
|
|
||||||
buff[off + n++] = zip_slide[zip_wp++] = zip_GETBITS(8);
|
|
||||||
zip_DUMPBITS(8);
|
|
||||||
}
|
|
||||||
if(zip_copy_leng == 0)
|
|
||||||
zip_method = -1; // done
|
|
||||||
}
|
|
||||||
if(n == size)
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(zip_method == -1) {
|
|
||||||
if(zip_eof)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// read in last block bit
|
|
||||||
zip_NEEDBITS(1);
|
|
||||||
if(zip_GETBITS(1) != 0)
|
|
||||||
zip_eof = true;
|
|
||||||
zip_DUMPBITS(1);
|
|
||||||
|
|
||||||
// read in block type
|
|
||||||
zip_NEEDBITS(2);
|
|
||||||
zip_method = zip_GETBITS(2);
|
|
||||||
zip_DUMPBITS(2);
|
|
||||||
zip_tl = null;
|
|
||||||
zip_copy_leng = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(zip_method) {
|
|
||||||
case 0: // zip_STORED_BLOCK
|
|
||||||
i = zip_inflate_stored(buff, off + n, size - n);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1: // zip_STATIC_TREES
|
|
||||||
if(zip_tl != null)
|
|
||||||
i = zip_inflate_codes(buff, off + n, size - n);
|
|
||||||
else
|
|
||||||
i = zip_inflate_fixed(buff, off + n, size - n);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2: // zip_DYN_TREES
|
|
||||||
if(zip_tl != null)
|
|
||||||
i = zip_inflate_codes(buff, off + n, size - n);
|
|
||||||
else
|
|
||||||
i = zip_inflate_dynamic(buff, off + n, size - n);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default: // error
|
|
||||||
i = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(i == -1) {
|
|
||||||
if(zip_eof)
|
|
||||||
return 0;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
n += i;
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
var zip_inflate = function(str) {
|
|
||||||
var i, j;
|
|
||||||
|
|
||||||
zip_inflate_start();
|
|
||||||
zip_inflate_data = str;
|
|
||||||
zip_inflate_pos = 0;
|
|
||||||
|
|
||||||
var buff = new Array(1024);
|
|
||||||
var aout = [];
|
|
||||||
while((i = zip_inflate_internal(buff, 0, buff.length)) > 0) {
|
|
||||||
var cbuf = new Array(i);
|
|
||||||
for(j = 0; j < i; j++){
|
|
||||||
cbuf[j] = String.fromCharCode(buff[j]);
|
|
||||||
}
|
|
||||||
aout[aout.length] = cbuf.join("");
|
|
||||||
}
|
|
||||||
zip_inflate_data = null; // G.C.
|
|
||||||
return aout.join("");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! ctx.RawDeflate) ctx.RawDeflate = {};
|
|
||||||
ctx.RawDeflate.inflate = zip_inflate;
|
|
||||||
|
|
||||||
})(this);
|
|
|
@ -40,191 +40,6 @@ describe('CryptTool', function () {
|
||||||
{tests: 3});
|
{tests: 3});
|
||||||
});
|
});
|
||||||
|
|
||||||
// The below static unit tests are included to ensure deciphering of "classic"
|
|
||||||
// SJCL based pastes still works
|
|
||||||
it(
|
|
||||||
'supports PrivateBin v1 ciphertext with password (SJCL & browser atob)',
|
|
||||||
async function () {
|
|
||||||
delete global.Base64;
|
|
||||||
const clean = jsdom();
|
|
||||||
Object.defineProperty(window, 'crypto', {
|
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
|
||||||
// -- "That's amazing. I've got the same combination on my luggage."
|
|
||||||
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
|
||||||
'{"iv":"4HNFIl7eYbCh6HuShctTIA==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"u0lQvePq6L0=","ct":"fGPUVrDyaVr1ZDGb+kqQ3CPEW8x4YKG' +
|
|
||||||
'fzHDmA0Vjkh250aWNe7Cnigkps9aaFVMX9AaerrTp3yZbojJtNqVGMfL' +
|
|
||||||
'dUTu+53xmZHqRKxCCqSfDNSNoW4Oxk5OVgAtRyuG4bXHDsWTXDNz2xce' +
|
|
||||||
'qzVFqhkwTwlUchrV7uuFK/XUKTNjPFM744moivIcBbfM2FOeKlIFs8RY' +
|
|
||||||
'PYuvqQhp2rMLlNGwwKh//4kykQsHMQDeSDuJl8stMQzgWR/btUBZuwNZ' +
|
|
||||||
'EydkMH6IPpTdf5WTSrZ+wC2OK0GutCm4UaEe6txzaTMfu+WRVu4PN6q+' +
|
|
||||||
'N+2zljWJ1XdpVcN/i0Sv4QVMym0Xa6y0eccEhj/69o47PmExmMMeEwEx' +
|
|
||||||
'ImPalMNT9JUSiZdOZJ/GdzwrwoIuq1mdQR6vSH+XJ/8jXJQ7bjjJVJYX' +
|
|
||||||
'TcT0Di5jixArI2Kpp1GGlGVFbLgPugwU1wczg+byqeDOAECXRRnQcoge' +
|
|
||||||
'aJtVcRwXwfy4j3ORFcblYMilxyHqKBewcYPRVBGtBs50cVjSIkAfR84r' +
|
|
||||||
'nc1nfvnxK/Gmm+4VBNHI6ODWNpRolVMCzXjbKYnV3Are5AgSpsTqaGl4' +
|
|
||||||
'1VJGpcco6cAwi4K0Bys1seKR+bLSdUgqRrkEqSRSdu3/VTu9HhEk8an0' +
|
|
||||||
'rjTE4CBB5/LMn16p0TGLoOb32odKFIEtpanVvLjeyiVMvSxcgYLNnTi/' +
|
|
||||||
'5FiaAC4pJxRD+AZHedU1FICUeEXxIcac/4E5qjkHjX9SpQtLl80QLIVn' +
|
|
||||||
'jNliZm7QLB/nKu7W8Jb0+/CiTdV3Q9LhxlH4ciprnX+W0B00BKYFHnL9' +
|
|
||||||
'jRVzKdXhf1EHydbXMAfpCjHAXIVCkFakJinQBDIIw/SC6Yig0u0ddEID' +
|
|
||||||
'2B7LYAP1iE4RZwzTrxCB+ke2jQr8c20Jj6u6ShFOPC9DCw9XupZ4HAal' +
|
|
||||||
'VG00kSgjus+b8zrVji3/LKEhb4EBzp1ctBJCFTeXwej8ZETLoXTylev5' +
|
|
||||||
'dlwZSYAbuBPPcbFR/xAIPx3uDabd1E1gTqUc68ICIGhd197Mb2eRWiSv' +
|
|
||||||
'Hr5SPsASerMxId6XA6+iQlRiI+NDR+TGVNmCnfxSlyPFMOHGTmslXOGI' +
|
|
||||||
'qGfBR8l4ft8YVZ70lCwmwTuViGc75ULSf9mM57/LmRzQFMYQtvI8IFK9' +
|
|
||||||
'JaQEMY5xz0HLtR4iyQUUdwR9e0ytBNdWF2a2WPDEnJuY/QJo4GzTlgv4' +
|
|
||||||
'QUxMXI5htsn2rf0HxCFu7Po8DNYLxTS+67hYjDIYWYaEIc8LXWMLyDm9' +
|
|
||||||
'C5fARPJ4F2BIWgzgzkNj+dVjusft2XnziamWdbS5u3kuRlVuz5LQj+R5' +
|
|
||||||
'imnqQAincdZTkTT1nYx+DatlOLllCYIHffpI="}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
const result = typeof paste === 'string' && paste.includes('securely packed in iron');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
|
||||||
'supports PrivateBin v1 ciphertext no password (SJCL & browser atob)',
|
|
||||||
async function () {
|
|
||||||
delete global.Base64;
|
|
||||||
const clean = jsdom();
|
|
||||||
// ensure zlib is getting loaded
|
|
||||||
$.PrivateBin.Controller.initZ();
|
|
||||||
Object.defineProperty(window, 'crypto', {
|
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
|
||||||
'', // no password
|
|
||||||
'{"iv":"WA42mdxIVXUwBqZu7JYNiw==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"jN6CjbQMJCM=","ct":"kYYMo5DFG1+w0UHiYXT5pdV0IUuXxzO' +
|
|
||||||
'lslkW/c3DRCbGFROCVkAskHce7HoRczee1N9c5MhHjVMJUIZE02qIS8U' +
|
|
||||||
'yHdJ/GqcPVidTUcj9rnDNWsTXkjVv8jCwHS/cwmAjDTWpwp5ThECN+ov' +
|
|
||||||
'/wNp/NdtTj8Qj7f/T3rfZIOCWfwLH9s4Des35UNcUidfPTNQ1l0Gm0X+' +
|
|
||||||
'r98CCUSYZjQxkZc6hRZBLPQ8EaNVooUwd5eP4GiYlmSDNA0wOSA+5isP' +
|
|
||||||
'YxomVCt+kFf58VBlNhpfNi7BLYAUTPpXT4SfH5drR9+C7NTeZ+tTCYjb' +
|
|
||||||
'U94PzYItOpu8vgnB1/a6BAM5h3m9w+giUb0df4hgTWeZnZxLjo5BN8WV' +
|
|
||||||
'+kdTXMj3/Vv0gw0DQrDcCuX/cBAjpy3lQGwlAN1vXoOIyZJUjMpQRrOL' +
|
|
||||||
'dKvLB+zcmVNtGDbgnfP2IYBzk9NtodpUa27ne0T0ZpwOPlVwevsIVZO2' +
|
|
||||||
'24WLa+iQmmHOWDFFpVDlS0t0fLfOk7Hcb2xFsTxiCIiyKMho/IME1Du3' +
|
|
||||||
'X4e6BVa3hobSSZv0rRtNgY1KcyYPrUPW2fxZ+oik3y9SgGvb7XpjVIta' +
|
|
||||||
'8DWlDWRfZ9kzoweWEYqz9IA8Xd373RefpyuWI25zlHoX3nwljzsZU6dC' +
|
|
||||||
'//h/Dt2DNr+IAvKO3+u23cWoB9kgcZJ2FJuqjLvVfCF+OWcig7zs2pTY' +
|
|
||||||
'JW6Rg6lqbBCxiUUlae6xJrjfv0pzD2VYCLY7v1bVTagppwKzNI3WaluC' +
|
|
||||||
'OrdDYUCxUSe56yd1oAoLPRVbYvomRboUO6cjQhEknERyvt45og2kORJO' +
|
|
||||||
'EJayHW+jZgR0Y0jM3Nk17ubpij2gHxNx9kiLDOiCGSV5mn9mV7qd3HHc' +
|
|
||||||
'OMSykiBgbyzjobi96LT2dIGLeDXTIdPOog8wyobO4jWq0GGs0vBB8oSY' +
|
|
||||||
'XhHvixZLcSjX2KQuHmEoWzmJcr3DavdoXZmAurGWLKjzEdJc5dSD/eNr' +
|
|
||||||
'99gjHX7wphJ6umKMM+fn6PcbYJkhDh2GlJL5COXjXfm/5aj/vuyaRRWZ' +
|
|
||||||
'MZtmnYpGAtAPg7AUG"}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
const result = typeof paste === 'string' && paste.includes('Sol is right');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
|
||||||
'supports ZeroBin ciphertext with password (SJCL & Base64 1.7)',
|
|
||||||
async function () {
|
|
||||||
global.Base64 = require('../base64-1.7').Base64;
|
|
||||||
const clean = jsdom();
|
|
||||||
Object.defineProperty(window, 'crypto', {
|
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
// Of course you can easily decipher the following texts, if you like.
|
|
||||||
// Bonus points for finding their sources and hidden meanings.
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
'6t2qsmLyfXIokNCL+3/yl15rfTUBQvm5SOnFPvNE7Q8=',
|
|
||||||
// -- "That's amazing. I've got the same combination on my luggage."
|
|
||||||
Array.apply(0, Array(6)).map((_,b) => b + 1).join(''),
|
|
||||||
'{"iv":"aTnR2qBL1CAmLX8FdWe3VA==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"u0lQvePq6L0=","ct":"A3nBTvICZtYy6xqbIJE0c8Veored5lM' +
|
|
||||||
'JUGgGUm4581wjrPFlU0Q0tUZSf+RUUoZj2jqDa4kiyyZ5YNMe30hNMV0' +
|
|
||||||
'oVSalNhRgD9svVMnPuF162IbyhVCwr7ULjT981CHxVlGNqGqmIU6L/Xi' +
|
|
||||||
'xgdArxAA8x1GCrfAkBWWGeq8Qw5vJPG/RCHpwR4Wy3azrluqeyERBzma' +
|
|
||||||
'OQjO/kM35TiI6IrLYFyYyL7upYlxAaxS0XBMZvN8QU8Lnerwvh5JVC6O' +
|
|
||||||
'kkKrhogajTJIKozCF79yI78c50LUh7tTuI3Yoh7+fXxhoODvQdYFmoiU' +
|
|
||||||
'lrutN7Y5ZMRdITvVu8fTYtX9c7Fiufmcq5icEimiHp2g1bvfpOaGOsFT' +
|
|
||||||
'+XNFgC9215jcp5mpBdN852xs7bUtw+nDrf+LsDEX6iRpRZ+PYgLDN5xQ' +
|
|
||||||
'T1ByEtYbeP+tO38pnx72oZdIB3cj8UkOxnxdNiZM5YB5egn4jUj1fHot' +
|
|
||||||
'1I69WoTiUJipZ5PIATv7ScymRB+AYzjxjurQ9lVfX9QtAbEH2dhdmoUo' +
|
|
||||||
'3IDRSXpWNCe9RC1aUIyWfZO7oI7FEohNscHNTLEcT+wFnFUPByLlXmjN' +
|
|
||||||
'Z7FKeNpvUm3jTY4t4sbZH8o2dUl624PAw1INcJ6FKqWGWwoFT2j1MYC+' +
|
|
||||||
'YV/LkLTdjuWfayvwLMh27G/FfKCRbW36vqinegqpPDylsx9+3oFkEw3y' +
|
|
||||||
'5Z8+44oN91rE/4Md7JhPJeRVlFC9TNCj4dA+EVhbbQqscvSnIH2uHkMw' +
|
|
||||||
'7mNNo7xba/YT9KoPDaniqnYqb+q2pX1WNWE7dLS2wfroMAS3kh8P22DA' +
|
|
||||||
'V37AeiNoD2PcI6ZcHbRdPa+XRrRcJhSPPW7UQ0z4OvBfjdu/w390QxAx' +
|
|
||||||
'SxvZewoh49fKKB6hTsRnZb4tpHkjlww=="}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
delete global.Base64;
|
|
||||||
const result = typeof paste === 'string' && paste.includes('securely packed in iron');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
|
||||||
'supports ZeroBin ciphertext no password (SJCL & Base64 1.7)',
|
|
||||||
async function () {
|
|
||||||
global.Base64 = require('../base64-1.7').Base64;
|
|
||||||
const clean = jsdom();
|
|
||||||
Object.defineProperty(window, 'crypto', {
|
|
||||||
value: new WebCrypto(),
|
|
||||||
writeable: false,
|
|
||||||
});
|
|
||||||
global.atob = common.atob;
|
|
||||||
|
|
||||||
const paste = await $.PrivateBin.CryptTool.decipher(
|
|
||||||
's9pmKZKOBN7EVvHpTA8jjLFH3Xlz/0l8lB4+ONPACrM=',
|
|
||||||
'', // no password
|
|
||||||
'{"iv":"Z7lAZQbkrqGMvruxoSm6Pw==","v":1,"iter":10000,"ks"' +
|
|
||||||
':256,"ts":128,"mode":"gcm","adata":"","cipher":"aes","sa' +
|
|
||||||
'lt":"jN6CjbQMJCM=","ct":"PuOPWB3i2FPcreSrLYeQf84LdE8RHjs' +
|
|
||||||
'c+MGtiOr4b7doNyWKYtkNorbRadxaPnEee2/Utrp1MIIfY5juJSy8RGw' +
|
|
||||||
'EPX5ciWcYe6EzsXWznsnvhmpKNj9B7eIIrfSbxfy8E2e/g7xav1nive+' +
|
|
||||||
'ljToka3WT1DZ8ILQd/NbnJeHWaoSEOfvz8+d8QJPb1tNZvs7zEY95Dum' +
|
|
||||||
'QwbyOsIMKAvcZHJ9OJNpujXzdMyt6DpcFcqlldWBZ/8q5rAUTw0HNx/r' +
|
|
||||||
'CgbhAxRYfNoTLIcMM4L0cXbPSgCjwf5FuO3EdE13mgEDhcClW79m0Qvc' +
|
|
||||||
'nIh8xgzYoxLbp0+AwvC/MbZM8savN/0ieWr2EKkZ04ggiOIEyvfCUuNp' +
|
|
||||||
'rQBYO+y8kKduNEN6by0Yf4LRCPfmwN+GezDLuzTnZIMhPbGqUAdgV6Ex' +
|
|
||||||
'qK2ULEEIrQEMoOuQIxfoMhqLlzG79vXGt2O+BY+4IiYfvmuRLks4UXfy' +
|
|
||||||
'HqxPXTJg48IYbGs0j4TtJPUgp3523EyYLwEGyVTAuWhYAmVIwd/hoV7d' +
|
|
||||||
'7tmfcF73w9dufDFI3LNca2KxzBnWNPYvIZKBwWbq8ncxkb191dP6mjEi' +
|
|
||||||
'7NnhqVk5A6vIBbu4AC5PZf76l6yep4xsoy/QtdDxCMocCXeAML9MQ9uP' +
|
|
||||||
'QbuspOKrBvMfN5igA1kBqasnxI472KBNXsdZnaDddSVUuvhTcETM="}'
|
|
||||||
);
|
|
||||||
clean();
|
|
||||||
delete global.Base64;
|
|
||||||
const result = typeof paste === 'string' && paste.includes('Sol is right');
|
|
||||||
if (!result) console.log(paste);
|
|
||||||
assert.ok(result);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
it('does not truncate messages', async function () {
|
it('does not truncate messages', async function () {
|
||||||
const message = fs.readFileSync('test/compression-sample.txt', 'ascii').trim(),
|
const message = fs.readFileSync('test/compression-sample.txt', 'ascii').trim(),
|
||||||
clean = jsdom();
|
clean = jsdom();
|
||||||
|
|
|
@ -65,7 +65,6 @@ class Configuration
|
||||||
'email' => true,
|
'email' => true,
|
||||||
'icon' => 'identicon',
|
'icon' => 'identicon',
|
||||||
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'wasm-unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; frame-src blob:; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads',
|
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'wasm-unsafe-eval\'; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; frame-src blob:; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-modals allow-downloads',
|
||||||
'zerobincompatibility' => false,
|
|
||||||
'httpwarning' => true,
|
'httpwarning' => true,
|
||||||
'compression' => 'zlib',
|
'compression' => 'zlib',
|
||||||
),
|
),
|
||||||
|
@ -110,7 +109,6 @@ class Configuration
|
||||||
// update this array when adding/changing/removing js files
|
// update this array when adding/changing/removing js files
|
||||||
'sri' => array(
|
'sri' => array(
|
||||||
'js/base-x-4.0.0.js' => 'sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==',
|
'js/base-x-4.0.0.js' => 'sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==',
|
||||||
'js/base64-1.7.js' => 'sha512-JdwsSP3GyHR+jaCkns9CL9NTt4JUJqm/BsODGmYhBcj5EAPKcHYh+OiMfyHbcDLECe17TL0hjXADFkusAqiYgA==',
|
|
||||||
'js/bootstrap-3.4.1.js' => 'sha512-oBTprMeNEKCnqfuqKd6sbvFzmFQtlXS3e0C/RGFV0hD6QzhHV+ODfaQbAlmY6/q0ubbwlAM/nCJjkrgA3waLzg==',
|
'js/bootstrap-3.4.1.js' => 'sha512-oBTprMeNEKCnqfuqKd6sbvFzmFQtlXS3e0C/RGFV0hD6QzhHV+ODfaQbAlmY6/q0ubbwlAM/nCJjkrgA3waLzg==',
|
||||||
'js/bootstrap-5.3.3.js' => 'sha512-in2rcOpLTdJ7/pw5qjF4LWHFRtgoBDxXCy49H4YGOcVdGiPaQucGIbOqxt1JvmpvOpq3J/C7VTa0FlioakB2gQ==',
|
'js/bootstrap-5.3.3.js' => 'sha512-in2rcOpLTdJ7/pw5qjF4LWHFRtgoBDxXCy49H4YGOcVdGiPaQucGIbOqxt1JvmpvOpq3J/C7VTa0FlioakB2gQ==',
|
||||||
'js/dark-mode-switch.js' => 'sha512-BhY7dNU14aDN5L+muoUmA66x0CkYUWkQT0nxhKBLP/o2d7jE025+dvWJa4OiYffBGEFgmhrD/Sp+QMkxGMTz2g==',
|
'js/dark-mode-switch.js' => 'sha512-BhY7dNU14aDN5L+muoUmA66x0CkYUWkQT0nxhKBLP/o2d7jE025+dvWJa4OiYffBGEFgmhrD/Sp+QMkxGMTz2g==',
|
||||||
|
@ -118,9 +116,8 @@ class Configuration
|
||||||
'js/kjua-0.9.0.js' => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
|
'js/kjua-0.9.0.js' => 'sha512-CVn7af+vTMBd9RjoS4QM5fpLFEOtBCoB0zPtaqIDC7sF4F8qgUSRFQQpIyEDGsr6yrjbuOLzdf20tkHHmpaqwQ==',
|
||||||
'js/legacy.js' => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
|
'js/legacy.js' => 'sha512-UxW/TOZKon83n6dk/09GsYKIyeO5LeBHokxyIq+r7KFS5KMBeIB/EM7NrkVYIezwZBaovnyNtY2d9tKFicRlXg==',
|
||||||
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
|
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
|
||||||
'js/privatebin.js' => 'sha512-9X1Ns+w/WPlWde118Mbl1UFDPsFmBcXK2zr6ny7oDOuZMVP1hFCPzXjKbC+59xDQW0Q+NmyT4NC6/5B6UzkkDw==',
|
'js/privatebin.js' => 'sha512-wQci0zYb+eGsbQaLWunZ7sMoT7+3w5SUfvBJ3JactOOO2WytQGt/q6wRdWZsCkZjCE6hxkEBOxlfSqLHluh3KQ==',
|
||||||
'js/purify-3.2.6.js' => 'sha512-zqwL4OoBLFx89QPewkz4Lz5CSA2ktU+f31fuECkF0iK3Id5qd3Zpq5dMby8KwHjIEpsUgOqwF58cnmcaNem0EA==',
|
'js/purify-3.2.6.js' => 'sha512-zqwL4OoBLFx89QPewkz4Lz5CSA2ktU+f31fuECkF0iK3Id5qd3Zpq5dMby8KwHjIEpsUgOqwF58cnmcaNem0EA==',
|
||||||
'js/rawinflate-0.3.js' => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
|
|
||||||
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
|
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',
|
||||||
'js/zlib-1.3.1-1.js' => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
|
'js/zlib-1.3.1-1.js' => 'sha512-5bU9IIP4PgBrOKLZvGWJD4kgfQrkTz8Z3Iqeu058mbQzW3mCumOU6M3UVbVZU9rrVoVwaW4cZK8U8h5xjF88eQ==',
|
||||||
),
|
),
|
||||||
|
|
|
@ -473,7 +473,6 @@ class Controller
|
||||||
$page->assign('BURNAFTERREADINGSELECTED', $this->_conf->getKey('burnafterreadingselected'));
|
$page->assign('BURNAFTERREADINGSELECTED', $this->_conf->getKey('burnafterreadingselected'));
|
||||||
$page->assign('PASSWORD', $this->_conf->getKey('password'));
|
$page->assign('PASSWORD', $this->_conf->getKey('password'));
|
||||||
$page->assign('FILEUPLOAD', $this->_conf->getKey('fileupload'));
|
$page->assign('FILEUPLOAD', $this->_conf->getKey('fileupload'));
|
||||||
$page->assign('ZEROBINCOMPATIBILITY', $this->_conf->getKey('zerobincompatibility'));
|
|
||||||
$page->assign('LANGUAGESELECTION', $languageselection);
|
$page->assign('LANGUAGESELECTION', $languageselection);
|
||||||
$page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
|
$page->assign('LANGUAGES', I18n::getLanguageLabels(I18n::getAvailableLanguages()));
|
||||||
$page->assign('TEMPLATESELECTION', $templateselection);
|
$page->assign('TEMPLATESELECTION', $templateselection);
|
||||||
|
|
|
@ -190,11 +190,7 @@ class Paste extends AbstractModel
|
||||||
if (!array_key_exists('salt', $this->_data['meta'])) {
|
if (!array_key_exists('salt', $this->_data['meta'])) {
|
||||||
$this->get();
|
$this->get();
|
||||||
}
|
}
|
||||||
return hash_hmac(
|
return hash_hmac('sha256', $this->getId(), $this->_data['meta']['salt']);
|
||||||
$this->_conf->getKey('zerobincompatibility') ? 'sha1' : 'sha256',
|
|
||||||
$this->getId(),
|
|
||||||
$this->_data['meta']['salt']
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -49,15 +49,9 @@ if ($QRCODE) :
|
||||||
<?php $this->_scriptTag('js/kjua-0.9.0.js', 'async'); ?>
|
<?php $this->_scriptTag('js/kjua-0.9.0.js', 'async'); ?>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
if ($ZEROBINCOMPATIBILITY) :
|
|
||||||
?>
|
|
||||||
<?php $this->_scriptTag('js/base64-1.7.js', 'async'); ?>
|
|
||||||
<?php
|
|
||||||
endif;
|
|
||||||
?>
|
?>
|
||||||
<?php $this->_scriptTag('js/zlib-1.3.1-1.js', 'async'); ?>
|
<?php $this->_scriptTag('js/zlib-1.3.1-1.js', 'async'); ?>
|
||||||
<?php $this->_scriptTag('js/base-x-4.0.0.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/base-x-4.0.0.js', 'defer'); ?>
|
||||||
<?php $this->_scriptTag('js/rawinflate-0.3.js', 'defer'); ?>
|
|
||||||
<?php $this->_scriptTag('js/bootstrap-3.4.1.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/bootstrap-3.4.1.js', 'defer'); ?>
|
||||||
<?php
|
<?php
|
||||||
if ($SYNTAXHIGHLIGHTING) :
|
if ($SYNTAXHIGHLIGHTING) :
|
||||||
|
|
|
@ -32,15 +32,9 @@ if ($QRCODE) :
|
||||||
<?php $this->_scriptTag('js/kjua-0.9.0.js', 'async'); ?>
|
<?php $this->_scriptTag('js/kjua-0.9.0.js', 'async'); ?>
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
if ($ZEROBINCOMPATIBILITY) :
|
|
||||||
?>
|
|
||||||
<?php $this->_scriptTag('js/base64-1.7.js', 'defer'); ?>
|
|
||||||
<?php
|
|
||||||
endif;
|
|
||||||
?>
|
?>
|
||||||
<?php $this->_scriptTag('js/zlib-1.3.1-1.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/zlib-1.3.1-1.js', 'defer'); ?>
|
||||||
<?php $this->_scriptTag('js/base-x-4.0.0.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/base-x-4.0.0.js', 'defer'); ?>
|
||||||
<?php $this->_scriptTag('js/rawinflate-0.3.js', 'defer'); ?>
|
|
||||||
<?php $this->_scriptTag('js/bootstrap-5.3.3.js', 'async'); ?>
|
<?php $this->_scriptTag('js/bootstrap-5.3.3.js', 'async'); ?>
|
||||||
<?php $this->_scriptTag('js/dark-mode-switch.js', 'defer'); ?>
|
<?php $this->_scriptTag('js/dark-mode-switch.js', 'defer'); ?>
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -52,7 +52,6 @@ class ViewTest extends TestCase
|
||||||
$page->assign('BURNAFTERREADINGSELECTED', false);
|
$page->assign('BURNAFTERREADINGSELECTED', false);
|
||||||
$page->assign('PASSWORD', true);
|
$page->assign('PASSWORD', true);
|
||||||
$page->assign('FILEUPLOAD', false);
|
$page->assign('FILEUPLOAD', false);
|
||||||
$page->assign('ZEROBINCOMPATIBILITY', false);
|
|
||||||
$page->assign('INFO', 'example');
|
$page->assign('INFO', 'example');
|
||||||
$page->assign('NOTICE', 'example');
|
$page->assign('NOTICE', 'example');
|
||||||
$page->assign('LANGUAGESELECTION', '');
|
$page->assign('LANGUAGESELECTION', '');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue