Просмотр исходного кода

Merge branch 'master' into admin

El RIDO 3 лет назад
Родитель
Сommit
c00b95011b

+ 5 - 1
CHANGELOG.md

@@ -1,6 +1,10 @@
 # PrivateBin version history
 
-  * **1.5 (not yet released)**
+  * **1.5.1 (not yet released)**
+    * FIXED: Revert Filesystem purge to limited and randomized lookup (#1030)
+    * FIXED: Catch JSON decode errors when invalid data gets sent to the API (#1030)
+    * FIXED: Support sorting v1 format in mixed version comments in Filesystem backend (#1030)
+  * **1.5 (2022-12-11)**
     * ADDED: script for data storage backend migrations (#1012)
     * ADDED: script for administrative tasks: deleting pastes (#274), removing empty directories (#277), purging expired pastes (#276) & statistics (#319)
     * ADDED: Translations for Turkish, Slovak, Greek and Thai

+ 1 - 2
CREDITS.md

@@ -29,9 +29,8 @@
 * rodehoed - option to exempt ips from the rate-limiter
 * Mark van Holsteijn - Google Cloud Storage backend
 * Austin Huang - Oracle database support
-* Felix J. Ogris - S3 Storage backend
+* Felix J. Ogris - S3 Storage backend, script for data backend migrations, dropped singleton behaviour of data backends
 * Mounir Idrassi & J. Mozdzen - secure YOURLS integration
-* Felix J. Ogris - script for data backend migrations, dropped singleton behaviour of data backends
 
 ## Translations
 * Hexalyse - French

+ 1 - 1
INSTALL.md

@@ -205,7 +205,7 @@ CREATE INDEX parent ON prefix_comment(pasteid);
 CREATE TABLE prefix_config (
     id CHAR(16) NOT NULL, value TEXT, PRIMARY KEY (id)
 );
-INSERT INTO prefix_config VALUES('VERSION', '1.4.0');
+INSERT INTO prefix_config VALUES('VERSION', '1.5.0');
 ```
 
 In **PostgreSQL**, the `data`, `attachment`, `nickname` and `vizhash` columns

+ 3 - 3
Makefile

@@ -1,7 +1,7 @@
 .PHONY: all coverage coverage-js coverage-php doc doc-js doc-php increment sign test test-js test-php help
 
-CURRENT_VERSION = 1.4.0
-VERSION ?= 1.4.1
+CURRENT_VERSION = 1.5.0
+VERSION ?= 1.5.1
 VERSION_FILES = index.php cfg/ *.md css/ i18n/ img/ js/package.json js/privatebin.js lib/ Makefile tpl/ tst/
 REGEX_CURRENT_VERSION := $(shell echo $(CURRENT_VERSION) | sed "s/\./\\\./g")
 REGEX_VERSION := $(shell echo $(VERSION) | sed "s/\./\\\./g")
@@ -38,7 +38,7 @@ increment: ## Increment and commit new version number, set target version using
 	git commit -m "incrementing version"
 
 sign: ## Sign a release.
-	git tag $(VERSION)
+	git tag --sign --message "Release v$(VERSION)" $(VERSION)
 	git push origin $(VERSION)
 	signrelease.sh
 

+ 1 - 1
README.md

@@ -1,6 +1,6 @@
 # [![PrivateBin](https://cdn.rawgit.com/PrivateBin/assets/master/images/preview/logoSmall.png)](https://privatebin.info/)
 
-*Current version: 1.4.0*
+*Current version: 1.5.0*
 
 **PrivateBin** is a minimalist, open source online
 [pastebin](https://en.wikipedia.org/wiki/Pastebin)

+ 2 - 2
SECURITY.md

@@ -4,8 +4,8 @@
 
 | Version | Supported          |
 | ------- | ------------------ |
-| 1.4.0   | :heavy_check_mark: |
-| < 1.4.0 | :x:                |
+| 1.5.0   | :heavy_check_mark: |
+| < 1.5.0 | :x:                |
 
 ## Reporting a Vulnerability
 

+ 1 - 1
css/bootstrap/privatebin.css

@@ -6,7 +6,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 body {

+ 1 - 1
css/noscript.css

@@ -6,7 +6,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 /* When there is no script at all other */

+ 1 - 1
css/privatebin.css

@@ -6,7 +6,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 /*  CSS Reset from YUI 3.4.1 (build 4118) - Copyright 2011 Yahoo! Inc. All rights reserved.

+ 1 - 1
i18n/cs.json

@@ -47,7 +47,7 @@
         "%d minutes (3rd plural)"
     ],
     "%d hours": [
-        "%d hodin",
+        "%d hodina",
         "%d hodiny",
         "%d hodin",
         "%d hours (3rd plural)"

+ 41 - 41
i18n/nl.json

@@ -1,10 +1,10 @@
 {
     "PrivateBin": "PrivateBin",
-    "%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s is een minimalistische, open source online pastebin waarbij de server geen kennis heeft van de geplakte gegevens. Gegevens worden gecodeerd/gedecodeerd %s in de browser %s met behulp van 256 bits AES.",
+    "%s is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted %sin the browser%s using 256 bits AES.": "%s is een minimalistische, open source online pastebin waarbij de server geen kennis heeft van de paste data zelf. Gegevens worden gecodeerd/gedecodeerd %s in de browser %s met behulp van 256-bits AES.",
     "More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Meer informatie is te vinden op de <a href=\"https://privatebin.info/\">projectpagina</a>.",
     "Because ignorance is bliss": "Onwetendheid is een zegen",
     "en": "nl",
-    "Paste does not exist, has expired or has been deleted.": "Geplakte tekst bestaat niet, is verlopen of verwijderd.",
+    "Paste does not exist, has expired or has been deleted.": "Paste bestaat niet, is verlopen of verwijderd.",
     "%s requires php %s or above to work. Sorry.": "%s vereist PHP %s of hoger om te kunnen werken. Sorry",
     "%s requires configuration section [%s] to be present in configuration file.": "%s vereist dat de configuratiesectie [%s] aanwezig is in het configuratiebestand",
     "Please wait %d seconds between each post.": [
@@ -13,20 +13,20 @@
         "Alstublieft %d seconden wachten tussen elk bericht.",
         "Alstublieft %d seconden wachten tussen elk bericht."
     ],
-    "Paste is limited to %s of encrypted data.": "Geplakte tekst is beperkt tot %s aan versleutelde gegevens",
-    "Invalid data.": "Ongeldige gegevens",
-    "You are unlucky. Try again.": "Helaas. Probeer het nog eens",
+    "Paste is limited to %s of encrypted data.": "Paste is beperkt tot %s aan versleutelde gegevens.",
+    "Invalid data.": "Ongeldige gegevens.",
+    "You are unlucky. Try again.": "Helaas. Probeer het nog eens.",
     "Error saving comment. Sorry.": "Fout bij het opslaan van het commentaar. Sorry",
-    "Error saving paste. Sorry.": "Fout bij het opslaan van de geplakte tekst. Sorry.",
+    "Error saving paste. Sorry.": "Fout bij het opslaan van de paste. Sorry.",
     "Invalid paste ID.": "Ongeldige ID.",
-    "Paste is not of burn-after-reading type.": "Geplakte tekst is geen 'vernietig na lezen' type",
-    "Wrong deletion token. Paste was not deleted.": "Foutieve verwijdercode. Geplakte tekst is niet verwijderd.",
-    "Paste was properly deleted.": "Geplakte tekst is correct verwijderd.",
+    "Paste is not of burn-after-reading type.": "Paste is geen 'vernietig na lezen' type.",
+    "Wrong deletion token. Paste was not deleted.": "Foutieve verwijdercode. Paste is niet verwijderd.",
+    "Paste was properly deleted.": "Paste is correct verwijderd.",
     "JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript vereist om %s te laten werken. Sorry voor het ongemak.",
-    "%s requires a modern browser to work.": "%s vereist een moderne browser om te kunnen werken ",
+    "%s requires a modern browser to work.": "%s vereist een moderne browser om te kunnen werken.",
     "New": "Nieuw",
     "Send": "Verzenden",
-    "Clone": "Clonen",
+    "Clone": "Klonen",
     "Raw text": "Onbewerkte tekst",
     "Expires": "Verloopt",
     "Burn after reading": "Vernietig na lezen",
@@ -77,7 +77,7 @@
         "%d years (3rd plural)"
     ],
     "Never": "Nooit",
-    "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Opmerking: Dit is een testservice: Gegevens kunnen op elk gegeven moment verwijderd worden.",
+    "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Opmerking: Dit is een testservice: Gegevens kunnen op elk gegeven moment verwijderd worden. Katten zullen doodgaan als je misbruikt maakt van deze service.",
     "This document will expire in %d seconds.": [
         "Dit document verloopt over %d seconde.",
         "Dit document verloopt over %d seconden.",
@@ -108,14 +108,14 @@
         "Dit document verloopt over %d maanden.",
         "Dit document verloopt over %d maanden."
     ],
-    "Please enter the password for this paste:": "Voer het wachtwoord in voor deze geplakte tekst:",
+    "Please enter the password for this paste:": "Voer het wachtwoord in voor deze paste:",
     "Could not decrypt data (Wrong key?)": "Kon de gegevens niet decoderen (verkeerde sleutel?)",
-    "Could not delete the paste, it was not stored in burn after reading mode.": "Verwijderen van de geplakte tekst niet mogelijk, deze werd niet opgeslagen in 'vernietig na lezen' modus.",
-    "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Sluit dit venster niet, dit bericht kan niet opnieuw worden weergegeven.",
+    "Could not delete the paste, it was not stored in burn after reading mode.": "Verwijderen van de paste niet mogelijk, deze werd niet opgeslagen in 'vernietig na lezen' modus.",
+    "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "ALLEEN VOOR JOUW OGEN BESTEMD. Sluit dit venster niet, dit bericht kan niet opnieuw worden weergegeven.",
     "Could not decrypt comment; Wrong key?": "Kon het commentaar niet decoderen; Verkeerde sleutel?",
     "Reply": "Beantwoorden",
     "Anonymous": "Anoniem",
-    "Avatar generated from IP address": "Anonieme avatar (van het IP adres)",
+    "Avatar generated from IP address": "Anonieme avatar (van het IP-adres)",
     "Add comment": "Commentaar toevoegen",
     "Optional nickname…": "Optionele bijnaam…",
     "Post comment": "Plaats een commentaar",
@@ -125,11 +125,11 @@
     "unknown status": "Onbekende status",
     "server error or not responding": "Serverfout of server reageert niet",
     "Could not post comment: %s": "Kon het commentaar niet plaatsen: %s",
-    "Sending paste…": "Geplakte tekst verzenden…",
-    "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Uw geplakte tekst is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Druk [Ctrl]+[c] om te kopiëren)</span>",
+    "Sending paste…": "Paste verzenden…",
+    "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Je paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Druk [Ctrl]+[c] om te kopiëren)</span>",
     "Delete data": "Gegevens wissen",
-    "Could not create paste: %s": "Kon de geplakte tekst niet aanmaken: %s",
-    "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Kon de geplakte tekst niet decoderen: Decoderingssleutel ontbreekt in URL (Hebt u een redirector of een URL-verkorter gebruikt die een deel van de URL verwijdert?)",
+    "Could not create paste: %s": "Kon de paste niet aanmaken: %s",
+    "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Kon de paste niet decoderen: Decoderingssleutel ontbreekt in URL (Heb je een redirector of een URL-verkorter gebruikt die een deel van de URL verwijdert?)",
     "B": "B",
     "KiB": "KiB",
     "MiB": "MiB",
@@ -145,49 +145,49 @@
     "Markdown": "Markdown",
     "Download attachment": "Bijlage downloaden",
     "Cloned: '%s'": "Gekloond: '%s'",
-    "The cloned file '%s' was attached to this paste.": "Het gekloonde bestand '%s' is bijgevoegd aan de geplakte tekst.",
+    "The cloned file '%s' was attached to this paste.": "Het gekloonde bestand '%s' is bijgevoegd aan de paste.",
     "Attach a file": "Een bestand toevoegen",
-    "alternatively drag & drop a file or paste an image from the clipboard": "U kunt ook een bestand slepen en neerzetten of een afbeelding plakken van het klembord",
-    "File too large, to display a preview. Please download the attachment.": "Het bestand is te groot om voorbeeld weer te geven. Aub de bijlage downloaden",
+    "alternatively drag & drop a file or paste an image from the clipboard": "Je kunt ook een bestand slepen en neerzetten of een afbeelding plakken van het klembord",
+    "File too large, to display a preview. Please download the attachment.": "Het bestand is te groot om voorbeeld weer te geven. Aub de bijlage downloaden.",
     "Remove attachment": "Bijlage verwijderen",
-    "Your browser does not support uploading encrypted files. Please use a newer browser.": "Uw browser biedt geen ondersteuning voor het uploaden van gecodeerde bestanden. Gebruik alstublieft een nieuwere browser",
-    "Invalid attachment.": "Ongeldige bijlage",
+    "Your browser does not support uploading encrypted files. Please use a newer browser.": "Je browser biedt geen ondersteuning voor het uploaden van gecodeerde bestanden. Gebruik alstublieft een nieuwere browser.",
+    "Invalid attachment.": "Ongeldige bijlage.",
     "Options": "Opties",
     "Shorten URL": "URL verkorten",
     "Editor": "Editor",
     "Preview": "Preview",
-    "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s vereist dat het PATH eindigt in een '%s'. Aub het PATH updaten in uw index.php.",
+    "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s vereist dat PATH eindigt in een '%s'. a.u.b. PATH updaten in je index.php.",
     "Decrypt": "Decoderen",
     "Enter password": "Voer het wachtwoord in",
     "Loading…": "Laden…",
-    "Decrypting paste…": "Geplakte tekst decoderen…",
-    "Preparing new paste…": "Nieuwe geplakte tekst voorbereiden…",
-    "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In het geval dat dit bericht nooit verdwijnt, kijkt u dan eens naar <a href=\"%s\"> veelgestelde vragen voor informatie over het oplossen van problemen </a>.",
-    "+++ no paste text +++": "+++ geen geplakte tekst +++",
-    "Could not get paste data: %s": "Kon geen klembordgegevens verkrijgen: %s",
+    "Decrypting paste…": "Paste decoderen…",
+    "Preparing new paste…": "Nieuwe paste voorbereiden…",
+    "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In het geval dat dit bericht nooit verdwijnt, kijkt dan eens naar <a href=\"%s\"> veelgestelde vragen voor informatie over het oplossen van problemen </a>.",
+    "+++ no paste text +++": "+++ geen paste tekst +++",
+    "Could not get paste data: %s": "Kon geen paste data verkrijgen: %s",
     "QR code": "QR-code",
     "This website is using an insecure HTTP connection! Please use it only for testing.": "Deze website gebruikt een onveilige HTTP-verbinding! Gelieve deze enkel te gebruiken om te testen.",
     "For more information <a href=\"%s\">see this FAQ entry</a>.": "Voor meer informatie <a href=\"%s\">zie dit FAQ-artikel</a>.",
-    "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Uw browser kan een HTTPS-verbinding nodig hebben om de WebCrypto API te ondersteunen. Probeer <a href=\"%s\">het met HTTPS</a>.",
-    "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Uw browser ondersteunt WebAssembly niet, wat wordt gebruikt voor zlib compressie. U kunt niet-gecomprimeerde documenten maken, maar geen gecomprimeerde documenten lezen.",
+    "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Je browser kan een HTTPS-verbinding nodig hebben om de WebCrypto API te ondersteunen. Probeer <a href=\"%s\">het met HTTPS</a>.",
+    "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Je browser ondersteunt WebAssembly niet, wat wordt gebruikt voor zlib compressie. Je kunt niet-gecomprimeerde documenten maken, maar geen gecomprimeerde documenten lezen.",
     "waiting on user to provide a password": "wachtend op gebruiker om een wachtwoord te geven",
-    "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Kon de gegevens niet decoderen. Heeft u een verkeerd wachtwoord ingevoerd? Probeer het opnieuw met de knop bovenaan.",
+    "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Kon de gegevens niet decoderen. Heb je een verkeerd wachtwoord ingevoerd? Probeer het opnieuw met de knop bovenaan.",
     "Retry": "Opnieuw proberen",
     "Showing raw text…": "Platte tekst tonen…",
     "Notice:": "Let op:",
     "This link will expire after %s.": "Deze link vervalt na %s.",
-    "This link can only be accessed once, do not use back or refresh button in your browser.": "Deze link kan slechts eenmaal worden geopend, gebruik niet de terug- of verversknop in uw browser.",
+    "This link can only be accessed once, do not use back or refresh button in your browser.": "Deze link kan slechts eenmaal worden geopend, gebruik niet de terug- of verversknop in je browser.",
     "Link:": "Link:",
-    "Recipient may become aware of your timezone, convert time to UTC?": "Ontvanger kan zich bewust worden van uw tijdzone, tijd omzetten naar UTC?",
+    "Recipient may become aware of your timezone, convert time to UTC?": "Ontvanger kan zich bewust worden van je tijdzone, tijd omzetten naar UTC?",
     "Use Current Timezone": "Gebruik huidige tijdzone",
     "Convert To UTC": "Omzetten naar UTC",
     "Close": "Sluiten",
     "Encrypted note on %s": "Versleutelde notitie op %s",
     "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Bezoek deze link om de notitie te bekijken. Als je de URL aan iemand geeft, kan die de notitie ook bekijken.",
-    "URL shortener may expose your decrypt key in URL.": "URL-verkorter kan uw ontcijferingssleutel in URL blootleggen.",
+    "URL shortener may expose your decrypt key in URL.": "URL-verkorter kan je ontcijferingssleutel in URL blootleggen.",
     "Save paste": "Notitie opslaan",
-    "Your IP is not authorized to create pastes.": "Uw IP-adres is niet gemachtigd om geplakte tekst te maken.",
-    "Trying to shorten a URL that isn't pointing at our instance.": "Trying to shorten a URL that isn't pointing at our instance.",
-    "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".",
-    "Error parsing YOURLS response.": "Error parsing YOURLS response."
+    "Your IP is not authorized to create pastes.": "Je IP-adres is niet gemachtigd om pastes te maken.",
+    "Trying to shorten a URL that isn't pointing at our instance.": "Proberen om een URL te verkorten dat niet naar ons systeem wijst.",
+    "Error calling YOURLS. Probably a configuration issue, like wrong or missing \"apiurl\" or \"signature\".": "Foutmelding ophalen YOURLS. Waarschijnlijk een configuratiefout, zoals een verkeerde of missende \"apiurl\" of \"signature\".",
+    "Error parsing YOURLS response.": "Foutmelding bij parsen van YOURLS respons."
 }

+ 1 - 1
index.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 // change this, if your php files and data is outside of your webservers document root

+ 1 - 1
js/package.json

@@ -1,6 +1,6 @@
 {
   "name": "privatebin",
-  "version": "1.4.0",
+  "version": "1.5.0",
   "description": "PrivateBin is a minimalist, open source online pastebin where the server has zero knowledge of pasted data. Data is encrypted/decrypted in the browser using 256 bit AES in Galois Counter mode (GCM).",
   "main": "privatebin.js",
   "directories": {

+ 1 - 1
js/privatebin.js

@@ -6,7 +6,7 @@
  * @see       {@link https://github.com/PrivateBin/PrivateBin}
  * @copyright 2012 Sébastien SAUVAGE ({@link http://sebsauvage.net})
  * @license   {@link https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License}
- * @version   1.4.0
+ * @version   1.5.0
  * @name      PrivateBin
  * @namespace
  */

+ 1 - 1
lib/Configuration.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 2 - 2
lib/Controller.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;
@@ -28,7 +28,7 @@ class Controller
      *
      * @const string
      */
-    const VERSION = '1.4.0';
+    const VERSION = '1.5.0';
 
     /**
      * minimal required PHP version

+ 1 - 1
lib/Data/AbstractData.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Data;

+ 1 - 1
lib/Data/Database.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Data;

+ 18 - 24
lib/Data/Filesystem.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Data;
@@ -228,7 +228,13 @@ class Filesystem extends AbstractData
                     $comment['parentid'] = $items[2];
 
                     // Store in array
-                    $key            = $this->getOpenSlot($comments, (int) $comment['meta']['created']);
+                    $key            = $this->getOpenSlot(
+                        $comments, (
+                            (int) array_key_exists('created', $comment['meta']) ?
+                            $comment['meta']['created'] : // v2 comments
+                            $comment['meta']['postdate'] // v1 comments
+                        )
+                    );
                     $comments[$key] = $comment;
                 }
             }
@@ -358,12 +364,12 @@ class Filesystem extends AbstractData
     {
         $pastes = array();
         $count  = 0;
+        $opened = 0;
+        $limit  = $batchsize * 10; // try at most 10 times $batchsize pastes before giving up
         $time   = time();
-        foreach ($this->_getPasteIterator() as $file) {
-            if ($file->isDir()) {
-                continue;
-            }
-            $pasteid = $file->getBasename('.php');
+        $files  = $this->getAllPastes();
+        shuffle($files);
+        foreach ($files as $pasteid) {
             if ($this->exists($pasteid)) {
                 $data = $this->read($pasteid);
                 if (
@@ -371,11 +377,13 @@ class Filesystem extends AbstractData
                     $data['meta']['expire_date'] < $time
                 ) {
                     $pastes[] = $pasteid;
-                    ++$count;
-                    if ($count >= $batchsize) {
+                    if (++$count >= $batchsize) {
                         break;
                     }
                 }
+                if (++$opened >= $limit) {
+                    break;
+                }
             }
         }
         return $pastes;
@@ -387,7 +395,7 @@ class Filesystem extends AbstractData
     public function getAllPastes()
     {
         $pastes = array();
-        foreach ($this->_getPasteIterator() as $file) {
+        foreach (new \GlobIterator($this->_path . self::PASTE_FILE_PATTERN) as $file) {
             if ($file->isFile()) {
                 $pastes[] = $file->getBasename('.php');
             }
@@ -431,20 +439,6 @@ class Filesystem extends AbstractData
             '.discussion' . DIRECTORY_SEPARATOR;
     }
 
-    /**
-     * Get an iterator matching paste files.
-     *
-     * Note that creating the iterator issues the glob() call, so we can't pre-
-     * generate this object before files that should get matched exist.
-     *
-     * @access private
-     * @return \GlobIterator
-     */
-    private function _getPasteIterator()
-    {
-        return new \GlobIterator($this->_path . self::PASTE_FILE_PATTERN);
-    }
-
     /**
      * store the data
      *

+ 1 - 1
lib/Data/S3Storage.php

@@ -4,7 +4,7 @@
  *
  * an S3 compatible data backend for PrivateBin with CEPH/RadosGW in mind
  * see https://docs.ceph.com/en/latest/radosgw/s3/php/
- * based on lib/Data/GoogleCloudStorage.php from PrivateBin version 1.4.0
+ * based on lib/Data/GoogleCloudStorage.php from PrivateBin version 1.5.0
  *
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2022 Felix J. Ogris (https://ogris.de/)

+ 1 - 1
lib/Filter.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
lib/FormatV2.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
lib/I18n.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
lib/Json.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
lib/Model.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
lib/Model/AbstractModel.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Model;

+ 1 - 1
lib/Model/Comment.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Model;

+ 1 - 1
lib/Model/Paste.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Model;

+ 1 - 1
lib/Persistence/AbstractPersistence.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Persistence;

+ 1 - 1
lib/Persistence/PurgeLimiter.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Persistence;

+ 1 - 1
lib/Persistence/ServerSalt.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Persistence;

+ 1 - 1
lib/Persistence/TrafficLimiter.php

@@ -8,7 +8,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin\Persistence;

+ 10 - 4
lib/Request.php

@@ -7,11 +7,13 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;
 
+use Exception;
+
 /**
  * Request
  *
@@ -110,9 +112,13 @@ class Request
             case 'POST':
                 // it might be a creation or a deletion, the latter is detected below
                 $this->_operation = 'create';
-                $this->_params    = Json::decode(
-                    file_get_contents(self::$_inputStream)
-                );
+                try {
+                    $this->_params = Json::decode(
+                        file_get_contents(self::$_inputStream)
+                    );
+                } catch (Exception $e) {
+                    // ignore error, $this->_params will remain empty
+                }
                 break;
             default:
                 $this->_params = $_GET;

+ 1 - 1
lib/View.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
lib/Vizhash16x16.php

@@ -8,7 +8,7 @@
  * @link      https://sebsauvage.net/wiki/doku.php?id=php:vizhash_gd
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   0.0.5 beta PrivateBin 1.4.0
+ * @version   0.0.5 beta PrivateBin 1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
lib/YourlsProxy.php

@@ -7,7 +7,7 @@
  * @link      https://github.com/PrivateBin/PrivateBin
  * @copyright 2012 Sébastien SAUVAGE (sebsauvage.net)
  * @license   https://www.opensource.org/licenses/zlib-license.php The zlib/libpng License
- * @version   1.4.0
+ * @version   1.5.0
  */
 
 namespace PrivateBin;

+ 1 - 1
tpl/bootstrap.php

@@ -73,7 +73,7 @@ endif;
 ?>
 		<script type="text/javascript" data-cfasync="false" src="js/purify-2.4.6.js" integrity="sha512-+jcx+EqNbaFT4OHS86zGwU1SNAAZ7hG2pJlwMpXoe9AvTp37BrXMQ29g2GhdyQHTvYWaNlTQIkWXYM0Lvt8GiQ==" 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-0he/s7UnjLf2pxLH+EIGImaUBhVzpngrL5PId/QB2FcstucrPUPOhQpqJcGvtmVPyuXckiktEwwrz4Sn4Mi3Tw==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-4jbBDlhdAGCdPsFpAzU4qb2RoFx8FKactLHAcEkiIvott1yeQkJntlh+s/BHd5vsxdBoSgA1CeZ7sKIXL/c5vA==" 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" />

+ 1 - 1
tpl/page.php

@@ -51,7 +51,7 @@ endif;
 ?>
 		<script type="text/javascript" data-cfasync="false" src="js/purify-2.4.6.js" integrity="sha512-+jcx+EqNbaFT4OHS86zGwU1SNAAZ7hG2pJlwMpXoe9AvTp37BrXMQ29g2GhdyQHTvYWaNlTQIkWXYM0Lvt8GiQ==" 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-0he/s7UnjLf2pxLH+EIGImaUBhVzpngrL5PId/QB2FcstucrPUPOhQpqJcGvtmVPyuXckiktEwwrz4Sn4Mi3Tw==" crossorigin="anonymous"></script>
+		<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-4jbBDlhdAGCdPsFpAzU4qb2RoFx8FKactLHAcEkiIvott1yeQkJntlh+s/BHd5vsxdBoSgA1CeZ7sKIXL/c5vA==" 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" />

+ 1 - 1
tst/Bootstrap.php

@@ -149,7 +149,7 @@ class BucketStub extends Bucket
         throw new BadMethodCallException('not supported by this stub');
     }
 
-    public function exists()
+    public function exists(array $options = array())
     {
         return true;
     }

+ 5 - 2
tst/ControllerTest.php

@@ -436,8 +436,6 @@ class ControllerTest extends PHPUnit_Framework_TestCase
      * silently removed, check that this case is handled
      *
      * @runInSeparateProcess
-     * @expectedException Exception
-     * @expectedExceptionCode 90
      */
     public function testCreateBrokenUpload()
     {
@@ -449,7 +447,12 @@ class ControllerTest extends PHPUnit_Framework_TestCase
         $_SERVER['REQUEST_METHOD']        = 'POST';
         $_SERVER['REMOTE_ADDR']           = '::1';
         $this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste does not exists before posting data');
+        ob_start();
         new Controller;
+        $content = ob_get_contents();
+        ob_end_clean();
+        $response = json_decode($content, true);
+        $this->assertEquals(1, $response['status'], 'outputs error status');
         $this->assertFalse($this->_data->exists(Helper::getPasteId()), 'paste exists after posting data');
     }
 

+ 1 - 1
tst/I18nTest.php

@@ -135,7 +135,7 @@ class I18nTest extends PHPUnit_Framework_TestCase
         $_SERVER['HTTP_ACCEPT_LANGUAGE'] = 'cs;q=0.8,en-GB;q=0.6,en-US;q=0.4,en;q=0.2';
         I18n::loadTranslations();
         $this->assertEquals('cs', I18n::_('en'), 'browser language cs');
-        $this->assertEquals('1 hodin', I18n::_('%d hours', 1), '1 hour in Czech');
+        $this->assertEquals('1 hodina', I18n::_('%d hours', 1), '1 hour in Czech');
         $this->assertEquals('2 hodiny', I18n::_('%d hours', 2), '2 hours in Czech');
         $this->assertEquals('5 minut',  I18n::_('%d minutes', 5), '5 minutes in Czech');
         $this->assertEquals('14 minut',  I18n::_('%d minutes', 14), '14 minutes in Czech');

+ 17 - 4
tst/RequestTest.php

@@ -97,7 +97,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
         Request::setInputStream($file);
         $request = new Request;
         unlink($file);
-        $this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
+        $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
         $this->assertEquals('create', $request->getOperation());
         $this->assertEquals('foo', $request->getParam('ct'));
     }
@@ -111,7 +111,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
         file_put_contents($file, '{"ct":"foo"}');
         Request::setInputStream($file);
         $request = new Request;
-        $this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
+        $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
         $this->assertEquals('create', $request->getOperation());
         $this->assertEquals('foo', $request->getParam('ct'));
     }
@@ -125,7 +125,7 @@ class RequestTest extends PHPUnit_Framework_TestCase
         $_SERVER['QUERY_STRING']   = $id;
         $_GET[$id]                 = '';
         $request                   = new Request;
-        $this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
+        $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
         $this->assertEquals($id, $request->getParam('pasteid'));
         $this->assertEquals('read', $request->getOperation());
     }
@@ -142,12 +142,25 @@ class RequestTest extends PHPUnit_Framework_TestCase
         file_put_contents($file, '{"deletetoken":"bar"}');
         Request::setInputStream($file);
         $request = new Request;
-        $this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
+        $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
         $this->assertEquals('delete', $request->getOperation());
         $this->assertEquals($id, $request->getParam('pasteid'));
         $this->assertEquals('bar', $request->getParam('deletetoken'));
     }
 
+    public function testPostGarbage()
+    {
+        $this->reset();
+        $_SERVER['REQUEST_METHOD']        = 'POST';
+        $file                             = tempnam(sys_get_temp_dir(), 'FOO');
+        file_put_contents($file, random_bytes(256));
+        Request::setInputStream($file);
+        $request = new Request;
+        unlink($file);
+        $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
+        $this->assertEquals('create', $request->getOperation());
+    }
+
     public function testReadWithNegotiation()
     {
         $this->reset();