implement zlib via web assembly, replacing rawdeflate library
This commit is contained in:
parent
5ce3aa2817
commit
0ad5b3e900
8 changed files with 216 additions and 1724 deletions
|
@ -10,8 +10,8 @@ global.WebCrypto = require('node-webcrypto-ossl');
|
||||||
|
|
||||||
// application libraries to test
|
// application libraries to test
|
||||||
global.$ = global.jQuery = require('./jquery-3.3.1');
|
global.$ = global.jQuery = require('./jquery-3.3.1');
|
||||||
global.RawDeflate = require('./rawdeflate-0.5').RawDeflate;
|
global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
|
||||||
global.RawDeflate.inflate = require('./rawinflate-0.3').RawDeflate.inflate;
|
require('./zlib-1.2.11');
|
||||||
require('./prettify');
|
require('./prettify');
|
||||||
global.prettyPrint = window.PR.prettyPrint;
|
global.prettyPrint = window.PR.prettyPrint;
|
||||||
global.prettyPrintOne = window.PR.prettyPrintOne;
|
global.prettyPrintOne = window.PR.prettyPrintOne;
|
||||||
|
|
|
@ -32,6 +32,13 @@ jQuery(document).ready(function() {
|
||||||
jQuery.PrivateBin = (function($, RawDeflate) {
|
jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zlib library interface
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
let z;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* static Helper methods
|
* static Helper methods
|
||||||
*
|
*
|
||||||
|
@ -619,40 +626,67 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* compress a string, returns base64 encoded data (deflate compression)
|
* compress a string (deflate compression), returns buffer
|
||||||
*
|
*
|
||||||
* @name CryptTool.compress
|
* @name CryptTool.compress
|
||||||
|
* @async
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
* @param {string} message
|
* @param {string} message
|
||||||
* @return {string} base64 data
|
* @param {string} mode
|
||||||
|
* @return {ArrayBuffer} data
|
||||||
*/
|
*/
|
||||||
function compress(message)
|
async function compress(message, mode)
|
||||||
{
|
{
|
||||||
// detect presence of Base64.js, indicating legacy ZeroBin paste
|
message = StrToArr(
|
||||||
if (typeof Base64 === 'undefined') {
|
utob(message)
|
||||||
return btoa( utob( RawDeflate.deflate( utob( message ) ) ) );
|
);
|
||||||
} else {
|
if (mode === 'zlib') {
|
||||||
return Base64.toBase64( RawDeflate.deflate( Base64.utob( message ) ) );
|
return z.deflate(message).buffer;
|
||||||
}
|
}
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* decompress a base64 encoded data (deflate compression), returns string
|
* decompress potentially base64 encoded, deflate compressed buffer, returns string
|
||||||
*
|
*
|
||||||
* @name CryptTool.decompress
|
* @name CryptTool.decompress
|
||||||
|
* @async
|
||||||
* @function
|
* @function
|
||||||
* @private
|
* @private
|
||||||
* @param {string} data base64 data
|
* @param {ArrayBuffer} data
|
||||||
|
* @param {string} mode
|
||||||
* @return {string} message
|
* @return {string} message
|
||||||
*/
|
*/
|
||||||
function decompress(data)
|
async function decompress(data, mode)
|
||||||
{
|
{
|
||||||
|
if (mode === 'zlib' || mode === 'none') {
|
||||||
|
if (mode === 'zlib') {
|
||||||
|
data = z.inflate(new Uint8Array(data)).buffer;
|
||||||
|
}
|
||||||
|
return btou(
|
||||||
|
ArrToStr(data)
|
||||||
|
);
|
||||||
|
}
|
||||||
// detect presence of Base64.js, indicating legacy ZeroBin paste
|
// detect presence of Base64.js, indicating legacy ZeroBin paste
|
||||||
if (typeof Base64 === 'undefined') {
|
if (typeof Base64 === 'undefined') {
|
||||||
return btou( RawDeflate.inflate( btou( atob( data ) ) ) );
|
return btou(
|
||||||
|
RawDeflate.inflate(
|
||||||
|
btou(
|
||||||
|
atob(
|
||||||
|
ArrToStr(data)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return Base64.btou( RawDeflate.inflate( Base64.fromBase64( data ) ) );
|
return Base64.btou(
|
||||||
|
RawDeflate.inflate(
|
||||||
|
Base64.fromBase64(
|
||||||
|
ArrToStr(data)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -779,7 +813,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
* @param {string} password
|
* @param {string} password
|
||||||
* @param {string} message
|
* @param {string} message
|
||||||
* @param {array} adata
|
* @param {array} adata
|
||||||
* @return {array} encrypted message & adata containing encryption spec
|
* @return {array} encrypted message in base64 encoding & adata containing encryption spec
|
||||||
*/
|
*/
|
||||||
me.cipher = async function(key, password, message, adata)
|
me.cipher = async function(key, password, message, adata)
|
||||||
{
|
{
|
||||||
|
@ -793,17 +827,11 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
128, // tag size
|
128, // tag size
|
||||||
'aes', // algorithm
|
'aes', // algorithm
|
||||||
'gcm', // algorithm mode
|
'gcm', // algorithm mode
|
||||||
'none' // compression
|
'zlib' // compression
|
||||||
], encodedSpec = [
|
], encodedSpec = [];
|
||||||
btoa(spec[0]),
|
for (let i = 0; i < spec.length; ++i) {
|
||||||
btoa(spec[1]),
|
encodedSpec[i] = i < 2 ? btoa(spec[i]) : spec[i];
|
||||||
spec[2],
|
}
|
||||||
spec[3],
|
|
||||||
spec[4],
|
|
||||||
spec[5],
|
|
||||||
spec[6],
|
|
||||||
spec[7]
|
|
||||||
];
|
|
||||||
if (adata.length === 0) {
|
if (adata.length === 0) {
|
||||||
// comment
|
// comment
|
||||||
adata = encodedSpec;
|
adata = encodedSpec;
|
||||||
|
@ -819,7 +847,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
await window.crypto.subtle.encrypt(
|
await window.crypto.subtle.encrypt(
|
||||||
cryptoSettings(JSON.stringify(adata), spec),
|
cryptoSettings(JSON.stringify(adata), spec),
|
||||||
await deriveKey(key, password, spec),
|
await deriveKey(key, password, spec),
|
||||||
StrToArr(utob(message))
|
await compress(message, spec[7])
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -864,28 +892,21 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
} else {
|
} else {
|
||||||
throw 'unsupported message format';
|
throw 'unsupported message format';
|
||||||
}
|
}
|
||||||
compression = encodedSpec[7];
|
|
||||||
let spec = encodedSpec, plainText = '';
|
let spec = encodedSpec, plainText = '';
|
||||||
spec[0] = atob(spec[0]);
|
spec[0] = atob(spec[0]);
|
||||||
spec[1] = atob(spec[1]);
|
spec[1] = atob(spec[1]);
|
||||||
try {
|
try {
|
||||||
plainText = ArrToStr(
|
return await decompress(
|
||||||
await window.crypto.subtle.decrypt(
|
await window.crypto.subtle.decrypt(
|
||||||
cryptoSettings(adataString, spec),
|
cryptoSettings(adataString, spec),
|
||||||
await deriveKey(key, password, spec),
|
await deriveKey(key, password, spec),
|
||||||
StrToArr(atob(cipherMessage))
|
StrToArr(atob(cipherMessage))
|
||||||
)
|
),
|
||||||
|
encodedSpec[7]
|
||||||
);
|
);
|
||||||
} catch(err) {
|
} catch(err) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
if (compression === 'none') {
|
|
||||||
return btou(plainText);
|
|
||||||
} else if (compression === 'rawdeflate') {
|
|
||||||
return decompress(plainText);
|
|
||||||
} else {
|
|
||||||
throw 'unsupported compression format';
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4487,7 +4508,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
* @name Controller.init
|
* @name Controller.init
|
||||||
* @function
|
* @function
|
||||||
*/
|
*/
|
||||||
me.init = function()
|
me.init = async function()
|
||||||
{
|
{
|
||||||
// first load translations
|
// first load translations
|
||||||
I18n.loadTranslations();
|
I18n.loadTranslations();
|
||||||
|
@ -4505,6 +4526,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||||
Prompt.init();
|
Prompt.init();
|
||||||
TopNav.init();
|
TopNav.init();
|
||||||
UiHelper.init();
|
UiHelper.init();
|
||||||
|
z = (await zlib);
|
||||||
|
|
||||||
// check whether existing paste needs to be shown
|
// check whether existing paste needs to be shown
|
||||||
try {
|
try {
|
||||||
|
|
1675
js/rawdeflate-0.5.js
1675
js/rawdeflate-0.5.js
File diff suppressed because it is too large
Load diff
|
@ -2,12 +2,12 @@
|
||||||
require('../common');
|
require('../common');
|
||||||
|
|
||||||
describe('CryptTool', function () {
|
describe('CryptTool', function () {
|
||||||
afterEach(async function () {
|
|
||||||
// pause to let async functions conclude
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 1900));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('cipher & decipher', function () {
|
describe('cipher & decipher', function () {
|
||||||
|
afterEach(async function () {
|
||||||
|
// pause to let async functions conclude
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1900));
|
||||||
|
});
|
||||||
|
|
||||||
this.timeout(30000);
|
this.timeout(30000);
|
||||||
it('can en- and decrypt any message', function () {
|
it('can en- and decrypt any message', function () {
|
||||||
jsc.check(jsc.forall(
|
jsc.check(jsc.forall(
|
||||||
|
@ -29,7 +29,8 @@ describe('CryptTool', function () {
|
||||||
clean();
|
clean();
|
||||||
return message === plaintext;
|
return message === plaintext;
|
||||||
}
|
}
|
||||||
));
|
),
|
||||||
|
{tests: 3});
|
||||||
});
|
});
|
||||||
|
|
||||||
// The below static unit tests are included to ensure deciphering of "classic"
|
// The below static unit tests are included to ensure deciphering of "classic"
|
||||||
|
|
144
js/zlib-1.2.11.js
Normal file
144
js/zlib-1.2.11.js
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
let ret;
|
||||||
|
|
||||||
|
async function initialize() {
|
||||||
|
if (ret) return ret;
|
||||||
|
|
||||||
|
const COMPRESSION_LEVEL = 9;
|
||||||
|
const NO_ZLIB_HEADER = -1;
|
||||||
|
const CHUNK_SIZE = 32 * 1024;
|
||||||
|
const map = {};
|
||||||
|
const memory = new WebAssembly.Memory({
|
||||||
|
initial: 1,
|
||||||
|
maximum: 1024, // 64MB
|
||||||
|
});
|
||||||
|
const env = {
|
||||||
|
memory,
|
||||||
|
writeToJs(ptr, size) {
|
||||||
|
const o = map[ptr];
|
||||||
|
o.onData(new Uint8Array(memory.buffer, dstPtr, size));
|
||||||
|
},
|
||||||
|
_abort: errno => { console.error(`Error: ${errno}`) },
|
||||||
|
_grow: () => { },
|
||||||
|
};
|
||||||
|
|
||||||
|
let ins;
|
||||||
|
if (typeof fetch === 'undefined') {
|
||||||
|
const buff = fs.readFileSync('zlib-1.2.11.wasm');
|
||||||
|
const module = await WebAssembly.compile(buff);
|
||||||
|
ins = await WebAssembly.instantiate(module, { env });
|
||||||
|
} else {
|
||||||
|
ins = await WebAssembly.instantiateStreaming(fetch('zlib-1.2.11.wasm'));
|
||||||
|
}
|
||||||
|
|
||||||
|
const srcPtr = ins.exports._malloc(CHUNK_SIZE);
|
||||||
|
const dstPtr = ins.exports._malloc(CHUNK_SIZE);
|
||||||
|
|
||||||
|
class RawDef {
|
||||||
|
constructor() {
|
||||||
|
this.zstreamPtr = ins.exports._createDeflateContext(COMPRESSION_LEVEL, NO_ZLIB_HEADER);
|
||||||
|
map[this.zstreamPtr] = this;
|
||||||
|
this.offset = 0;
|
||||||
|
this.buff = new Uint8Array(CHUNK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
deflate(chunk, flush) {
|
||||||
|
const src = new Uint8Array(memory.buffer, srcPtr, chunk.length);
|
||||||
|
src.set(chunk);
|
||||||
|
ins.exports._deflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE, flush);
|
||||||
|
}
|
||||||
|
|
||||||
|
onData(chunk) {
|
||||||
|
if (this.buff.length < this.offset + chunk.length) {
|
||||||
|
const buff = this.buff;
|
||||||
|
this.buff = new Uint8Array(this.buff.length * 2);
|
||||||
|
this.buff.set(buff);
|
||||||
|
}
|
||||||
|
this.buff.set(chunk, this.offset);
|
||||||
|
this.offset += chunk.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
ins.exports._freeDeflateContext(this.zstreamPtr);
|
||||||
|
delete map[this.zstreamPtr];
|
||||||
|
this.buff = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBuffer() {
|
||||||
|
const res = new Uint8Array(this.offset);
|
||||||
|
for (let i = 0; i < this.offset; ++i) {
|
||||||
|
res[i] = this.buff[i];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class RawInf {
|
||||||
|
constructor() {
|
||||||
|
this.zstreamPtr = ins.exports._createInflateContext(NO_ZLIB_HEADER);
|
||||||
|
map[this.zstreamPtr] = this;
|
||||||
|
this.offset = 0;
|
||||||
|
this.buff = new Uint8Array(CHUNK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inflate(chunk) {
|
||||||
|
const src = new Uint8Array(memory.buffer, srcPtr, chunk.length);
|
||||||
|
src.set(chunk);
|
||||||
|
ins.exports._inflate(this.zstreamPtr, srcPtr, dstPtr, chunk.length, CHUNK_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
onData(chunk) {
|
||||||
|
if (this.buff.length < this.offset + chunk.length) {
|
||||||
|
const buff = this.buff;
|
||||||
|
this.buff = new Uint8Array(this.buff.length * 2);
|
||||||
|
this.buff.set(buff);
|
||||||
|
}
|
||||||
|
this.buff.set(chunk, this.offset);
|
||||||
|
this.offset += chunk.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
ins.exports._freeInflateContext(this.zstreamPtr);
|
||||||
|
delete map[this.zstreamPtr];
|
||||||
|
this.buff = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBuffer() {
|
||||||
|
const res = new Uint8Array(this.offset);
|
||||||
|
for (let i = 0; i < this.offset; ++i) {
|
||||||
|
res[i] = this.buff[i];
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = {
|
||||||
|
inflate(rawDeflateBuffer) {
|
||||||
|
const rawInf = new RawInf();
|
||||||
|
for (let offset = 0; offset < rawDeflateBuffer.length; offset += CHUNK_SIZE) {
|
||||||
|
const end = Math.min(offset + CHUNK_SIZE, rawDeflateBuffer.length);
|
||||||
|
const chunk = rawDeflateBuffer.subarray(offset, end);
|
||||||
|
rawInf.inflate(chunk);
|
||||||
|
}
|
||||||
|
const ret = rawInf.getBuffer();
|
||||||
|
rawInf.destroy();
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
deflate(rawInflateBuffer) {
|
||||||
|
const rawDef = new RawDef();
|
||||||
|
for (let offset = 0; offset < rawInflateBuffer.length; offset += CHUNK_SIZE) {
|
||||||
|
const end = Math.min(offset + CHUNK_SIZE, rawInflateBuffer.length);
|
||||||
|
const chunk = rawInflateBuffer.subarray(offset, end);
|
||||||
|
rawDef.deflate(chunk, rawInflateBuffer.length <= offset + CHUNK_SIZE);
|
||||||
|
}
|
||||||
|
const ret = rawDef.getBuffer();
|
||||||
|
rawDef.destroy();
|
||||||
|
return ret;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
global.zlib = initialize();
|
BIN
js/zlib-1.2.11.wasm
Normal file
BIN
js/zlib-1.2.11.wasm
Normal file
Binary file not shown.
|
@ -55,7 +55,7 @@ if ($ZEROBINCOMPATIBILITY):
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/rawdeflate-0.5.js" integrity="sha512-tTdZ7qMr7tt5VQy4iCHu6/aGB12eRwbUy+AEI5rXntfsjcRfBeeqJloMsBU9FrGk1bIYLiuND/FhU42LO1bi0g==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.11.js" integrity="sha512-UOOlXbjGGS/ezf/cbE3Hc4L0ybB2NQBbk523tAT8m1TsnagkIgYUKuFfl+DL4wZbu7IopLvhI2kl+61+2oaaGA==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/bootstrap-3.3.7.js" integrity="sha512-iztkobsvnjKfAtTNdHkGVjAYTrrtlC7mGp/54c40wowO7LhURYl3gVzzcEqGl/qKXQltJ2HwMrdLcNUdo+N/RQ==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/bootstrap-3.3.7.js" integrity="sha512-iztkobsvnjKfAtTNdHkGVjAYTrrtlC7mGp/54c40wowO7LhURYl3gVzzcEqGl/qKXQltJ2HwMrdLcNUdo+N/RQ==" crossorigin="anonymous"></script>
|
||||||
<?php
|
<?php
|
||||||
|
@ -71,7 +71,7 @@ if ($MARKDOWN):
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.7.js" integrity="sha512-VnKJHLosO8z2ojNvWk9BEKYqnhZyWK9rM90FgZUUEp/PRnUqR5OLLKE0a3BkVmn7YgB7LXRrjHgFHQYKd6DAIA==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.7.js" integrity="sha512-VnKJHLosO8z2ojNvWk9BEKYqnhZyWK9rM90FgZUUEp/PRnUqR5OLLKE0a3BkVmn7YgB7LXRrjHgFHQYKd6DAIA==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-cA9eDF/cppVcDihgEmTRmd2NGcSmT3XQnvO5uGQ6+rkr2VRIyIq4oHlBUvPGIBaJ3Fr40ovgUFeIJOIDyA/gXg==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-i5UkiqPD3iKG9PN5jspS3LhMrJQz5HLDEqXuPrVTr/yKY5FpGbhY5hZ72YLU6ixElnZpW7gPDnkf8GmLSc/N4Q==" crossorigin="anonymous"></script>
|
||||||
<!--[if lt IE 10]>
|
<!--[if lt IE 10]>
|
||||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
|
@ -34,7 +34,7 @@ if ($ZEROBINCOMPATIBILITY):
|
||||||
<?php
|
<?php
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/rawdeflate-0.5.js" integrity="sha512-tTdZ7qMr7tt5VQy4iCHu6/aGB12eRwbUy+AEI5rXntfsjcRfBeeqJloMsBU9FrGk1bIYLiuND/FhU42LO1bi0g==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.11.js" integrity="sha512-UOOlXbjGGS/ezf/cbE3Hc4L0ybB2NQBbk523tAT8m1TsnagkIgYUKuFfl+DL4wZbu7IopLvhI2kl+61+2oaaGA==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/rawinflate-0.3.js" integrity="sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==" crossorigin="anonymous"></script>
|
||||||
<?php
|
<?php
|
||||||
if ($SYNTAXHIGHLIGHTING):
|
if ($SYNTAXHIGHLIGHTING):
|
||||||
|
@ -49,7 +49,7 @@ if ($MARKDOWN):
|
||||||
endif;
|
endif;
|
||||||
?>
|
?>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.7.js" integrity="sha512-VnKJHLosO8z2ojNvWk9BEKYqnhZyWK9rM90FgZUUEp/PRnUqR5OLLKE0a3BkVmn7YgB7LXRrjHgFHQYKd6DAIA==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/purify-1.0.7.js" integrity="sha512-VnKJHLosO8z2ojNvWk9BEKYqnhZyWK9rM90FgZUUEp/PRnUqR5OLLKE0a3BkVmn7YgB7LXRrjHgFHQYKd6DAIA==" crossorigin="anonymous"></script>
|
||||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-cA9eDF/cppVcDihgEmTRmd2NGcSmT3XQnvO5uGQ6+rkr2VRIyIq4oHlBUvPGIBaJ3Fr40ovgUFeIJOIDyA/gXg==" crossorigin="anonymous"></script>
|
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-i5UkiqPD3iKG9PN5jspS3LhMrJQz5HLDEqXuPrVTr/yKY5FpGbhY5hZ72YLU6ixElnZpW7gPDnkf8GmLSc/N4Q==" crossorigin="anonymous"></script>
|
||||||
<!--[if lt IE 10]>
|
<!--[if lt IE 10]>
|
||||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
Loading…
Reference in a new issue