From 37ee3b1c7c0cdf7c17bf8b48b5ecb47d84185bda Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 7 Jan 2024 14:10:43 +0100 Subject: [PATCH 1/7] refactor URL generators --- js/common.js | 21 +++++++++++++ js/test/PasteStatus.js | 68 ++++++++++++------------------------------ 2 files changed, 40 insertions(+), 49 deletions(-) diff --git a/js/common.js b/js/common.js index 295fd090..c14a76ca 100644 --- a/js/common.js +++ b/js/common.js @@ -131,3 +131,24 @@ exports.jscMimeTypes = function() { exports.jscFormats = function() { return jsc.elements(formats); }; + +// provides random URLs +exports.jscUrl = function(withFragment = true, withQuery = true) { + let url = { + schema: exports.jscSchemas(), + address: jsc.nearray(exports.jscA2zString()), + }; + if (withFragment) { + url.fragment = jsc.string; + } + if(withQuery) { + url.query = jsc.array(exports.jscQueryString()); + } + return jsc.record(url); +}; + +exports.urlToString = function (url) { + return url.schema + '://' + url.address.join('') + '/' + (url.query ? '?' + + encodeURI(url.query.join('').replace(/^&+|&+$/gm,'')) : '') + + (url.fragment ? '#' + encodeURI(url.fragment) : ''); +}; \ No newline at end of file diff --git a/js/test/PasteStatus.js b/js/test/PasteStatus.js index baa6ab33..8b19c75b 100644 --- a/js/test/PasteStatus.js +++ b/js/test/PasteStatus.js @@ -7,21 +7,11 @@ describe('PasteStatus', function () { jsc.property( 'creates a notification after a successfull paste upload', - common.jscSchemas(), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - 'string', - common.jscSchemas(), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - function ( - schema1, address1, query1, fragment1, - schema2, address2, query2 - ) { - var expected1 = schema1 + '://' + address1.join('') + '/?' + - encodeURI(query1.join('').replace(/^&+|&+$/gm,'') + '#' + fragment1), - expected2 = schema2 + '://' + address2.join('') + '/?' + - encodeURI(query2.join('').replace(/^&+|&+$/gm,'')), + common.jscUrl(), + common.jscUrl(false), + function (url1, url2) { + const expected1 = common.urlToString(url1), + expected2 = common.urlToString(url2), clean = jsdom(); $('body').html('
'); $.PrivateBin.PasteStatus.init(); @@ -41,25 +31,23 @@ describe('PasteStatus', function () { 'extracts and updates URLs found in given response', jsc.elements(['http','https']), 'nestring', - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - jsc.array(common.jscAlnumString()), - 'string', - function (schema, domain, tld, query, shortid, fragment) { + common.jscUrl(), + function (schema, domain, url) { domain = domain.replace(/\P{Letter}|[\u00AA-\u00BA]/gu,'').toLowerCase(); if (domain.length === 0) { domain = 'a'; } - const expected = '.' + tld.join('') + '/' + (query.length > 0 ? - ('?' + encodeURI(query.join('').replace(/^&+|&+$/gm,'')) + - shortid.join('')) : '') + (fragment.length > 0 ? - ('#' + encodeURI(fragment)) : ''), + url.schema = schema; + url.address.unshift('.'); + url.address = domain.split('').concat(url.address); + const urlString = common.urlToString(url), + expected = urlString.substring((schema + '://' + domain).length), clean = jsdom(); $('body').html('
'); $.PrivateBin.PasteStatus.init(); $.PrivateBin.PasteStatus.createPasteNotification('', ''); - $.PrivateBin.PasteStatus.extractUrl(schema + '://' + domain + expected); + $.PrivateBin.PasteStatus.extractUrl(urlString); const result = $('#pasteurl')[0].href; clean(); @@ -79,18 +67,9 @@ describe('PasteStatus', function () { 'shows burn after reading message or remaining time v1', 'bool', 'nat', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscQueryString()), - 'string', - function ( - burnafterreading, remainingTime, - schema, address, query, fragment - ) { - var clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + - '/?' + query.join('') + '#' + fragment - }), + common.jscUrl(), + function (burnafterreading, remainingTime, url) { + let clean = jsdom('', {url: common.urlToString(url)}), result; $('body').html(''); $.PrivateBin.PasteStatus.init(); @@ -117,18 +96,9 @@ describe('PasteStatus', function () { 'shows burn after reading message or remaining time v2', 'bool', 'nat', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscQueryString()), - 'string', - function ( - burnafterreading, remainingTime, - schema, address, query, fragment - ) { - var clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + - '/?' + query.join('') + '#' + fragment - }), + common.jscUrl(), + function (burnafterreading, remainingTime, url) { + let clean = jsdom('', {url: common.urlToString(url)}), result; $('body').html(''); $.PrivateBin.PasteStatus.init(); From d493ba73376b3036f539dcfb4ec42ae17c9c81ed Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 7 Jan 2024 15:47:29 +0100 Subject: [PATCH 2/7] refactor URL generators --- js/test/Helper.js | 28 ++++++------ js/test/Model.js | 112 ++++++++++++++++------------------------------ 2 files changed, 52 insertions(+), 88 deletions(-) diff --git a/js/test/Helper.js b/js/test/Helper.js index 2cd5202f..434cd3e5 100644 --- a/js/test/Helper.js +++ b/js/test/Helper.js @@ -96,36 +96,34 @@ describe('Helper', function () { jsc.property( 'replaces URLs with anchors', 'string', - jsc.elements(['http', 'https', 'ftp']), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), + common.jscUrl(), jsc.array(common.jscHashString()), 'string', - function (prefix, schema, address, query, fragment, postfix) { - query = query.join(''); - fragment = fragment.join(''); + function (prefix, url, fragment, postfix) { prefix = prefix.replace(/\r|\f/g, '\n').replace(/\u0000/g, '').replace(/\u000b/g, ''); postfix = ' ' + postfix.replace(/\r/g, '\n').replace(/\u0000/g, ''); - let url = schema + '://' + address.join('') + '/?' + query + '#' + fragment, + url.fragment = fragment.join(''); + let urlString = common.urlToString(url), clean = jsdom(); $('body').html('
'); let e = $('#foo'); // special cases: When the query string and fragment imply the beginning of an HTML entity, eg. � or &#x if ( - query.slice(-1) === '&' && - (parseInt(fragment.substring(0, 1), 10) >= 0 || fragment.charAt(0) === 'x' ) - ) - { - url = schema + '://' + address.join('') + '/?' + query.substring(0, query.length - 1); + url.query[-1] === '&' && + (parseInt(url.fragment.charAt(0), 10) >= 0 || url.fragment.charAt(0) === 'x') + ) { + url.query.pop(); + urlString = common.urlToString(url); postfix = ''; } - e.text(prefix + url + postfix); + e.text(prefix + urlString + postfix); $.PrivateBin.Helper.urls2links(e); let result = e.html(); clean(); - url = $('
').text(url).html(); - return $('
').text(prefix).html() + '' + url + '' + $('
').text(postfix).html() === result; + urlString = $('
').text(urlString).html(); + const expected = $('
').text(prefix).html() + '' + urlString + '' + $('
').text(postfix).html(); + return $('
').text(prefix).html() + '' + urlString + '' + $('
').text(postfix).html() === result; } ); jsc.property( diff --git a/js/test/Model.js b/js/test/Model.js index 9ebc5472..491154b4 100644 --- a/js/test/Model.js +++ b/js/test/Model.js @@ -80,23 +80,22 @@ describe('Model', function () { jsc.property( 'returns the query string without separator, if any', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), + common.jscUrl(), jsc.tuple(new Array(16).fill(common.jscHexString)), jsc.array(common.jscQueryString()), jsc.array(common.jscQueryString()), - 'string', - function (schema, address, pasteId, queryStart, queryEnd, fragment) { - var pasteIdString = pasteId.join(''), - queryStartString = queryStart.join('') + (queryStart.length > 0 ? '&' : ''), - queryEndString = (queryEnd.length > 0 ? '&' : '') + queryEnd.join(''), - queryString = queryStartString + pasteIdString + queryEndString, - clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + - '/?' + queryString + '#' + fragment - }); - global.URL = require('jsdom-url').URL; - var result = $.PrivateBin.Model.getPasteId(); + function (url, pasteId, queryStart, queryEnd) { + if (queryStart.length > 0) { + queryStart.push('&'); + } + if (queryEnd.length > 0) { + queryEnd.unshift('&'); + } + url.query = queryStart.concat(pasteId, queryEnd); + const pasteIdString = pasteId.join(''), + clean = jsdom('', {url: common.urlToString(url)}); + global.URL = require('jsdom-url').URL; + const result = $.PrivateBin.Model.getPasteId(); $.PrivateBin.Model.reset(); clean(); return pasteIdString === result; @@ -104,14 +103,9 @@ describe('Model', function () { ); jsc.property( 'throws exception on empty query string', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - 'string', - function (schema, address, fragment) { - var clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + - '/#' + fragment - }), + common.jscUrl(true, false), + function (url) { + let clean = jsdom('', {url: common.urlToString(url)}), result = false; global.URL = require('jsdom-url').URL; try { @@ -135,35 +129,24 @@ describe('Model', function () { jsc.property( 'returns the fragment of a v1 URL', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - 'nestring', - function (schema, address, query, fragment) { - const fragmentString = common.btoa(fragment.padStart(32, '\u0000')); - let clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + - '/?' + query.join('') + '#' + fragmentString - }), + common.jscUrl(), + function (url) { + url.fragment = common.btoa(url.fragment.padStart(32, '\u0000')); + const clean = jsdom('', {url: common.urlToString(url)}), result = $.PrivateBin.Model.getPasteKey(); $.PrivateBin.Model.reset(); clean(); - return fragmentString === result; + return url.fragment === result; } ); jsc.property( 'returns the v1 fragment stripped of trailing query parts', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - 'nestring', + common.jscUrl(), jsc.array(common.jscHashString()), - function (schema, address, query, fragment, trail) { - const fragmentString = common.btoa(fragment.padStart(32, '\u0000')); - let clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + '/?' + - query.join('') + '#' + fragmentString + '&' + trail.join('') - }), + function (url, trail) { + const fragmentString = common.btoa(url.fragment.padStart(32, '\u0000')); + url.fragment = fragmentString + '&' + trail.join(''); + const clean = jsdom('', {url: common.urlToString(url)}), result = $.PrivateBin.Model.getPasteKey(); $.PrivateBin.Model.reset(); clean(); @@ -172,18 +155,12 @@ describe('Model', function () { ); jsc.property( 'returns the fragment of a v2 URL', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - 'nestring', - function (schema, address, query, fragment) { + common.jscUrl(), + function (url) { // base58 strips leading NULL bytes, so the string is padded with these if not found - fragment = fragment.padStart(32, '\u0000'); - let fragmentString = $.PrivateBin.CryptTool.base58encode(fragment), - clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + - '/?' + query.join('') + '#' + fragmentString - }), + const fragment = url.fragment.padStart(32, '\u0000'); + url.fragment = $.PrivateBin.CryptTool.base58encode(fragment); + const clean = jsdom('', {url: common.urlToString(url)}), result = $.PrivateBin.Model.getPasteKey(); $.PrivateBin.Model.reset(); clean(); @@ -192,19 +169,13 @@ describe('Model', function () { ); jsc.property( 'returns the v2 fragment stripped of trailing query parts', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - 'nestring', + common.jscUrl(), jsc.array(common.jscHashString()), - function (schema, address, query, fragment, trail) { + function (url, trail) { // base58 strips leading NULL bytes, so the string is padded with these if not found - fragment = fragment.padStart(32, '\u0000'); - let fragmentString = $.PrivateBin.CryptTool.base58encode(fragment), - clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + '/?' + - query.join('') + '#' + fragmentString + '&' + trail.join('') - }), + const fragment = url.fragment.padStart(32, '\u0000'); + url.fragment = $.PrivateBin.CryptTool.base58encode(fragment) + '&' + trail.join(''); + const clean = jsdom('', {url: common.urlToString(url)}), result = $.PrivateBin.Model.getPasteKey(); $.PrivateBin.Model.reset(); clean(); @@ -213,14 +184,9 @@ describe('Model', function () { ); jsc.property( 'throws exception on empty fragment of the URL', - jsc.nearray(common.jscA2zString()), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - function (schema, address, query) { - var clean = jsdom('', { - url: schema.join('') + '://' + address.join('') + - '/?' + query.join('') - }), + common.jscUrl(false, false), + function (url) { + let clean = jsdom('', {url: common.urlToString(url)}), result = false; try { $.PrivateBin.Model.getPasteKey(); From fd82b937a9e81a78ad32124615294281e3506d6a Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 7 Jan 2024 16:06:24 +0100 Subject: [PATCH 3/7] refactor URL generators --- js/test/Model.js | 4 ++-- js/test/UiHelper.js | 32 +++++++++++++------------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/js/test/Model.js b/js/test/Model.js index 491154b4..db2198ba 100644 --- a/js/test/Model.js +++ b/js/test/Model.js @@ -80,7 +80,7 @@ describe('Model', function () { jsc.property( 'returns the query string without separator, if any', - common.jscUrl(), + common.jscUrl(true, false), jsc.tuple(new Array(16).fill(common.jscHexString)), jsc.array(common.jscQueryString()), jsc.array(common.jscQueryString()), @@ -184,7 +184,7 @@ describe('Model', function () { ); jsc.property( 'throws exception on empty fragment of the URL', - common.jscUrl(false, false), + common.jscUrl(false), function (url) { let clean = jsdom('', {url: common.urlToString(url)}), result = false; diff --git a/js/test/UiHelper.js b/js/test/UiHelper.js index 817345c6..63968fdb 100644 --- a/js/test/UiHelper.js +++ b/js/test/UiHelper.js @@ -13,10 +13,9 @@ describe('UiHelper', function () { jsc.property( 'redirects to home, when the state is null', - common.jscSchemas(), - jsc.nearray(common.jscA2zString()), - function (schema, address) { - var expected = schema + '://' + address.join('') + '/', + common.jscUrl(false, false), + function (url) { + const expected = common.urlToString(url), clean = jsdom('', {url: expected}); // make window.location.href writable @@ -34,13 +33,11 @@ describe('UiHelper', function () { jsc.property( 'does not redirect to home, when a new paste is created', - common.jscSchemas(), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), + common.jscUrl(false), jsc.nearray(common.jscBase64String()), - function (schema, address, query, fragment) { - var expected = schema + '://' + address.join('') + '/?' + - query.join('') + '#' + fragment.join(''), + function (url, fragment) { + url.fragment = fragment.join(''); + const expected = common.urlToString(url), clean = jsdom('', {url: expected}); // make window.location.href writable @@ -67,15 +64,12 @@ describe('UiHelper', function () { jsc.property( 'redirects to home', - common.jscSchemas(), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscQueryString()), - jsc.nearray(common.jscBase64String()), - function (schema, address, query, fragment) { - var expected = schema + '://' + address.join('') + '/', - clean = jsdom('', { - url: expected + '?' + query.join('') + '#' + fragment.join('') - }); + common.jscUrl(), + function (url) { + const clean = jsdom('', {url: common.urlToString(url)}); + delete(url.query); + delete(url.fragment); + const expected = common.urlToString(url); // make window.location.href writable Object.defineProperty(window.location, 'href', { From 405479642ffeec59fed70aaa37a90c94f38fc20a Mon Sep 17 00:00:00 2001 From: El RIDO Date: Sun, 7 Jan 2024 17:45:01 +0100 Subject: [PATCH 4/7] add YOURLS API samples for extractUrl validation --- js/common.js | 4 +- js/privatebin.js | 4 +- js/test/Helper.js | 18 +++---- js/test/PasteStatus.js | 117 ++++++++++++++++++++++++++++++++++++++++- tpl/bootstrap.php | 2 +- tpl/page.php | 2 +- 6 files changed, 130 insertions(+), 17 deletions(-) diff --git a/js/common.js b/js/common.js index c14a76ca..d3953d36 100644 --- a/js/common.js +++ b/js/common.js @@ -113,8 +113,8 @@ exports.jscBase64String = function() { }; // provides a random URL schema supported by the whatwg-url library -exports.jscSchemas = function() { - return jsc.elements(schemas); +exports.jscSchemas = function(withFtp = true) { + return jsc.elements(withFtp ? schemas : schemas.slice(1)); }; // provides a random supported language string diff --git a/js/privatebin.js b/js/privatebin.js index 4e370e91..9196ca5f 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -2117,7 +2117,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { response = JSON.stringify(response); } if (typeof response === 'string' && response.length > 0) { - const shortUrlMatcher = /https?:\/\/[^\s]+/g; + const shortUrlMatcher = /https?:\/\/[^\s"<]+/g; // JSON API will have URL in quotes, XML in tags const shortUrl = (response.match(shortUrlMatcher) || []).filter(function(urlRegExMatch) { if (typeof URL.canParse === 'function') { return URL.canParse(urlRegExMatch); @@ -2129,7 +2129,7 @@ jQuery.PrivateBin = (function($, RawDeflate) { return false; } }).sort(function(a, b) { - return a.length - b.length; + return a.length - b.length; // shortest first })[0]; if (typeof shortUrl === 'string' && shortUrl.length > 0) { // we disable the button to avoid calling shortener again diff --git a/js/test/Helper.js b/js/test/Helper.js index 434cd3e5..95ae5709 100644 --- a/js/test/Helper.js +++ b/js/test/Helper.js @@ -259,16 +259,16 @@ describe('Helper', function () { this.timeout(30000); jsc.property( 'returns the URL without query & fragment', - jsc.elements(['http', 'https']), - jsc.nearray(common.jscA2zString()), - jsc.array(common.jscA2zString()), - jsc.array(common.jscQueryString()), - 'string', - function (schema, address, path, query, fragment) { + common.jscSchemas(false), + common.jscUrl(), + function (schema, url) { + url.schema = schema; + const fullUrl = common.urlToString(url); + delete(url.query); + delete(url.fragment); $.PrivateBin.Helper.reset(); - var path = path.join('') + (path.length > 0 ? '/' : ''), - expected = schema + '://' + address.join('') + '/' + path, - clean = jsdom('', {url: expected + '?' + query.join('') + '#' + fragment}), + const expected = common.urlToString(url), + clean = jsdom('', {url: fullUrl}), result = $.PrivateBin.Helper.baseUri(); clean(); return expected === result; diff --git a/js/test/PasteStatus.js b/js/test/PasteStatus.js index 8b19c75b..2e8e6dc7 100644 --- a/js/test/PasteStatus.js +++ b/js/test/PasteStatus.js @@ -1,6 +1,23 @@ 'use strict'; var common = require('../common'); +function urlStrings(schema, longUrl, shortUrl) { + longUrl.schema = schema; + shortUrl.schema = schema; + let longUrlString = common.urlToString(longUrl), + shortUrlString = common.urlToString(shortUrl); + // ensure the two random URLs actually are sorted as expected + if (longUrlString.length <= shortUrlString.length) { + if (longUrlString.length === shortUrlString.length) { + longUrl.address.unshift('a'); + longUrlString = common.urlToString(longUrl); + } else { + [longUrlString, shortUrlString] = [shortUrlString, longUrlString]; + } + } + return [longUrlString, shortUrlString]; +} + describe('PasteStatus', function () { describe('createPasteNotification', function () { this.timeout(30000); @@ -28,8 +45,8 @@ describe('PasteStatus', function () { this.timeout(30000); jsc.property( - 'extracts and updates URLs found in given response', - jsc.elements(['http','https']), + 'extracts and updates IDN URLs found in given response', + common.jscSchemas(false), 'nestring', common.jscUrl(), function (schema, domain, url) { @@ -58,6 +75,102 @@ describe('PasteStatus', function () { ); } ); + + // YOURLS API samples from: https://yourls.org/readme.html#API;apireturn + jsc.property( + 'extracts and updates URLs found in YOURLS API JSON response', + common.jscSchemas(false), + common.jscUrl(), + common.jscUrl(false), + function (schema, longUrl, shortUrl) { + const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl), + yourlsResponse = { + url: { + keyword: longUrl.address.join(''), + url: longUrlString, + title: "example title", + date: "2014-10-24 16:01:39", + ip: "127.0.0.1" + }, + status: "success", + message: longUrlString + " added to database", + title: "example title", + shorturl: shortUrlString, + statusCode: 200 + }, + clean = jsdom(); + + $('body').html('
'); + $.PrivateBin.PasteStatus.init(); + $.PrivateBin.PasteStatus.createPasteNotification('', ''); + $.PrivateBin.PasteStatus.extractUrl(JSON.stringify(yourlsResponse, undefined, 4)); + + const result = $('#pasteurl')[0].href; + clean(); + + return result === shortUrlString; + } + ); + jsc.property( + 'extracts and updates URLs found in YOURLS API XML response', + common.jscSchemas(false), + common.jscUrl(), + common.jscUrl(false), + function (schema, longUrl, shortUrl) { + const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl), + yourlsResponse = '\n' + + ' ' + longUrl.address.join('') + '\n' + + ' ' + shortUrlString + '\n' + + ' ' + longUrlString + '\n' + + ' success\n' + + ' 200\n' + + '', + clean = jsdom(); + + $('body').html('
'); + $.PrivateBin.PasteStatus.init(); + $.PrivateBin.PasteStatus.createPasteNotification('', ''); + $.PrivateBin.PasteStatus.extractUrl(yourlsResponse); + + const result = $('#pasteurl')[0].href; + clean(); + + return result === shortUrlString; + } + ); + jsc.property( + 'extracts and updates URLs found in YOURLS proxy HTML response', + common.jscSchemas(false), + common.jscUrl(), + common.jscUrl(false), + function (schema, longUrl, shortUrl) { + const [longUrlString, shortUrlString] = urlStrings(schema, longUrl, shortUrl), + yourlsResponse = '\n' + + '\n' + + '\t\n' + + '\t\t\n' + + '\t\t\n' + + '\t\t\n' + + '\t\t\n' + + '\t\tPrivateBin\n' + + '\t\n' + + '\t\n' + + '\t\t

Your paste is ' + shortUrlString + ' (Hit [Ctrl]+[c] to copy)

\n' + + '\t\n' + + '', + clean = jsdom(); + + $('body').html('
'); + $.PrivateBin.PasteStatus.init(); + $.PrivateBin.PasteStatus.createPasteNotification('', ''); + $.PrivateBin.PasteStatus.extractUrl(yourlsResponse); + + const result = $('#pasteurl')[0].href; + clean(); + + return result === shortUrlString; + } + ); }); describe('showRemainingTime', function () { diff --git a/tpl/bootstrap.php b/tpl/bootstrap.php index d1a54fcb..0cf27f5f 100644 --- a/tpl/bootstrap.php +++ b/tpl/bootstrap.php @@ -73,7 +73,7 @@ endif; ?> - + diff --git a/tpl/page.php b/tpl/page.php index b0b9cc1a..7e62f37e 100644 --- a/tpl/page.php +++ b/tpl/page.php @@ -51,7 +51,7 @@ endif; ?> - + From 4e62e1f6efd27289f3bd5f56aed27cdd32762f51 Mon Sep 17 00:00:00 2001 From: El RIDO Date: Mon, 8 Jan 2024 08:09:29 +0100 Subject: [PATCH 5/7] address jsverify rngState 87ab3f64de258190c7, fixes #1139 --- js/test/PasteStatus.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/js/test/PasteStatus.js b/js/test/PasteStatus.js index 2e8e6dc7..a233bb48 100644 --- a/js/test/PasteStatus.js +++ b/js/test/PasteStatus.js @@ -27,13 +27,13 @@ describe('PasteStatus', function () { common.jscUrl(), common.jscUrl(false), function (url1, url2) { - const expected1 = common.urlToString(url1), - expected2 = common.urlToString(url2), + const expected1 = common.urlToString(url1).replace(/&(gt|lt)$/, '&$1a'), + expected2 = common.urlToString(url2).replace(/&(gt|lt)$/, '&$1a'), clean = jsdom(); $('body').html('
'); $.PrivateBin.PasteStatus.init(); $.PrivateBin.PasteStatus.createPasteNotification(expected1, expected2); - var result1 = $('#pasteurl')[0].href, + const result1 = $('#pasteurl')[0].href, result2 = $('#deletelink a')[0].href; clean(); return result1 === expected1 && result2 === expected2; @@ -50,7 +50,7 @@ describe('PasteStatus', function () { 'nestring', common.jscUrl(), function (schema, domain, url) { - domain = domain.replace(/\P{Letter}|[\u00AA-\u00BA]/gu,'').toLowerCase(); + domain = domain.replace(/\P{Letter}|[\u00AA-\u00BA]/gu, '').toLowerCase(); if (domain.length === 0) { domain = 'a'; } From ba25ab8fa97a34f0236d9adbe0a464884fa2a06a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 11:21:35 +0000 Subject: [PATCH 6/7] Bump actions/cache from 3 to 4 Bumps [actions/cache](https://github.com/actions/cache) from 3 to 4. - [Release notes](https://github.com/actions/cache/releases) - [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md) - [Commits](https://github.com/actions/cache/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/cache dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index dd5f59b6..730de26e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: key: ${{ runner.os }}-${{ env.extensions-cache-key }} - name: Cache extensions - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ steps.extcache.outputs.dir }} key: ${{ steps.extcache.outputs.key }} @@ -76,7 +76,7 @@ jobs: shell: bash - name: Cache dependencies - uses: actions/cache@v3 + uses: actions/cache@v4 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/composer.json') }} From 3ff3db72a16f36f0ca886b467e90905785c43967 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:44:19 +0000 Subject: [PATCH 7/7] Bump phpunit/phpunit from 9.6.15 to 9.6.16 Bumps [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) from 9.6.15 to 9.6.16. - [Changelog](https://github.com/sebastianbergmann/phpunit/blob/9.6.16/ChangeLog-9.6.md) - [Commits](https://github.com/sebastianbergmann/phpunit/compare/9.6.15...9.6.16) --- updated-dependencies: - dependency-name: phpunit/phpunit dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- composer.lock | 66 +++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/composer.lock b/composer.lock index bf8fa3fd..5f8d2963 100644 --- a/composer.lock +++ b/composer.lock @@ -316,16 +316,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v4.18.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", "shasum": "" }, "require": { @@ -366,9 +366,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2023-12-10T21:03:43+00:00" }, { "name": "phar-io/manifest", @@ -483,23 +483,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -549,7 +549,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.30" }, "funding": [ { @@ -557,7 +557,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -802,16 +802,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.15", + "version": "9.6.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1" + "reference": "3767b2c56ce02d01e3491046f33466a1ae60a37f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1", - "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3767b2c56ce02d01e3491046f33466a1ae60a37f", + "reference": "3767b2c56ce02d01e3491046f33466a1ae60a37f", "shasum": "" }, "require": { @@ -885,7 +885,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.16" }, "funding": [ { @@ -901,7 +901,7 @@ "type": "tidelift" } ], - "time": "2023-12-01T16:55:19+00:00" + "time": "2024-01-19T07:03:14+00:00" }, { "name": "sebastian/cli-parser", @@ -1146,20 +1146,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -1191,7 +1191,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -1199,7 +1199,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -1473,20 +1473,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -1518,7 +1518,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -1526,7 +1526,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator",