fix url filter, IDN URL unit test

pull/1227/head
El RIDO 2024-01-04 23:08:17 +01:00
parent 8427c1136c
commit a80bd4e4ea
6 changed files with 87 additions and 28 deletions

View File

@ -37,7 +37,7 @@ var a2zString = ['a','b','c','d','e','f','g','h','i','j','k','l','m',
})
),
schemas = ['ftp','http','https'],
supportedLanguages = ['de', 'es', 'fr', 'it', 'no', 'pl', 'pt', 'oc', 'ru', 'sl', 'zh'],
supportedLanguages = ['ar', 'bg', 'ca', 'co', 'cs', 'de', 'el', 'es', 'et', 'fi', 'fr', 'he', 'hu', 'id', 'it', 'ja', 'jbo', 'lt', 'no', 'nl', 'pl', 'pt', 'oc', 'ru', 'sk', 'sl', 'th', 'tr', 'uk', 'zh'],
mimeTypes = ['image/png', 'application/octet-stream'],
formats = ['plaintext', 'markdown', 'syntaxhighlighting'],
mimeFile = fs.createReadStream('/etc/mime.types'),

4
js/package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "privatebin",
"version": "1.5.2",
"version": "1.6.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "privatebin",
"version": "1.5.2",
"version": "1.6.2",
"license": "zlib-acknowledgement",
"devDependencies": {
"@peculiar/webcrypto": "^1.1.1",

View File

@ -2035,29 +2035,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
xhrFields: {
withCredentials: false
},
success: function(response) {
let responseString = response;
if (typeof responseString === 'object') {
responseString = JSON.stringify(responseString);
}
if (typeof responseString === 'string' && responseString.length > 0) {
const shortUrlMatcher = /https?:\/\/[^\s]+/g;
const shortUrl = (responseString.match(shortUrlMatcher) || []).filter(URL.canParse).sort(function(a, b) {
return a.length - b.length;
})[0];
if (typeof shortUrl === 'string' && shortUrl.length > 0) {
// we disable the button to avoid calling shortener again
$shortenButton.addClass('buttondisabled');
// update link
$pasteUrl.text(shortUrl);
$pasteUrl.prop('href', shortUrl);
// we pre-select the link so that the user only has to [Ctrl]+[c] the link
Helper.selectText($pasteUrl[0]);
return;
}
}
Alert.showError('Cannot parse response from URL shortener.');
}
success: PasteStatus.extractUrl
})
.fail(function(data, textStatus, errorThrown) {
console.error(textStatus, errorThrown);
@ -2123,6 +2101,42 @@ jQuery.PrivateBin = (function($, RawDeflate) {
Helper.selectText($pasteUrl[0]);
};
/**
* extracts URLs from given string
*
* if at least one is found, it disables the shortener button and
* replaces the paste URL
*
* @name PasteStatus.extractUrl
* @function
* @param {string} response
*/
me.extractUrl = function(response)
{
if (typeof response === 'object') {
response = JSON.stringify(response);
}
if (typeof response === 'string' && response.length > 0) {
const shortUrlMatcher = /https?:\/\/[^\s]+/g;
const shortUrl = (response.match(shortUrlMatcher) || []).filter(function(a) {
return URL.canParse(a);
}).sort(function(a, b) {
return a.length - b.length;
})[0];
if (typeof shortUrl === 'string' && shortUrl.length > 0) {
// we disable the button to avoid calling shortener again
$shortenButton.addClass('buttondisabled');
// update link
$pasteUrl.text(shortUrl);
$pasteUrl.prop('href', shortUrl);
// we pre-select the link so that the user only has to [Ctrl]+[c] the link
Helper.selectText($pasteUrl[0]);
return;
}
}
Alert.showError('Cannot parse response from URL shortener.');
};
/**
* shows the remaining time
*

View File

@ -34,6 +34,51 @@ describe('PasteStatus', function () {
);
});
describe('extractUrl', function () {
this.timeout(30000);
jsc.property(
'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) {
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)) : ''),
clean = jsdom();
// not available in node before v19.9.0, v18.17.0
if (typeof URL.canParse !== 'function') {
URL.canParse = function(a) {
return true;
}
}
$('body').html('<div><div id="pastelink"></div></div>');
$.PrivateBin.PasteStatus.init();
$.PrivateBin.PasteStatus.createPasteNotification('', '');
$.PrivateBin.PasteStatus.extractUrl(schema + '://' + domain + expected);
const result = $('#pasteurl')[0].href;
clean();
return result.endsWith(expected) && (
result.startsWith(schema + '://xn--') ||
result.startsWith(schema + '://' + domain)
);
}
);
});
describe('showRemainingTime', function () {
this.timeout(30000);

View File

@ -73,7 +73,7 @@ endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-FF+BJPX+fC0o672f5HNwc3Q+v6dcAeO+jT4/NgnGpgG2bjesssaqkYVSdFX3kxLe4mm1A3DZB4w75OioqBIncw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-ga7H5TIOKUp1pst8C7AxGjnnuTe96WETRcjkLVY3jRjYYIlyGo+dT/sf4/6gjhMUc6tT8WHLtI5xBijTSCe6+w==" crossorigin="anonymous"></script>
<!-- icon -->
<link rel="apple-touch-icon" href="<?php echo I18n::encode($BASEPATH); ?>img/apple-touch-icon.png" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png" sizes="32x32" />

View File

@ -51,7 +51,7 @@ endif;
?>
<script type="text/javascript" data-cfasync="false" src="js/purify-3.0.6.js" integrity="sha512-N3y6/HOk3pbsw3lFh4O8CKKEVwu1B2CF8kinhjURf8Yqa5OfSUt+/arozxFW+TUPOPw3TsDCRT/0u7BGRTEVUw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/legacy.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-LYos+qXHIRqFf5ZPNphvtTB0cgzHUizu2wwcOwcwz/VIpRv9lpcBgPYz4uq6jx0INwCAj6Fbnl5HoKiLufS2jg==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-FF+BJPX+fC0o672f5HNwc3Q+v6dcAeO+jT4/NgnGpgG2bjesssaqkYVSdFX3kxLe4mm1A3DZB4w75OioqBIncw==" crossorigin="anonymous"></script>
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-ga7H5TIOKUp1pst8C7AxGjnnuTe96WETRcjkLVY3jRjYYIlyGo+dT/sf4/6gjhMUc6tT8WHLtI5xBijTSCe6+w==" crossorigin="anonymous"></script>
<!-- icon -->
<link rel="apple-touch-icon" href="img/apple-touch-icon.png?<?php echo rawurlencode($VERSION); ?>" sizes="180x180" />
<link rel="icon" type="image/png" href="img/favicon-32x32.png?<?php echo rawurlencode($VERSION); ?>" sizes="32x32" />