Compare commits
125 Commits
wasm-strea
...
experiment
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6731bc1214 | ||
|
|
94ef6392b0 | ||
|
|
438638b72b | ||
|
|
35698f0f99 | ||
|
|
0e3a7196f9 | ||
|
|
7277d2bb43 | ||
|
|
c8c6a67530 | ||
|
|
9443900f66 | ||
|
|
76bc8590a6 | ||
|
|
6cc47e6073 | ||
|
|
2d7f5e9a9f | ||
|
|
6307c01cc6 | ||
|
|
a200f8875c | ||
|
|
75eede9870 | ||
|
|
e822673e90 | ||
|
|
9df6754dfa | ||
|
|
f5f07b9288 | ||
|
|
75a86e2594 | ||
|
|
4758fd683a | ||
|
|
186dd82653 | ||
|
|
8faf0501f4 | ||
|
|
832f000576 | ||
|
|
6da1fa04c3 | ||
|
|
0c0be618e0 | ||
|
|
8b0ab8ee49 | ||
|
|
49d0b35dc8 | ||
|
|
86da334e8f | ||
|
|
b21d5afa2d | ||
|
|
5b5f1e3aa5 | ||
|
|
34923addd7 | ||
|
|
15374f99ae | ||
|
|
1d6bcb1f57 | ||
|
|
77dd0b027f | ||
|
|
902e7cf480 | ||
|
|
08d8922aad | ||
|
|
79abba5124 | ||
|
|
cadfb09193 | ||
|
|
401cd32d07 | ||
|
|
f3b14225ba | ||
|
|
3b472fdd41 | ||
|
|
bb3af09c6c | ||
|
|
57b03d438e | ||
|
|
1a7ac272eb | ||
|
|
1b2b183d7f | ||
|
|
1f872167c1 | ||
|
|
29ffd25c18 | ||
|
|
d43dfdefdf | ||
|
|
1d20eee169 | ||
|
|
53c0e4976b | ||
|
|
0333777a37 | ||
|
|
f4438a0103 | ||
|
|
55db9426b9 | ||
|
|
535f038daa | ||
|
|
0c4852c099 | ||
|
|
b8e8755fb1 | ||
|
|
0b6af67b99 | ||
|
|
56c54dd880 | ||
|
|
a8e1c33b54 | ||
|
|
0cc2b67753 | ||
|
|
4f051fe5a5 | ||
|
|
8d63921924 | ||
|
|
0be55e05bf | ||
|
|
b133c2e233 | ||
|
|
b54308a77e | ||
|
|
47deaeb7ca | ||
|
|
83336b2949 | ||
|
|
35ef64ff79 | ||
|
|
c725b4f0fe | ||
|
|
585d5db983 | ||
|
|
2182cdd44f | ||
|
|
041ef7f7a5 | ||
|
|
6a489d35ab | ||
|
|
ee99952d90 | ||
|
|
4f09873f94 | ||
|
|
ca999b15ed | ||
|
|
eef4f8be3f | ||
|
|
ff19d052b7 | ||
|
|
e53090a937 | ||
|
|
74e1f18ae0 | ||
|
|
02fcc0ba53 | ||
|
|
e36a94cfdd | ||
|
|
b80b318e38 | ||
|
|
1fff4bf4d7 | ||
|
|
20d39347c6 | ||
|
|
aa6e2f7631 | ||
|
|
3666db3b9a | ||
|
|
5ba8266eb8 | ||
|
|
86c5dc9db9 | ||
|
|
af852927a9 | ||
|
|
0fb104b102 | ||
|
|
f6421c9c7c | ||
|
|
2d1552a345 | ||
|
|
8085604385 | ||
|
|
31cdfc7be6 | ||
|
|
307443dac3 | ||
|
|
c5fd6028b5 | ||
|
|
c7cd450f9b | ||
|
|
a988be7431 | ||
|
|
981304848f | ||
|
|
51a590c3c7 | ||
|
|
f4e68fcc04 | ||
|
|
f43a41c117 | ||
|
|
ab11fbeb47 | ||
|
|
5f4fe52eab | ||
|
|
b80732f8e2 | ||
|
|
a372ee92e9 | ||
|
|
e2ae0da4e1 | ||
|
|
3f7bceb862 | ||
|
|
507a10adc5 | ||
|
|
a8f7840d25 | ||
|
|
3ba6483bf3 | ||
|
|
fba8384ac3 | ||
|
|
def58480b3 | ||
|
|
cb5ba022ba | ||
|
|
c5c3a0e743 | ||
|
|
3c068cd6c3 | ||
|
|
82f1431440 | ||
|
|
df2f5931cd | ||
|
|
ff3b668958 | ||
|
|
eb10d4d35e | ||
|
|
18972ae0fa | ||
|
|
e7fb9ac54c | ||
|
|
08816a1d71 | ||
|
|
ea663f7491 | ||
|
|
5f28acf629 |
37
.github/workflows/refresh-php8.yml
vendored
Normal file
37
.github/workflows/refresh-php8.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Refresh PHP 8 branch
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
schedule:
|
||||
- cron: '42 2 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout php8 branch
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# directly checkout the php8 branch
|
||||
ref: php8
|
||||
# Number of commits to fetch. 0 indicates all history for all branches and tags.
|
||||
# Default: 1
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Merge master changes into php8
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
|
||||
git merge origin/master
|
||||
|
||||
- name: Push new changes
|
||||
uses: github-actions-x/commit@v2.8
|
||||
with:
|
||||
name: github-actions[bot]
|
||||
email: 41898282+github-actions[bot]@users.noreply.github.com
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
push-branch: 'php8'
|
||||
|
||||
71
.github/workflows/tests.yml
vendored
71
.github/workflows/tests.yml
vendored
@@ -2,6 +2,7 @@ name: Tests
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
|
||||
Composer:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
@@ -11,43 +12,109 @@ jobs:
|
||||
run: composer validate
|
||||
- name: Install dependencies
|
||||
run: composer install --prefer-dist --no-dev
|
||||
|
||||
PHPunit:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['5.6', '7.0', '7.1', '7.2', '7.3', '7.4']
|
||||
name: PHP ${{ matrix.php-versions }} unit tests on ${{ matrix.operating-system }}
|
||||
env:
|
||||
extensions: gd, sqlite3
|
||||
extensions-cache-key-name: phpextensions
|
||||
|
||||
steps:
|
||||
|
||||
# let's get started!
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
# cache PHP extensions
|
||||
- name: Setup cache environment
|
||||
id: extcache
|
||||
uses: shivammathur/cache-extensions@v1
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: ${{ env.extensions }}
|
||||
key: ${{ runner.os }}-${{ env.extensions-cache-key }}
|
||||
|
||||
- name: Cache extensions
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.extcache.outputs.dir }}
|
||||
key: ${{ steps.extcache.outputs.key }}
|
||||
restore-keys: ${{ runner.os }}-${{ env.extensions-cache-key }}
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-versions }}
|
||||
extensions: gd, sqlite3
|
||||
extensions: ${{ env.extensions }}
|
||||
|
||||
# Setup GitHub CI PHP problem matchers
|
||||
# https://github.com/shivammathur/setup-php#problem-matchers
|
||||
- name: Setup problem matchers for PHP
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
|
||||
|
||||
- name: Setup problem matchers for PHPUnit
|
||||
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
|
||||
|
||||
# composer cache
|
||||
- name: Remove composer lock
|
||||
run: rm composer.lock
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
|
||||
|
||||
# http://man7.org/linux/man-pages/man1/date.1.html
|
||||
# https://github.com/actions/cache#creating-a-cache-key
|
||||
- name: Get Date
|
||||
id: get-date
|
||||
run: |
|
||||
echo "::set-output name=date::$(/bin/date -u "+%Y%m%d")"
|
||||
shell: bash
|
||||
|
||||
- name: Cache dependencies
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: ${{ runner.os }}-composer-${{ steps.get-date.outputs.date }}-${{ hashFiles('**/composer.json') }}
|
||||
restore-keys: ${{ runner.os }}-composer-${{ steps.get-date.outputs.date }}-
|
||||
|
||||
# composer installation
|
||||
- name: Setup PHPunit
|
||||
run: composer install -n
|
||||
|
||||
- name: Install Google Cloud Storage
|
||||
run: composer require google/cloud-storage
|
||||
|
||||
# testing
|
||||
- name: Run unit tests
|
||||
run: ../vendor/bin/phpunit --no-coverage
|
||||
working-directory: tst
|
||||
|
||||
Mocha:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v1
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: 'js/package.json'
|
||||
|
||||
- name: Setup Mocha
|
||||
run: npm install -g mocha
|
||||
|
||||
- name: Setup Node modules
|
||||
run: npm install
|
||||
working-directory: js
|
||||
|
||||
- name: Run unit tests
|
||||
run: mocha
|
||||
working-directory: js
|
||||
|
||||
@@ -29,3 +29,9 @@ disabled:
|
||||
- short_array_syntax
|
||||
- single_line_after_imports
|
||||
- unalign_equals
|
||||
|
||||
finder:
|
||||
path:
|
||||
- "lib/"
|
||||
- "tpl/"
|
||||
- "tst/"
|
||||
|
||||
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,19 +1,20 @@
|
||||
# PrivateBin version history
|
||||
|
||||
* **1.4 (not yet released)**
|
||||
* ADDED: Translation for Estonian
|
||||
* ADDED: Translations for Estonian and Lojban
|
||||
* ADDED: new HTTP headers improving security (#765)
|
||||
* ADDED: Download button for paste text (#774)
|
||||
* ADDED: Opt-out of federated learning of cohorts (FLoC) (#776)
|
||||
* ADDED: Configuration option to exempt IPs from the rate-limiter (#787)
|
||||
* ADDED: Google Cloud Storage backend support (#795)
|
||||
* ADDED: Oracle database support (#868)
|
||||
* CHANGED: Language selection cookie only transmitted over HTTPS (#472)
|
||||
* CHANGED: Upgrading libraries to: random_compat 2.0.20
|
||||
* CHANGED: Upgrading libraries to: base-x 4.0.0, DOMpurify 2.3.6, ip-lib 1.18.0, jQuery 3.6.0, random_compat 2.0.21 & Showdown 2.0.0
|
||||
* CHANGED: Removed automatic `.ini` configuration file migration (#808)
|
||||
* CHANGED: Removed configurable `dir` for `traffic` & `purge` limiters (#419)
|
||||
* CHANGED: Server salt, traffic and purge limiter now stored in the storage backend (#419)
|
||||
* **1.3.5 (2021-04-05)**
|
||||
* ADDED: Translation for Hebrew, Lithuanian, Indonesian and Catalan
|
||||
* ADDED: Translations for Hebrew, Lithuanian, Indonesian and Catalan
|
||||
* ADDED: Make the project info configurable (#681)
|
||||
* CHANGED: Upgrading libraries to: DOMpurify 2.2.7, kjua 0.9.0 & random_compat 2.0.18
|
||||
* CHANGED: Open all links in new window (#630)
|
||||
@@ -65,7 +66,7 @@
|
||||
* CHANGED: Upgrading libraries to: DOMpurify 2.0.1
|
||||
* FIXED: Enabling browsers without WASM to create pastes and read uncompressed ones (#454)
|
||||
* FIXED: Cloning related issues (#489, #491, #493, #494)
|
||||
* FIXED: Enable file operation only when editing (#497)
|
||||
* FIXED: Enable file operation only when editing (#497)
|
||||
* FIXED: Clicking 'New' on a previously submitted paste does not blank address bar (#354)
|
||||
* FIXED: Clear address bar when create new paste from existing paste (#479)
|
||||
* FIXED: Discussion section not hiding when new/clone paste is clicked on (#484)
|
||||
@@ -228,7 +229,7 @@ encryption), i18n (translation, counterpart of i18n.php) and helper (stateless u
|
||||
* FIXED: 2 minor corrections to avoid notices in php log.
|
||||
* FIXED: Sources converted to UTF-8.
|
||||
* **Alpha 0.14 (2012-04-20):**
|
||||
* ADDED: GD presence is checked.
|
||||
* ADDED: GD presence is checked.
|
||||
* CHANGED: Traffic limiter data files moved to data/ (→easier rights management)
|
||||
* ADDED: "Burn after reading" implemented. Opening the URL will display the paste and immediately destroy it on server.
|
||||
* **Alpha 0.13 (2012-04-18):**
|
||||
@@ -236,16 +237,16 @@ encryption), i18n (translation, counterpart of i18n.php) and helper (stateless u
|
||||
* FIXED: $error not properly initialized in index.php
|
||||
* **Alpha 0.12 (2012-04-18):**
|
||||
* **DISCUSSIONS !** Now you can enable discussions on your pastes. Of course, posted comments and nickname are also encrypted and the server cannot see them.
|
||||
* This feature implies a change in storage format. You will have to delete all previous pastes in your ZeroBin.
|
||||
* This feature implies a change in storage format. You will have to delete all previous pastes in your ZeroBin.
|
||||
* Added [[php:vizhash_gd|Vizhash]] as avatars, so you can match posters IP addresses without revealing them. (Same image = same IP). Of course the IP address cannot be deduced from the Vizhash.
|
||||
* Remaining time before expiration is now displayed.
|
||||
* Explicit tags were added to CSS and jQuery selectors (eg. div#aaa instead of #aaa) to speed up browser.
|
||||
* Explicit tags were added to CSS and jQuery selectors (eg. div#aaa instead of #aaa) to speed up browser.
|
||||
* Better cleaning of the URL (to make sure the key is not broken by some stupid redirection service)
|
||||
* **Alpha 0.11 (2012-04-12):**
|
||||
* Automatically ignore parameters (such as &utm_source=...) added //after// the anchor by some stupid Web 2.0 services.
|
||||
* First public release.
|
||||
* **Alpha 0.10 (2012-04-12):**
|
||||
* IE9 does not seem to correctly support ''pre-wrap'' either. Special handling mode activated for all version of IE<10. (Note: **ALL other browsers** correctly support this feature.)
|
||||
* IE9 does not seem to correctly support ''pre-wrap'' either. Special handling mode activated for all version of IE<10. (Note: **ALL other browsers** correctly support this feature.)
|
||||
* **Alpha 0.9 (2012-04-11):**
|
||||
* Oh bummer... IE 8 is as shitty as IE6/7: Its does not seem to support ''white-space:pre-wrap'' correctly. I had to activate the special handling mode. I still have to test IE 9.
|
||||
* **Alpha 0.8 (2012-04-11):**
|
||||
|
||||
@@ -29,6 +29,7 @@ Sébastien Sauvage - original idea and main developer
|
||||
* Lucas Savva - configurable config file location, NixOS packaging
|
||||
* rodehoed - option to exempt ips from the rate-limiter
|
||||
* Mark van Holsteijn - Google Cloud Storage backend
|
||||
* Austin Huang - Oracle database support
|
||||
|
||||
## Translations
|
||||
* Hexalyse - French
|
||||
@@ -53,3 +54,4 @@ Sébastien Sauvage - original idea and main developer
|
||||
* whenwesober - Indonesian
|
||||
* retiolus - Catalan
|
||||
* sarnane - Estonian
|
||||
* foxsouns - Lojban
|
||||
|
||||
12
INSTALL.md
12
INSTALL.md
@@ -1,7 +1,7 @@
|
||||
# Installation
|
||||
|
||||
**TL;DR:** Download the
|
||||
[latest release archive](https://github.com/PrivateBin/PrivateBin/releases/latest)
|
||||
[latest release archive](https://github.com/PrivateBin/PrivateBin/releases/latest) (with the link labelled as „Source code (…)“)
|
||||
and extract it in your web hosts folder where you want to install your PrivateBin
|
||||
instance. We try to provide a mostly safe default configuration, but we urge you to
|
||||
check the [security section](#hardening-and-security) below and the [configuration
|
||||
@@ -190,8 +190,14 @@ CREATE TABLE prefix_config (
|
||||
INSERT INTO prefix_config VALUES('VERSION', '1.3.5');
|
||||
```
|
||||
|
||||
In **PostgreSQL**, the data, attachment, nickname and vizhash columns needs to
|
||||
be TEXT and not BLOB or MEDIUMBLOB.
|
||||
In **PostgreSQL**, the `data`, `attachment`, `nickname` and `vizhash` columns
|
||||
need to be `TEXT` and not `BLOB` or `MEDIUMBLOB`. The key names in brackets,
|
||||
after `PRIMARY KEY`, need to be removed.
|
||||
|
||||
In **Oracle**, the `data`, `attachment`, `nickname` and `vizhash` columns need
|
||||
to be `CLOB` and not `BLOB` or `MEDIUMBLOB`, the `id` column in the `config`
|
||||
table needs to be `VARCHAR2(16)` and the `meta` column in the `paste` table
|
||||
and the `value` column in the `config` table need to be `VARCHAR2(4000)`.
|
||||
|
||||
### Using Google Cloud Storage
|
||||
If you want to deploy PrivateBin in a serverless manner in the Google Cloud, you
|
||||
|
||||
@@ -87,7 +87,7 @@ languageselection = false
|
||||
; async functions and display an error if not and for Chrome to enable
|
||||
; webassembly support (used for zlib compression). You can remove it if Chrome
|
||||
; doesn't need to be supported and old browsers don't need to be warned.
|
||||
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval' resource:; style-src 'self'; font-src 'self'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads"
|
||||
; cspheader = "default-src 'none'; base-uri 'self'; form-action 'none'; manifest-src 'self'; connect-src * blob:; script-src 'self' 'unsafe-eval' resource:; style-src 'self'; font-src 'self'; frame-ancestors 'none'; img-src 'self' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads"
|
||||
|
||||
; stay compatible with PrivateBin Alpha 0.19, less secure
|
||||
; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
|
||||
@@ -161,7 +161,7 @@ class = Filesystem
|
||||
[model_options]
|
||||
dir = PATH "data"
|
||||
|
||||
[model]
|
||||
;[model]
|
||||
; example of a Google Cloud Storage configuration
|
||||
;class = GoogleCloudStorage
|
||||
;[model_options]
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
},
|
||||
"require" : {
|
||||
"php" : "^5.6.0 || ^7.0 || ^8.0",
|
||||
"paragonie/random_compat" : "2.0.20",
|
||||
"paragonie/random_compat" : "2.0.21",
|
||||
"yzalis/identicon" : "2.0.0",
|
||||
"mlocati/ip-lib" : "1.14.0"
|
||||
"mlocati/ip-lib" : "1.18.0"
|
||||
},
|
||||
"suggest" : {
|
||||
"google/cloud-storage" : "1.23.1"
|
||||
"google/cloud-storage" : "1.26.1"
|
||||
},
|
||||
"require-dev" : {
|
||||
"phpunit/phpunit" : "^4.6 || ^5.0"
|
||||
@@ -43,4 +43,4 @@
|
||||
"config" : {
|
||||
"autoloader-suffix" : "DontChange"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
84
composer.lock
generated
84
composer.lock
generated
@@ -4,20 +4,20 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "217f0ba9bdac1014a332a8ba390be949",
|
||||
"content-hash": "fa52d4988bfe17d4b27e3a4789a1ec49",
|
||||
"packages": [
|
||||
{
|
||||
"name": "mlocati/ip-lib",
|
||||
"version": "1.14.0",
|
||||
"version": "1.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mlocati/ip-lib.git",
|
||||
"reference": "882bc0e115970a536b13bcfa59f312783fce08c8"
|
||||
"reference": "c77bd0b1f3e3956c7e9661e75cb1f54ed67d95d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/882bc0e115970a536b13bcfa59f312783fce08c8",
|
||||
"reference": "882bc0e115970a536b13bcfa59f312783fce08c8",
|
||||
"url": "https://api.github.com/repos/mlocati/ip-lib/zipball/c77bd0b1f3e3956c7e9661e75cb1f54ed67d95d2",
|
||||
"reference": "c77bd0b1f3e3956c7e9661e75cb1f54ed67d95d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -25,8 +25,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-pdo_sqlite": "*",
|
||||
"phpunit/dbunit": "^1.4 || ^2 || ^3 || ^4",
|
||||
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5"
|
||||
"phpunit/phpunit": "^4.8 || ^5.7 || ^6.5 || ^7.5 || ^8.5 || ^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -72,27 +71,27 @@
|
||||
"type": "other"
|
||||
}
|
||||
],
|
||||
"time": "2020-12-31T11:30:02+00:00"
|
||||
"time": "2022-01-13T18:05:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/random_compat",
|
||||
"version": "v2.0.20",
|
||||
"version": "v2.0.21",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/random_compat.git",
|
||||
"reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a"
|
||||
"reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/0f1f60250fccffeaf5dda91eea1c018aed1adc2a",
|
||||
"reference": "0f1f60250fccffeaf5dda91eea1c018aed1adc2a",
|
||||
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/96c132c7f2f7bc3230723b66e89f8f150b29d5ae",
|
||||
"reference": "96c132c7f2f7bc3230723b66e89f8f150b29d5ae",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "4.*|5.*"
|
||||
"phpunit/phpunit": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
|
||||
@@ -121,7 +120,7 @@
|
||||
"pseudorandom",
|
||||
"random"
|
||||
],
|
||||
"time": "2021-04-17T09:33:01+00:00"
|
||||
"time": "2022-02-16T17:07:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "yzalis/identicon",
|
||||
@@ -270,12 +269,12 @@
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"DeepCopy\\": "src/DeepCopy/"
|
||||
},
|
||||
"files": [
|
||||
"src/DeepCopy/deep_copy.php"
|
||||
]
|
||||
],
|
||||
"psr-4": {
|
||||
"DeepCopy\\": "src/DeepCopy/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
@@ -348,16 +347,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/reflection-docblock",
|
||||
"version": "5.2.2",
|
||||
"version": "5.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
|
||||
"reference": "069a785b2141f5bcf49f3e353548dc1cce6df556"
|
||||
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556",
|
||||
"reference": "069a785b2141f5bcf49f3e353548dc1cce6df556",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170",
|
||||
"reference": "622548b623e81ca6d78b721c5e029f4ce664f170",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -368,7 +367,8 @@
|
||||
"webmozart/assert": "^1.9.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "~1.3.2"
|
||||
"mockery/mockery": "~1.3.2",
|
||||
"psalm/phar": "^4.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@@ -396,20 +396,20 @@
|
||||
}
|
||||
],
|
||||
"description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
|
||||
"time": "2020-09-03T19:13:55+00:00"
|
||||
"time": "2021-10-19T17:43:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
"version": "1.4.0",
|
||||
"version": "1.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0"
|
||||
"reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
|
||||
"reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706",
|
||||
"reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -417,7 +417,8 @@
|
||||
"phpdocumentor/reflection-common": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-tokenizer": "*"
|
||||
"ext-tokenizer": "*",
|
||||
"psalm/phar": "^4.8"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
@@ -441,7 +442,7 @@
|
||||
}
|
||||
],
|
||||
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
|
||||
"time": "2020-09-17T18:55:26+00:00"
|
||||
"time": "2022-01-04T19:58:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
@@ -1419,21 +1420,24 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.23.0",
|
||||
"version": "v1.24.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
|
||||
"reference": "30885182c981ab175d4d034db0f6f469898070ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
|
||||
"reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
|
||||
"reference": "30885182c981ab175d4d034db0f6f469898070ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.1"
|
||||
},
|
||||
"provide": {
|
||||
"ext-ctype": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-ctype": "For best performance"
|
||||
},
|
||||
@@ -1491,20 +1495,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-02-19T12:13:01+00:00"
|
||||
"time": "2021-10-20T20:35:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v4.4.24",
|
||||
"version": "v4.4.37",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "8b6d1b97521e2f125039b3fcb4747584c6dfa0ef"
|
||||
"reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/8b6d1b97521e2f125039b3fcb4747584c6dfa0ef",
|
||||
"reference": "8b6d1b97521e2f125039b3fcb4747584c6dfa0ef",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/d7f637cc0f0cc14beb0984f2bb50da560b271311",
|
||||
"reference": "d7f637cc0f0cc14beb0984f2bb50da560b271311",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1559,7 +1563,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-05-16T09:52:47+00:00"
|
||||
"time": "2022-01-24T20:11:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
|
||||
74
i18n/ca.json
74
i18n/ca.json
@@ -8,10 +8,10 @@
|
||||
"%s requires php %s or above to work. Sorry.": "%s requereix php %s o superior per funcionar. Ho sento.",
|
||||
"%s requires configuration section [%s] to be present in configuration file.": "%s requereix que la secció de configuració [%s] sigui present al fitxer de configuració.",
|
||||
"Please wait %d seconds between each post.": [
|
||||
"Espereu %d segon entre cada entrada. (singular)",
|
||||
"Espereu %d segons entre cada entrada. (1r plural)",
|
||||
"Espereu %d segons entre cada entrada. (2n plural)",
|
||||
"Please wait %d seconds between each post. (3er plural)"
|
||||
"Espereu %d segon entre cada entrada.",
|
||||
"Espereu %d segons entre cada entrada.",
|
||||
"Please wait %d seconds between each post. (2nd plural)",
|
||||
"Please wait %d seconds between each post. (3rd plural)"
|
||||
],
|
||||
"Paste is limited to %s of encrypted data.": "L'enganxat està limitat a %s de dades encriptades.",
|
||||
"Invalid data.": "Dades no vàlides.",
|
||||
@@ -20,8 +20,8 @@
|
||||
"Error saving paste. Sorry.": "S'ha produït un error en desar l'enganxat. Ho sento.",
|
||||
"Invalid paste ID.": "Identificador d'enganxament no vàlid.",
|
||||
"Paste is not of burn-after-reading type.": "Paste is not of burn-after-reading type.",
|
||||
"Wrong deletion token. Paste was not deleted.": "Wrong deletion token. Paste was not deleted.",
|
||||
"Paste was properly deleted.": "Paste was properly deleted.",
|
||||
"Wrong deletion token. Paste was not deleted.": "El token d'eliminació és incorrecte. El Paste no s'ha eliminat.",
|
||||
"Paste was properly deleted.": "El Paste s'ha esborrat correctament.",
|
||||
"JavaScript is required for %s to work. Sorry for the inconvenience.": "Cal JavaScript perquè %s funcioni. Em sap greu les molèsties.",
|
||||
"%s requires a modern browser to work.": "%s requereix un navegador modern per funcionar.",
|
||||
"New": "Nou",
|
||||
@@ -35,48 +35,48 @@
|
||||
"Discussion": "Discussió",
|
||||
"Toggle navigation": "Alternar navegació",
|
||||
"%d seconds": [
|
||||
"%d second (singular)",
|
||||
"%d seconds (1st plural)",
|
||||
"%d segon",
|
||||
"%d segons",
|
||||
"%d seconds (2nd plural)",
|
||||
"%d seconds (3rd plural)"
|
||||
],
|
||||
"%d minutes": [
|
||||
"%d minute (singular)",
|
||||
"%d minutes (1st plural)",
|
||||
"%d minut",
|
||||
"%d minuts",
|
||||
"%d minutes (2nd plural)",
|
||||
"%d minutes (3rd plural)"
|
||||
],
|
||||
"%d hours": [
|
||||
"%d hour (singular)",
|
||||
"%d hours (1st plural)",
|
||||
"%d hora",
|
||||
"%d hores",
|
||||
"%d hours (2nd plural)",
|
||||
"%d hours (3rd plural)"
|
||||
],
|
||||
"%d days": [
|
||||
"%d day (singular)",
|
||||
"%d days (1st plural)",
|
||||
"%d dia",
|
||||
"%d dies",
|
||||
"%d days (2nd plural)",
|
||||
"%d days (3rd plural)"
|
||||
],
|
||||
"%d weeks": [
|
||||
"%d week (singular)",
|
||||
"%d weeks (1st plural)",
|
||||
"%d setmana",
|
||||
"%d setmanes",
|
||||
"%d weeks (2nd plural)",
|
||||
"%d weeks (3rd plural)"
|
||||
],
|
||||
"%d months": [
|
||||
"%d month (singular)",
|
||||
"%d months (1st plural)",
|
||||
"%d mes",
|
||||
"%d mesos",
|
||||
"%d months (2nd plural)",
|
||||
"%d months (3rd plural)"
|
||||
],
|
||||
"%d years": [
|
||||
"%d year (singular)",
|
||||
"%d years (1st plural)",
|
||||
"%d any",
|
||||
"%d anys",
|
||||
"%d years (2nd plural)",
|
||||
"%d years (3rd plural)"
|
||||
],
|
||||
"Never": "Never",
|
||||
"Never": "Mai",
|
||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.",
|
||||
"This document will expire in %d seconds.": [
|
||||
"This document will expire in %d second. (singular)",
|
||||
@@ -108,26 +108,26 @@
|
||||
"This document will expire in %d months. (2nd plural)",
|
||||
"This document will expire in %d months. (3rd plural)"
|
||||
],
|
||||
"Please enter the password for this paste:": "Please enter the password for this paste:",
|
||||
"Could not decrypt data (Wrong key?)": "Could not decrypt data (Wrong key?)",
|
||||
"Please enter the password for this paste:": "Si us plau, introdueix la contrasenya per aquest paste:",
|
||||
"Could not decrypt data (Wrong key?)": "No s'han pogut desxifrar les dades (Clau incorrecte?)",
|
||||
"Could not delete the paste, it was not stored in burn after reading mode.": "Could not delete the paste, it was not stored in burn after reading mode.",
|
||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.",
|
||||
"Could not decrypt comment; Wrong key?": "Could not decrypt comment; Wrong key?",
|
||||
"Reply": "Reply",
|
||||
"Anonymous": "Anonymous",
|
||||
"Avatar generated from IP address": "Avatar generated from IP address",
|
||||
"Add comment": "Add comment",
|
||||
"Optional nickname…": "Optional nickname…",
|
||||
"Post comment": "Post comment",
|
||||
"Sending comment…": "Sending comment…",
|
||||
"Comment posted.": "Comment posted.",
|
||||
"Reply": "Respondre",
|
||||
"Anonymous": "Anònim",
|
||||
"Avatar generated from IP address": "Avatar generat a partir de l'adreça IP",
|
||||
"Add comment": "Afegir comentari",
|
||||
"Optional nickname…": "Pseudònim opcional…",
|
||||
"Post comment": "Publicar comentari",
|
||||
"Sending comment…": "Enviant comentari…",
|
||||
"Comment posted.": "Comentari publicat.",
|
||||
"Could not refresh display: %s": "Could not refresh display: %s",
|
||||
"unknown status": "unknown status",
|
||||
"unknown status": "estat desconegut",
|
||||
"server error or not responding": "server error or not responding",
|
||||
"Could not post comment: %s": "Could not post comment: %s",
|
||||
"Sending paste…": "Sending paste…",
|
||||
"Sending paste…": "Enviant paste…",
|
||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>",
|
||||
"Delete data": "Delete data",
|
||||
"Delete data": "Esborrar les dades",
|
||||
"Could not create paste: %s": "Could not create paste: %s",
|
||||
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)",
|
||||
"B": "B",
|
||||
@@ -140,10 +140,10 @@
|
||||
"ZiB": "ZiB",
|
||||
"YiB": "YiB",
|
||||
"Format": "Format",
|
||||
"Plain Text": "Plain Text",
|
||||
"Source Code": "Source Code",
|
||||
"Plain Text": "Text sense format",
|
||||
"Source Code": "Codi font",
|
||||
"Markdown": "Markdown",
|
||||
"Download attachment": "Download attachment",
|
||||
"Download attachment": "Baixar els adjunts",
|
||||
"Cloned: '%s'": "Cloned: '%s'",
|
||||
"The cloned file '%s' was attached to this paste.": "The cloned file '%s' was attached to this paste.",
|
||||
"Attach a file": "Attach a file",
|
||||
|
||||
90
i18n/cs.json
90
i18n/cs.json
@@ -6,7 +6,7 @@
|
||||
"en": "cs",
|
||||
"Paste does not exist, has expired or has been deleted.": "Vložený text neexistuje, expiroval nebo byl odstraněn.",
|
||||
"%s requires php %s or above to work. Sorry.": "%s vyžaduje php %s nebo vyšší. Lituji.",
|
||||
"%s requires configuration section [%s] to be present in configuration file.": "%s requires configuration section [%s] to be present in configuration file.",
|
||||
"%s requires configuration section [%s] to be present in configuration file.": "%s vyžaduje, aby byla v konfiguračním souboru přítomna sekce [%s].",
|
||||
"Please wait %d seconds between each post.": [
|
||||
"Počet sekund do dalšího příspěvku: %d.",
|
||||
"Počet sekund do dalšího příspěvku: %d.",
|
||||
@@ -19,10 +19,10 @@
|
||||
"Error saving comment. Sorry.": "Chyba při ukládání komentáře.",
|
||||
"Error saving paste. Sorry.": "Chyba při ukládání příspěvku.",
|
||||
"Invalid paste ID.": "Chybně vložené ID.",
|
||||
"Paste is not of burn-after-reading type.": "Paste is not of burn-after-reading type.",
|
||||
"Wrong deletion token. Paste was not deleted.": "Wrong deletion token. Paste was not deleted.",
|
||||
"Paste was properly deleted.": "Paste was properly deleted.",
|
||||
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript is required for %s to work. Sorry for the inconvenience.",
|
||||
"Paste is not of burn-after-reading type.": "Příspěvek není nastaven na smazaní po přečtení.",
|
||||
"Wrong deletion token. Paste was not deleted.": "Chybný token pro odstranění. Příspěvek nebyl smazán.",
|
||||
"Paste was properly deleted.": "Příspěvek byl řádně smazán.",
|
||||
"JavaScript is required for %s to work. Sorry for the inconvenience.": "Pro fungování %s je vyžadován JavaScript. Omlouváme se za nepříjemnosti.",
|
||||
"%s requires a modern browser to work.": "%%s requires a modern browser to work.",
|
||||
"New": "Nový",
|
||||
"Send": "Odeslat",
|
||||
@@ -33,7 +33,7 @@
|
||||
"Open discussion": "Povolit komentáře",
|
||||
"Password (recommended)": "Heslo (doporučeno)",
|
||||
"Discussion": "Komentáře",
|
||||
"Toggle navigation": "Toggle navigation",
|
||||
"Toggle navigation": "Přepnout navigaci",
|
||||
"%d seconds": [
|
||||
"%d sekuda",
|
||||
"%d sekundy",
|
||||
@@ -77,7 +77,7 @@
|
||||
"%d years (3rd plural)"
|
||||
],
|
||||
"Never": "Nikdy",
|
||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.",
|
||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Poznámka: Tato služba slouží k vyzkoušení: Data mohou být kdykoliv smazána. Při zneužití této služby zemřou koťátka.",
|
||||
"This document will expire in %d seconds.": [
|
||||
"Tento dokument expiruje za %d sekundu.",
|
||||
"Tento dokument expiruje za %d sekundy.",
|
||||
@@ -109,19 +109,19 @@
|
||||
"Tento dokument expiruje za %d měsíců."
|
||||
],
|
||||
"Please enter the password for this paste:": "Zadejte prosím heslo:",
|
||||
"Could not decrypt data (Wrong key?)": "Could not decrypt data (Wrong key?)",
|
||||
"Could not delete the paste, it was not stored in burn after reading mode.": "Could not delete the paste, it was not stored in burn after reading mode.",
|
||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.",
|
||||
"Could not decrypt comment; Wrong key?": "Could not decrypt comment; Wrong key?",
|
||||
"Reply": "Reply",
|
||||
"Could not decrypt data (Wrong key?)": "Nepodařilo se dešifrovat data (Špatný klíč?)",
|
||||
"Could not delete the paste, it was not stored in burn after reading mode.": "Nepodařilo se odstranit příspěvek, nebyl uložen v režimu smazání po přečtení.",
|
||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "POUZE PRO VAŠE OČI. Nezavírejte toto okno, tuto zprávu nelze znovu zobrazit.",
|
||||
"Could not decrypt comment; Wrong key?": "Nepodařilo se dešifrovat komentář; Špatný klíč?",
|
||||
"Reply": "Odpovědět",
|
||||
"Anonymous": "Anonym",
|
||||
"Avatar generated from IP address": "Avatar generated from IP address",
|
||||
"Avatar generated from IP address": "Avatar vygenerován z IP adresy",
|
||||
"Add comment": "Přidat komentář",
|
||||
"Optional nickname…": "Volitelný nickname…",
|
||||
"Post comment": "Odeslat komentář",
|
||||
"Sending comment…": "Odesílání komentáře…",
|
||||
"Comment posted.": "Komentář odeslán.",
|
||||
"Could not refresh display: %s": "Could not refresh display: %s",
|
||||
"Could not refresh display: %s": "Nepodařilo se obnovit zobrazení: %s",
|
||||
"unknown status": "neznámý stav",
|
||||
"server error or not responding": "Chyba na serveru nebo server neodpovídá",
|
||||
"Could not post comment: %s": "Nelze odeslat komentář: %s",
|
||||
@@ -145,45 +145,45 @@
|
||||
"Markdown": "Markdown",
|
||||
"Download attachment": "Stáhnout přílohu",
|
||||
"Cloned: '%s'": "Klonováno: '%s'",
|
||||
"The cloned file '%s' was attached to this paste.": "The cloned file '%s' was attached to this paste.",
|
||||
"The cloned file '%s' was attached to this paste.": "Naklonovaný soubor '%s' byl připojen k tomuto příspěvku.",
|
||||
"Attach a file": "Připojit soubor",
|
||||
"alternatively drag & drop a file or paste an image from the clipboard": "alternatively drag & drop a file or paste an image from the clipboard",
|
||||
"alternatively drag & drop a file or paste an image from the clipboard": "alternativně přetáhněte soubor nebo vložte obrázek ze schránky",
|
||||
"File too large, to display a preview. Please download the attachment.": "Soubor je příliš velký pro zobrazení náhledu. Stáhněte si přílohu.",
|
||||
"Remove attachment": "Odstranit přílohu",
|
||||
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Váš prohlížeč nepodporuje nahrávání šifrovaných souborů. Použijte modernější verzi prohlížeče.",
|
||||
"Invalid attachment.": "Chybná příloha.",
|
||||
"Options": "Volby",
|
||||
"Shorten URL": "Shorten URL",
|
||||
"Shorten URL": "Zkrátit URL",
|
||||
"Editor": "Editor",
|
||||
"Preview": "Náhled",
|
||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
|
||||
"Decrypt": "Decrypt",
|
||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s vyžaduje, aby PATH skončil s \"%s\". Aktualizujte PATH ve vašem souboru index.php.",
|
||||
"Decrypt": "Dešifrovat",
|
||||
"Enter password": "Zadejte heslo",
|
||||
"Loading…": "Loading…",
|
||||
"Decrypting paste…": "Decrypting paste…",
|
||||
"Preparing new paste…": "Preparing new paste…",
|
||||
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.",
|
||||
"Loading…": "Načítání…",
|
||||
"Decrypting paste…": "Dešifruji příspěvek…",
|
||||
"Preparing new paste…": "Připravuji nový příspěvek…",
|
||||
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "V případě, že tato zpráva nezmizí, se podívejte na <a href=\"%s\">tyto často kladené otázky pro řešení</a>.",
|
||||
"+++ no paste text +++": "+++ žádný vložený text +++",
|
||||
"Could not get paste data: %s": "Could not get paste data: %s",
|
||||
"QR code": "QR code",
|
||||
"This website is using an insecure HTTP connection! Please use it only for testing.": "This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||
"For more information <a href=\"%s\">see this FAQ entry</a>.": "For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.",
|
||||
"waiting on user to provide a password": "waiting on user to provide a password",
|
||||
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.",
|
||||
"Retry": "Retry",
|
||||
"Showing raw text…": "Showing raw text…",
|
||||
"Notice:": "Notice:",
|
||||
"This link will expire after %s.": "This link will expire after %s.",
|
||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "This link can only be accessed once, do not use back or refresh button in your browser.",
|
||||
"Link:": "Link:",
|
||||
"Recipient may become aware of your timezone, convert time to UTC?": "Recipient may become aware of your timezone, convert time to UTC?",
|
||||
"Use Current Timezone": "Use Current Timezone",
|
||||
"Convert To UTC": "Convert To UTC",
|
||||
"Close": "Close",
|
||||
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
|
||||
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
|
||||
"Save paste": "Save paste"
|
||||
"Could not get paste data: %s": "Nepodařilo se získat data příspěvku: %s",
|
||||
"QR code": "QR kód",
|
||||
"This website is using an insecure HTTP connection! Please use it only for testing.": "Tato stránka používá nezabezpečený připojení HTTP! Použijte ji prosím jen pro testování.",
|
||||
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Více informací naleznete <a href=\"%s\">v této položce FAQ</a>.",
|
||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Váš prohlížeč může vyžadovat připojení HTTPS pro podporu WebCrypto API. Zkuste <a href=\"%s\">přepnout na HTTPS</a>.",
|
||||
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Váš prohlížeč nepodporuje WebAssembly, který se používá pro zlib kompresi. Můžete vytvořit nekomprimované dokumenty, ale nebudete moct číst ty komprimované.",
|
||||
"waiting on user to provide a password": "čekám na zadání hesla",
|
||||
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Nepodařilo se dešifrovat data. Zadali jste špatné heslo? Zkuste to znovu pomocí tlačítka nahoře.",
|
||||
"Retry": "Opakovat",
|
||||
"Showing raw text…": "Zobrazuji surový text…",
|
||||
"Notice:": "Upozornění:",
|
||||
"This link will expire after %s.": "Tento odkaz vyprší za %s.",
|
||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "Tento odkaz je přístupný pouze jednou, nepoužívejte tlačítko zpět ani neobnovujte tuto stránku ve vašem prohlížeči.",
|
||||
"Link:": "Odkaz:",
|
||||
"Recipient may become aware of your timezone, convert time to UTC?": "Příjemce se může dozvědět o vašem časovém pásmu, převést čas na UTC?",
|
||||
"Use Current Timezone": "Použít aktuální časové pásmo",
|
||||
"Convert To UTC": "Převést na UTC",
|
||||
"Close": "Zavřít",
|
||||
"Encrypted note on PrivateBin": "Šifrovaná poznámka ve službě PrivateBin",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Navštivte tento odkaz pro zobrazení poznámky. Přeposláním URL umožníte také jiným lidem přístup.",
|
||||
"URL shortener may expose your decrypt key in URL.": "Zkracovač URL může odhalit váš dešifrovací klíč v URL.",
|
||||
"Save paste": "Uložit příspěvek"
|
||||
}
|
||||
|
||||
@@ -175,15 +175,15 @@
|
||||
"Retry": "Wiederholen",
|
||||
"Showing raw text…": "Rohtext wird angezeigt…",
|
||||
"Notice:": "Hinweis:",
|
||||
"This link will expire after %s.": "Diese Verknüpfung wird in %s ablaufen.",
|
||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "Diese Verknüpfung kann nur einmal geöffnet werden, verwende nicht den Zurück- oder Neu-laden-Knopf Deines Browsers.",
|
||||
"Link:": "Verknüpfung:",
|
||||
"This link will expire after %s.": "Dieser Link wird am %s ablaufen.",
|
||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "Dieser Link kann nur einmal geöffnet werden, verwende nicht den Zurück- oder Neu-laden-Knopf Deines Browsers.",
|
||||
"Link:": "Link:",
|
||||
"Recipient may become aware of your timezone, convert time to UTC?": "Der Empfänger könnte Deine Zeitzone erfahren, möchtest Du die Zeit in UTC umwandeln?",
|
||||
"Use Current Timezone": "Aktuelle Zeitzone verwenden",
|
||||
"Convert To UTC": "In UTC umwandeln",
|
||||
"Close": "Schliessen",
|
||||
"Encrypted note on PrivateBin": "Verschlüsselte Notiz auf PrivateBin",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Besuche diese Verknüpfung um das Dokument zu sehen. Wird die URL an eine andere Person gegeben, so kann diese Person ebenfalls auf dieses Dokument zugreifen.",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Besuche diesen Link um das Dokument zu sehen. Wird die URL an eine andere Person gegeben, so kann diese Person ebenfalls auf dieses Dokument zugreifen.",
|
||||
"URL shortener may expose your decrypt key in URL.": "Der URL-Verkürzer kann den Schlüssel in der URL enthüllen.",
|
||||
"Save paste": "Text speichern"
|
||||
}
|
||||
|
||||
189
i18n/fi.json
Normal file
189
i18n/fi.json
Normal file
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"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 on minimalistinen, avoimen lähdekoodin online pastebin jossa palvelimella ei ole tietoa syötetystä datasta. Data salataan/puretaan %sselaimessa%s käyttäen 256-bittistä AES:ää.",
|
||||
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "Enemmän tietoa <a href=\"https://privatebin.info/\">projektisivulla</a>.",
|
||||
"Because ignorance is bliss": "Koska tieto lisää tuskaa",
|
||||
"en": "fi",
|
||||
"Paste does not exist, has expired or has been deleted.": "Pastea ei ole olemassa, se on vanhentunut, tai se on poistettu.",
|
||||
"%s requires php %s or above to work. Sorry.": "%s tarvitsee php %s-versiota tai uudempaa toimiakseen. Anteeksi.",
|
||||
"%s requires configuration section [%s] to be present in configuration file.": "%s vaatii konfiguraatio-osion [%s] olevan läsnä konfiguraatiotiedostossa.",
|
||||
"Please wait %d seconds between each post.": [
|
||||
"Odotathan %d sekuntin jokaisen lähetyksen välillä.",
|
||||
"Odotathan %d sekuntia jokaisen lähetyksen välillä.",
|
||||
"Odotathan %d sekuntia jokaisen lähetyksen välillä.",
|
||||
"Odotathan %d sekuntia jokaisen lähetyksen välillä."
|
||||
],
|
||||
"Paste is limited to %s of encrypted data.": "Paste on rajoitettu kokoon %s salattua dataa.",
|
||||
"Invalid data.": "Virheellinen data.",
|
||||
"You are unlucky. Try again.": "Olet epäonnekas. Yritä uudelleen",
|
||||
"Error saving comment. Sorry.": "Virhe kommenttia tallentaessa. Anteeksi.",
|
||||
"Error saving paste. Sorry.": "Virhe pastea tallentaessa. Anteeksi.",
|
||||
"Invalid paste ID.": "Virheellinen paste ID.",
|
||||
"Paste is not of burn-after-reading type.": "Paste ei ole polta-lukemisen-jälkeen-tyyppiä",
|
||||
"Wrong deletion token. Paste was not deleted.": "Virheellinen poistotunniste. Pastea ei poistettu.",
|
||||
"Paste was properly deleted.": "Paste poistettiin kunnolla.",
|
||||
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScriptiä tarvitaan jotta %s toimisi. Anteeksi haitasta.",
|
||||
"%s requires a modern browser to work.": "%s tarvitsee modernia selainta toimiakseen.",
|
||||
"New": "Uusi",
|
||||
"Send": "Lähetä",
|
||||
"Clone": "Kloonaa",
|
||||
"Raw text": "Raaka teksti",
|
||||
"Expires": "Vanhenee",
|
||||
"Burn after reading": "Polta lukemisen jälkeen",
|
||||
"Open discussion": "Avaa keskustelu",
|
||||
"Password (recommended)": "Salasana (suositeltu)",
|
||||
"Discussion": "Keskustelu",
|
||||
"Toggle navigation": "Navigointi päällä/pois",
|
||||
"%d seconds": [
|
||||
"%d sekunti",
|
||||
"%d sekuntia",
|
||||
"%d sekuntia",
|
||||
"%d sekuntia"
|
||||
],
|
||||
"%d minutes": [
|
||||
"%d minuutti",
|
||||
"%d minuuttia",
|
||||
"%d minuuttia",
|
||||
"%d minuuttia"
|
||||
],
|
||||
"%d hours": [
|
||||
"%d tunti",
|
||||
"%d tuntia",
|
||||
"%d tuntia",
|
||||
"%d tuntia"
|
||||
],
|
||||
"%d days": [
|
||||
"%d päivä",
|
||||
"%d päivää",
|
||||
"%d päivää",
|
||||
"%d päivää"
|
||||
],
|
||||
"%d weeks": [
|
||||
"%d viikko",
|
||||
"%d viikkoa",
|
||||
"%d viikkoa",
|
||||
"%d viikkoa"
|
||||
],
|
||||
"%d months": [
|
||||
"%d kuukausi",
|
||||
"%d kuukautta",
|
||||
"%d kuukautta",
|
||||
"%d kuukautta"
|
||||
],
|
||||
"%d years": [
|
||||
"%d vuosi",
|
||||
"%d vuotta",
|
||||
"%d vuotta",
|
||||
"%d vuotta"
|
||||
],
|
||||
"Never": "Ei koskaan",
|
||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Huomaa: Tämä on testipalvelu: Data voidaan poistaa milloin tahansa. Kissanpennut kuolevat jos väärinkäytät tätä palvelua.",
|
||||
"This document will expire in %d seconds.": [
|
||||
"Tämä dokumentti vanhenee %d sekuntissa.",
|
||||
"Tämä dokumentti vanhenee %d sekunnissa.",
|
||||
"Tämä dokumentti vanhenee %d sekunnissa.",
|
||||
"Tämä dokumentti vanhenee %d sekunnissa."
|
||||
],
|
||||
"This document will expire in %d minutes.": [
|
||||
"Tämä dokumentti vanhenee %d minuutissa.",
|
||||
"Tämä dokumentti vanhenee %d minuutissa.",
|
||||
"Tämä dokumentti vanhenee %d minuutissa.",
|
||||
"Tämä dokumentti vanhenee %d minuutissa."
|
||||
],
|
||||
"This document will expire in %d hours.": [
|
||||
"Tämä dokumentti vanhenee %d tunnissa.",
|
||||
"Tämä dokumentti vanhenee %d tunnissa.",
|
||||
"Tämä dokumentti vanhenee %d tunnissa.",
|
||||
"Tämä dokumentti vanhenee %d tunnissa."
|
||||
],
|
||||
"This document will expire in %d days.": [
|
||||
"Tämä dokumentti vanhenee %d päivässä.",
|
||||
"Tämä dokumentti vanhenee %d päivässä.",
|
||||
"Tämä dokumentti vanhenee %d päivässä.",
|
||||
"Tämä dokumentti vanhenee %d päivässä."
|
||||
],
|
||||
"This document will expire in %d months.": [
|
||||
"Tämä dokumentti vanhenee %d kuukaudessa.",
|
||||
"Tämä dokumentti vanhenee %d kuukaudessa.",
|
||||
"Tämä dokumentti vanhenee %d kuukaudessa.",
|
||||
"Tämä dokumentti vanhenee %d kuukaudessa."
|
||||
],
|
||||
"Please enter the password for this paste:": "Syötä salasana tälle pastelle:",
|
||||
"Could not decrypt data (Wrong key?)": "Dataa ei voitu purkaa (Väärä avain?)",
|
||||
"Could not delete the paste, it was not stored in burn after reading mode.": "Pastea ei voitu poistaa, sitä ei säilytetty \"Polta lukemisen jälkeen\" -tilassa.",
|
||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "VAIN SINUN SILMILLESI. Älä sulje tätä ikkunaa, tätä viestiä ei voida näyttää uudelleen.",
|
||||
"Could not decrypt comment; Wrong key?": "Kommenttia ei voitu purkaa; väärä avain?",
|
||||
"Reply": "Vastaa",
|
||||
"Anonymous": "Anonyymi",
|
||||
"Avatar generated from IP address": "Avatar generoitu IP-osoitteesta",
|
||||
"Add comment": "Lisää kommentti",
|
||||
"Optional nickname…": "Valinnainen nimimerkki…",
|
||||
"Post comment": "Lähetä kommentti",
|
||||
"Sending comment…": "Lähetetään kommenttia…",
|
||||
"Comment posted.": "Kommentti lähetetty.",
|
||||
"Could not refresh display: %s": "Näyttöä ei voitu päivittää: %s",
|
||||
"unknown status": "tuntematon status",
|
||||
"server error or not responding": "palvelinvirhe tai palvelin ei vastaa",
|
||||
"Could not post comment: %s": "Kommenttia ei voitu lähettää: %s",
|
||||
"Sending paste…": "Lähetetään pastea…",
|
||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Pastesi on <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Paina [Ctrl]+[c] kopioidaksesi)</span>",
|
||||
"Delete data": "Poista data",
|
||||
"Could not create paste: %s": "Pastea ei voitu luoda: %s",
|
||||
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Pastea ei voitu purkaa: Purkausavain puuttuu URL:stä (Käytitkö uudelleenohjaajaa tai URL-lyhentäjää joka poistaa osan URL:stä?)",
|
||||
"B": "B",
|
||||
"KiB": "KiB",
|
||||
"MiB": "MiB",
|
||||
"GiB": "GiB",
|
||||
"TiB": "TiB",
|
||||
"PiB": "PiB",
|
||||
"EiB": "EiB",
|
||||
"ZiB": "ZiB",
|
||||
"YiB": "YiB",
|
||||
"Format": "Formaatti",
|
||||
"Plain Text": "Perusteksti",
|
||||
"Source Code": "Lähdekoodi",
|
||||
"Markdown": "Markdown",
|
||||
"Download attachment": "Lataa liite",
|
||||
"Cloned: '%s'": "Kloonattu: '%s'",
|
||||
"The cloned file '%s' was attached to this paste.": "Kloonattu tiedosto '%s' liitettiin tähän pasteen",
|
||||
"Attach a file": "Liitä tiedosto",
|
||||
"alternatively drag & drop a file or paste an image from the clipboard": "vaihtoehtoisesti vedä & pudota tiedosto tai liitä kuva leikepöydältä",
|
||||
"File too large, to display a preview. Please download the attachment.": "Tiedosto on liian iso esikatselun näyttämiseksi. Lataathan liitteen.",
|
||||
"Remove attachment": "Poista liite",
|
||||
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Selaimesi ei tue salattujen tiedostojen lataamista. Käytäthän uudempaa selainta.",
|
||||
"Invalid attachment.": "Virheellinen liite.",
|
||||
"Options": "Asetukset",
|
||||
"Shorten URL": "Lyhennä URL",
|
||||
"Editor": "Muokkaaja",
|
||||
"Preview": "Esikatselu",
|
||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s vaatii PATH:in loppuvan \"%s\"-merkkiin. Päivitäthän PATH:in index.php:ssäsi.",
|
||||
"Decrypt": "Pura",
|
||||
"Enter password": "Syötä salasana",
|
||||
"Loading…": "Ladataan…",
|
||||
"Decrypting paste…": "Puretaan pastea…",
|
||||
"Preparing new paste…": "Valmistellaan uutta pastea",
|
||||
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "Jos tämä viesti ei katoa koskaan, katsothan <a href=\"%s\">tämän FAQ:n ongelmanratkaisutiedon löytämiseksi</a>.",
|
||||
"+++ no paste text +++": "+++ ei paste-tekstiä +++",
|
||||
"Could not get paste data: %s": "Paste-tietoja ei löydetty: %s",
|
||||
"QR code": "QR-koodi",
|
||||
"This website is using an insecure HTTP connection! Please use it only for testing.": "Tämä sivusto käyttää epäturvallista HTTP-yhteyttä! Käytäthän sitä vain testaukseen.",
|
||||
"For more information <a href=\"%s\">see this FAQ entry</a>.": "Lisätietoja varten <a href=\"%s\">lue tämä FAQ-kohta</a>.",
|
||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Selaimesi ehkä tarvitsee HTTPS-yhteyden tukeakseen WebCrypto API:a. Yritä <a href=\"%s\">vaihtamista HTTPS:ään</a>.",
|
||||
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Selaimesi ei tue WebAssemblyä jota käytetään zlib-pakkaamiseen. Voit luoda pakkaamattomia dokumentteja, mutta et voi lukea pakattuja dokumentteja.",
|
||||
"waiting on user to provide a password": "odotetaan käyttäjän antavan salasanan",
|
||||
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Dataa ei voitu purkaa. Syötitkö väärän salasanan? Yritä uudelleen ylhäällä olevalla painikkeella.",
|
||||
"Retry": "Yritä uudelleen",
|
||||
"Showing raw text…": "Näytetään raaka reksti…",
|
||||
"Notice:": "Huomautus:",
|
||||
"This link will expire after %s.": "Tämä linkki vanhenee ajan %s jälkeen.",
|
||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "Tätä linkkiä voidaan käyttää vain kerran, älä käytä taaksepäin- tai päivityspainiketta selaimessasi.",
|
||||
"Link:": "Linkki:",
|
||||
"Recipient may become aware of your timezone, convert time to UTC?": "Vastaanottaja saattaa tulla tietoiseksi aikavyöhykkeestäsi, muutetaanko aika UTC:ksi?",
|
||||
"Use Current Timezone": "Käytä nykyistä aikavyöhykettä",
|
||||
"Convert To UTC": "Muuta UTC:ksi",
|
||||
"Close": "Sulje",
|
||||
"Encrypted note on PrivateBin": "Salattu viesti PrivateBinissä",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Käy tässä linkissä nähdäksesi viestin. URL:n antaminen kenellekään antaa heidänkin päästä katsomeen viestiä. ",
|
||||
"URL shortener may expose your decrypt key in URL.": "URL-lyhentäjä voi paljastaa purkuavaimesi URL:ssä.",
|
||||
"Save paste": "Tallenna paste"
|
||||
}
|
||||
189
i18n/jbo.json
Normal file
189
i18n/jbo.json
Normal file
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"PrivateBin": "sivlolnitvanku'a",
|
||||
"%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.": ".i la %s mupli lo sorcu lo'e se setca kibro .i ji'a zo'e se zancari gi'e fingubni .i lo samse'u na djuno lo datni selru'e cu .i ba'e %sle brauzero%s ku mipri le do datni ku fi la'oi AES poi bitni li 256",
|
||||
"More information on the <a href=\"https://privatebin.info/\">project page</a>.": "More information on the <a href=\"https://privatebin.info/\">project page</a>.",
|
||||
"Because ignorance is bliss": ".i ki'u le ka na djuno cu ka saxfri",
|
||||
"en": "jbo",
|
||||
"Paste does not exist, has expired or has been deleted.": "Paste does not exist, has expired or has been deleted.",
|
||||
"%s requires php %s or above to work. Sorry.": "%s requires php %s or above to work. Sorry.",
|
||||
"%s requires configuration section [%s] to be present in configuration file.": "%s requires configuration section [%s] to be present in configuration file.",
|
||||
"Please wait %d seconds between each post.": [
|
||||
"Please wait %d second between each post. (singular)",
|
||||
"Please wait %d seconds between each post. (1st plural)",
|
||||
"Please wait %d seconds between each post. (2nd plural)",
|
||||
"Please wait %d seconds between each post. (3rd plural)"
|
||||
],
|
||||
"Paste is limited to %s of encrypted data.": "Paste is limited to %s of encrypted data.",
|
||||
"Invalid data.": ".i le selru'e cu na drani",
|
||||
"You are unlucky. Try again.": "You are unlucky. Try again.",
|
||||
"Error saving comment. Sorry.": "Error saving comment. Sorry.",
|
||||
"Error saving paste. Sorry.": "Error saving paste. Sorry.",
|
||||
"Invalid paste ID.": "Invalid paste ID.",
|
||||
"Paste is not of burn-after-reading type.": "Paste is not of burn-after-reading type.",
|
||||
"Wrong deletion token. Paste was not deleted.": "Wrong deletion token. Paste was not deleted.",
|
||||
"Paste was properly deleted.": "Paste was properly deleted.",
|
||||
"JavaScript is required for %s to work. Sorry for the inconvenience.": "JavaScript is required for %s to work. Sorry for the inconvenience.",
|
||||
"%s requires a modern browser to work.": "%s requires a modern browser to work.",
|
||||
"New": "cnino",
|
||||
"Send": "benji",
|
||||
"Clone": "fukpi",
|
||||
"Raw text": "vlapoi nalselrucyzu'e",
|
||||
"Expires": "vimcu",
|
||||
"Burn after reading": "vimcu ba la tcidu",
|
||||
"Open discussion": "lo zbasu cu casnu",
|
||||
"Password (recommended)": "japyvla (nelti'i)",
|
||||
"Discussion": "casnu",
|
||||
"Toggle navigation": "Toggle navigation",
|
||||
"%d seconds": [
|
||||
"%d second (singular)",
|
||||
"%d seconds (1st plural)",
|
||||
"%d seconds (2nd plural)",
|
||||
"%d seconds (3rd plural)"
|
||||
],
|
||||
"%d minutes": [
|
||||
"%d minute (singular)",
|
||||
"%d minutes (1st plural)",
|
||||
"%d minutes (2nd plural)",
|
||||
"%d minutes (3rd plural)"
|
||||
],
|
||||
"%d hours": [
|
||||
"%d hour (singular)",
|
||||
"%d hours (1st plural)",
|
||||
"%d hours (2nd plural)",
|
||||
"%d hours (3rd plural)"
|
||||
],
|
||||
"%d days": [
|
||||
"%d day (singular)",
|
||||
"%d days (1st plural)",
|
||||
"%d days (2nd plural)",
|
||||
"%d days (3rd plural)"
|
||||
],
|
||||
"%d weeks": [
|
||||
"%d week (singular)",
|
||||
"%d weeks (1st plural)",
|
||||
"%d weeks (2nd plural)",
|
||||
"%d weeks (3rd plural)"
|
||||
],
|
||||
"%d months": [
|
||||
"%d month (singular)",
|
||||
"%d months (1st plural)",
|
||||
"%d months (2nd plural)",
|
||||
"%d months (3rd plural)"
|
||||
],
|
||||
"%d years": [
|
||||
"%d year (singular)",
|
||||
"%d years (1st plural)",
|
||||
"%d years (2nd plural)",
|
||||
"%d years (3rd plural)"
|
||||
],
|
||||
"Never": "Never",
|
||||
"Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.": "Note: This is a test service: Data may be deleted anytime. Kittens will die if you abuse this service.",
|
||||
"This document will expire in %d seconds.": [
|
||||
"This document will expire in %d second. (singular)",
|
||||
"This document will expire in %d seconds. (1st plural)",
|
||||
"This document will expire in %d seconds. (2nd plural)",
|
||||
"This document will expire in %d seconds. (3rd plural)"
|
||||
],
|
||||
"This document will expire in %d minutes.": [
|
||||
"This document will expire in %d minute. (singular)",
|
||||
"This document will expire in %d minutes. (1st plural)",
|
||||
"This document will expire in %d minutes. (2nd plural)",
|
||||
"This document will expire in %d minutes. (3rd plural)"
|
||||
],
|
||||
"This document will expire in %d hours.": [
|
||||
"This document will expire in %d hour. (singular)",
|
||||
"This document will expire in %d hours. (1st plural)",
|
||||
"This document will expire in %d hours. (2nd plural)",
|
||||
"This document will expire in %d hours. (3rd plural)"
|
||||
],
|
||||
"This document will expire in %d days.": [
|
||||
"This document will expire in %d day. (singular)",
|
||||
"This document will expire in %d days. (1st plural)",
|
||||
"This document will expire in %d days. (2nd plural)",
|
||||
"This document will expire in %d days. (3rd plural)"
|
||||
],
|
||||
"This document will expire in %d months.": [
|
||||
"This document will expire in %d month. (singular)",
|
||||
"This document will expire in %d months. (1st plural)",
|
||||
"This document will expire in %d months. (2nd plural)",
|
||||
"This document will expire in %d months. (3rd plural)"
|
||||
],
|
||||
"Please enter the password for this paste:": "Please enter the password for this paste:",
|
||||
"Could not decrypt data (Wrong key?)": "Could not decrypt data (Wrong key?)",
|
||||
"Could not delete the paste, it was not stored in burn after reading mode.": "Could not delete the paste, it was not stored in burn after reading mode.",
|
||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.",
|
||||
"Could not decrypt comment; Wrong key?": "Could not decrypt comment; Wrong key?",
|
||||
"Reply": "Reply",
|
||||
"Anonymous": "Anonymous",
|
||||
"Avatar generated from IP address": "Avatar generated from IP address",
|
||||
"Add comment": "Add comment",
|
||||
"Optional nickname…": "Optional nickname…",
|
||||
"Post comment": "Post comment",
|
||||
"Sending comment…": "Sending comment…",
|
||||
"Comment posted.": "Comment posted.",
|
||||
"Could not refresh display: %s": "Could not refresh display: %s",
|
||||
"unknown status": "unknown status",
|
||||
"server error or not responding": "server error or not responding",
|
||||
"Could not post comment: %s": "Could not post comment: %s",
|
||||
"Sending paste…": "Sending paste…",
|
||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>",
|
||||
"Delete data": "Delete data",
|
||||
"Could not create paste: %s": "Could not create paste: %s",
|
||||
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)",
|
||||
"B": "B",
|
||||
"KiB": "KiB",
|
||||
"MiB": "MiB",
|
||||
"GiB": "GiB",
|
||||
"TiB": "TiB",
|
||||
"PiB": "PiB",
|
||||
"EiB": "EiB",
|
||||
"ZiB": "ZiB",
|
||||
"YiB": "YiB",
|
||||
"Format": "Format",
|
||||
"Plain Text": "Plain Text",
|
||||
"Source Code": "Source Code",
|
||||
"Markdown": "Markdown",
|
||||
"Download attachment": "Download attachment",
|
||||
"Cloned: '%s'": "Cloned: '%s'",
|
||||
"The cloned file '%s' was attached to this paste.": "The cloned file '%s' was attached to this paste.",
|
||||
"Attach a file": "Attach a file",
|
||||
"alternatively drag & drop a file or paste an image from the clipboard": "alternatively drag & drop a file or paste an image from the clipboard",
|
||||
"File too large, to display a preview. Please download the attachment.": "File too large, to display a preview. Please download the attachment.",
|
||||
"Remove attachment": "Remove attachment",
|
||||
"Your browser does not support uploading encrypted files. Please use a newer browser.": "Your browser does not support uploading encrypted files. Please use a newer browser.",
|
||||
"Invalid attachment.": "Invalid attachment.",
|
||||
"Options": "Options",
|
||||
"Shorten URL": "Shorten URL",
|
||||
"Editor": "Editor",
|
||||
"Preview": "Preview",
|
||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
|
||||
"Decrypt": "Decrypt",
|
||||
"Enter password": "Enter password",
|
||||
"Loading…": "Loading…",
|
||||
"Decrypting paste…": "Decrypting paste…",
|
||||
"Preparing new paste…": "Preparing new paste…",
|
||||
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.",
|
||||
"+++ no paste text +++": "+++ no paste text +++",
|
||||
"Could not get paste data: %s": "Could not get paste data: %s",
|
||||
"QR code": "ky.bu ry termifra",
|
||||
"This website is using an insecure HTTP connection! Please use it only for testing.": "This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||
"For more information <a href=\"%s\">see this FAQ entry</a>.": "For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.",
|
||||
"waiting on user to provide a password": "waiting on user to provide a password",
|
||||
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.",
|
||||
"Retry": "refcfa",
|
||||
"Showing raw text…": "Showing raw text…",
|
||||
"Notice:": "Notice:",
|
||||
"This link will expire after %s.": "This link will expire after %s.",
|
||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "This link can only be accessed once, do not use back or refresh button in your browser.",
|
||||
"Link:": "urli:",
|
||||
"Recipient may become aware of your timezone, convert time to UTC?": "Recipient may become aware of your timezone, convert time to UTC?",
|
||||
"Use Current Timezone": "Use Current Timezone",
|
||||
"Convert To UTC": "galfi lo cabni la utc",
|
||||
"Close": "ganlo",
|
||||
"Encrypted note on PrivateBin": ".i lo lo notci ku mifra cu zvati sivlolnitvanku'a",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
|
||||
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
|
||||
"Save paste": "rejgau fukpi"
|
||||
}
|
||||
@@ -89,6 +89,7 @@
|
||||
"ku": ["Kurdî", "Kurdish"],
|
||||
"kj": ["Kuanyama", "Kwanyama"],
|
||||
"la": ["lingua latina", "Latin"],
|
||||
"jbo":["jbobau", "Lojban"],
|
||||
"lb": ["Lëtzebuergesch", "Luxembourgish"],
|
||||
"lg": ["Luganda", "Ganda"],
|
||||
"li": ["Limburgs", "Limburgish"],
|
||||
|
||||
@@ -185,5 +185,5 @@
|
||||
"Encrypted note on PrivateBin": "Šifruoti užrašai ties PrivateBin",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Norėdami matyti užrašus, aplankykite šį tinklalapį. Pasidalinus šiuo URL adresu su kitais žmonėmis, jiems taip pat bus leidžiama prieiga prie šių užrašų.",
|
||||
"URL shortener may expose your decrypt key in URL.": "URL trumpinimo įrankis gali atskleisti URL adrese jūsų iššifravimo raktą.",
|
||||
"Save paste": "Save paste"
|
||||
"Save paste": "Įrašyti įdėjimą"
|
||||
}
|
||||
|
||||
@@ -184,6 +184,6 @@
|
||||
"Close": "Tampar",
|
||||
"Encrypted note on PrivateBin": "Nòtas chifradas sus PrivateBin",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visitatz aqueste ligam per veire la nòta. Fornir lo ligam a qualqu’un mai li permet tanben d’accedir a la nòta.",
|
||||
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
|
||||
"Save paste": "Save paste"
|
||||
"URL shortener may expose your decrypt key in URL.": "Los espleches d’acorchiment d’URL pòdon expausar la clau de deschiframent dins l’URL.",
|
||||
"Save paste": "Enregistrar lo tèxt"
|
||||
}
|
||||
|
||||
38
i18n/tr.json
38
i18n/tr.json
@@ -26,14 +26,14 @@
|
||||
"%s requires a modern browser to work.": "%s requires a modern browser to work.",
|
||||
"New": "Yeni",
|
||||
"Send": "Gönder",
|
||||
"Clone": "Clone",
|
||||
"Clone": "Kopyala",
|
||||
"Raw text": "Raw text",
|
||||
"Expires": "Expires",
|
||||
"Expires": "Süre Sonu",
|
||||
"Burn after reading": "Burn after reading",
|
||||
"Open discussion": "Open discussion",
|
||||
"Open discussion": "Açık Tartışmalar",
|
||||
"Password (recommended)": "Password (recommended)",
|
||||
"Discussion": "Discussion",
|
||||
"Toggle navigation": "Toggle navigation",
|
||||
"Discussion": "Tartışma",
|
||||
"Toggle navigation": "Gezinmeyi değiştir",
|
||||
"%d seconds": [
|
||||
"%d second (singular)",
|
||||
"%d seconds (1st plural)",
|
||||
@@ -113,21 +113,21 @@
|
||||
"Could not delete the paste, it was not stored in burn after reading mode.": "Could not delete the paste, it was not stored in burn after reading mode.",
|
||||
"FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.": "FOR YOUR EYES ONLY. Don't close this window, this message can't be displayed again.",
|
||||
"Could not decrypt comment; Wrong key?": "Could not decrypt comment; Wrong key?",
|
||||
"Reply": "Reply",
|
||||
"Anonymous": "Anonymous",
|
||||
"Reply": "Cevapla",
|
||||
"Anonymous": "Anonim",
|
||||
"Avatar generated from IP address": "Avatar generated from IP address",
|
||||
"Add comment": "Add comment",
|
||||
"Add comment": "Yorum ekle",
|
||||
"Optional nickname…": "Optional nickname…",
|
||||
"Post comment": "Post comment",
|
||||
"Post comment": "Yorumu gönder",
|
||||
"Sending comment…": "Sending comment…",
|
||||
"Comment posted.": "Comment posted.",
|
||||
"Comment posted.": "Yorum gönderildi.",
|
||||
"Could not refresh display: %s": "Could not refresh display: %s",
|
||||
"unknown status": "unknown status",
|
||||
"server error or not responding": "server error or not responding",
|
||||
"Could not post comment: %s": "Could not post comment: %s",
|
||||
"Sending paste…": "Sending paste…",
|
||||
"Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>": "Your paste is <a id=\"pasteurl\" href=\"%s\">%s</a> <span id=\"copyhint\">(Hit [Ctrl]+[c] to copy)</span>",
|
||||
"Delete data": "Delete data",
|
||||
"Delete data": "Veriyi sil",
|
||||
"Could not create paste: %s": "Could not create paste: %s",
|
||||
"Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)": "Cannot decrypt paste: Decryption key missing in URL (Did you use a redirector or an URL shortener which strips part of the URL?)",
|
||||
"B": "B",
|
||||
@@ -155,33 +155,33 @@
|
||||
"Options": "Options",
|
||||
"Shorten URL": "Shorten URL",
|
||||
"Editor": "Editor",
|
||||
"Preview": "Preview",
|
||||
"Preview": "Ön izleme",
|
||||
"%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.": "%s requires the PATH to end in a \"%s\". Please update the PATH in your index.php.",
|
||||
"Decrypt": "Decrypt",
|
||||
"Enter password": "Enter password",
|
||||
"Loading…": "Loading…",
|
||||
"Enter password": "Şifreyi girin",
|
||||
"Loading…": "Yükleniyor…",
|
||||
"Decrypting paste…": "Decrypting paste…",
|
||||
"Preparing new paste…": "Preparing new paste…",
|
||||
"In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.": "In case this message never disappears please have a look at <a href=\"%s\">this FAQ for information to troubleshoot</a>.",
|
||||
"+++ no paste text +++": "+++ no paste text +++",
|
||||
"Could not get paste data: %s": "Could not get paste data: %s",
|
||||
"QR code": "QR code",
|
||||
"QR code": "QR kodu",
|
||||
"This website is using an insecure HTTP connection! Please use it only for testing.": "This website is using an insecure HTTP connection! Please use it only for testing.",
|
||||
"For more information <a href=\"%s\">see this FAQ entry</a>.": "For more information <a href=\"%s\">see this FAQ entry</a>.",
|
||||
"Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.": "Your browser may require an HTTPS connection to support the WebCrypto API. Try <a href=\"%s\">switching to HTTPS</a>.",
|
||||
"Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.": "Your browser doesn't support WebAssembly, used for zlib compression. You can create uncompressed documents, but can't read compressed ones.",
|
||||
"waiting on user to provide a password": "waiting on user to provide a password",
|
||||
"Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.": "Could not decrypt data. Did you enter a wrong password? Retry with the button at the top.",
|
||||
"Retry": "Retry",
|
||||
"Retry": "Yeniden Dene",
|
||||
"Showing raw text…": "Showing raw text…",
|
||||
"Notice:": "Notice:",
|
||||
"Notice:": "Bildirim:",
|
||||
"This link will expire after %s.": "This link will expire after %s.",
|
||||
"This link can only be accessed once, do not use back or refresh button in your browser.": "This link can only be accessed once, do not use back or refresh button in your browser.",
|
||||
"Link:": "Link:",
|
||||
"Link:": "Bağlantı:",
|
||||
"Recipient may become aware of your timezone, convert time to UTC?": "Recipient may become aware of your timezone, convert time to UTC?",
|
||||
"Use Current Timezone": "Use Current Timezone",
|
||||
"Convert To UTC": "Convert To UTC",
|
||||
"Close": "Close",
|
||||
"Close": "Kapat",
|
||||
"Encrypted note on PrivateBin": "Encrypted note on PrivateBin",
|
||||
"Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.": "Visit this link to see the note. Giving the URL to anyone allows them to access the note, too.",
|
||||
"URL shortener may expose your decrypt key in URL.": "URL shortener may expose your decrypt key in URL.",
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
'use strict';
|
||||
// base-x encoding / decoding
|
||||
// based on https://github.com/cryptocoinjs/base-x 3.0.7
|
||||
// modification: removed Buffer dependency and node.modules entry
|
||||
// Copyright (c) 2018 base-x contributors
|
||||
// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)
|
||||
// Distributed under the MIT software license, see the accompanying
|
||||
// file LICENSE or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
(function(){
|
||||
this.baseX = function base (ALPHABET) {
|
||||
if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }
|
||||
var BASE_MAP = new Uint8Array(256)
|
||||
BASE_MAP.fill(255)
|
||||
for (var j = 0; j < BASE_MAP.length; j++) {
|
||||
BASE_MAP[j] = 255
|
||||
}
|
||||
for (var i = 0; i < ALPHABET.length; i++) {
|
||||
var x = ALPHABET.charAt(i)
|
||||
var xc = x.charCodeAt(0)
|
||||
@@ -23,6 +22,13 @@ this.baseX = function base (ALPHABET) {
|
||||
var FACTOR = Math.log(BASE) / Math.log(256) // log(BASE) / log(256), rounded up
|
||||
var iFACTOR = Math.log(256) / Math.log(BASE) // log(256) / log(BASE), rounded up
|
||||
function encode (source) {
|
||||
if (source instanceof Uint8Array) {
|
||||
} else if (ArrayBuffer.isView(source)) {
|
||||
source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength)
|
||||
} else if (Array.isArray(source)) {
|
||||
source = Uint8Array.from(source)
|
||||
}
|
||||
if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }
|
||||
if (source.length === 0) { return '' }
|
||||
// Skip & count leading zeroes.
|
||||
var zeroes = 0
|
||||
@@ -62,10 +68,8 @@ this.baseX = function base (ALPHABET) {
|
||||
}
|
||||
function decodeUnsafe (source) {
|
||||
if (typeof source !== 'string') { throw new TypeError('Expected String') }
|
||||
if (source.length === 0) { return '' }
|
||||
if (source.length === 0) { return new Uint8Array() }
|
||||
var psz = 0
|
||||
// Skip leading spaces.
|
||||
if (source[psz] === ' ') { return }
|
||||
// Skip and count leading '1's.
|
||||
var zeroes = 0
|
||||
var length = 0
|
||||
@@ -92,14 +96,12 @@ this.baseX = function base (ALPHABET) {
|
||||
length = i
|
||||
psz++
|
||||
}
|
||||
// Skip trailing spaces.
|
||||
if (source[psz] === ' ') { return }
|
||||
// Skip leading zeroes in b256.
|
||||
var it4 = size - length
|
||||
while (it4 !== size && b256[it4] === 0) {
|
||||
it4++
|
||||
}
|
||||
var vch = []
|
||||
var vch = new Uint8Array(zeroes + (size - it4))
|
||||
var j = zeroes
|
||||
while (it4 !== size) {
|
||||
vch[j++] = b256[it4++]
|
||||
@@ -10,15 +10,15 @@ global.fs = require('fs');
|
||||
global.WebCrypto = require('@peculiar/webcrypto').Crypto;
|
||||
|
||||
// application libraries to test
|
||||
global.$ = global.jQuery = require('./jquery-3.4.1');
|
||||
global.$ = global.jQuery = require('./jquery-3.6.0');
|
||||
global.RawDeflate = require('./rawinflate-0.3').RawDeflate;
|
||||
global.zlib = require('./zlib-1.2.11').zlib;
|
||||
require('./prettify');
|
||||
global.prettyPrint = window.PR.prettyPrint;
|
||||
global.prettyPrintOne = window.PR.prettyPrintOne;
|
||||
global.showdown = require('./showdown-1.9.1');
|
||||
global.DOMPurify = require('./purify-2.2.7');
|
||||
global.baseX = require('./base-x-3.0.7').baseX;
|
||||
global.showdown = require('./showdown-2.0.0');
|
||||
global.DOMPurify = require('./purify-2.3.6');
|
||||
global.baseX = require('./base-x-4.0.0').baseX;
|
||||
global.Legacy = require('./legacy').Legacy;
|
||||
require('./bootstrap-3.3.7');
|
||||
require('./privatebin');
|
||||
|
||||
2
js/jquery-3.4.1.js
vendored
2
js/jquery-3.4.1.js
vendored
File diff suppressed because one or more lines are too long
2
js/jquery-3.6.0.js
vendored
Normal file
2
js/jquery-3.6.0.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -601,7 +601,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||
* @prop {string[]}
|
||||
* @readonly
|
||||
*/
|
||||
const supportedLanguages = ['bg', 'ca', 'cs', 'de', 'es', 'et', 'fr', 'he', 'hu', 'id', 'it', 'lt', 'no', 'nl', 'pl', 'pt', 'oc', 'ru', 'sl', 'uk', 'zh'];
|
||||
const supportedLanguages = ['bg', 'ca', 'cs', 'de', 'es', 'et', 'fr', 'he', 'hu', 'id', 'it', 'jbo', 'lt', 'no', 'nl', 'pl', 'pt', 'oc', 'ru', 'sl', 'uk', 'zh'];
|
||||
|
||||
/**
|
||||
* built in language
|
||||
@@ -785,6 +785,7 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||
case 'he':
|
||||
return n === 1 ? 0 : (n === 2 ? 1 : ((n < 0 || n > 10) && (n % 10 === 0) ? 2 : 3));
|
||||
case 'id':
|
||||
case 'jbo':
|
||||
return 0;
|
||||
case 'lt':
|
||||
return n % 10 === 1 && n % 100 !== 11 ? 0 : ((n % 10 >= 2 && n % 100 < 10 || n % 100 >= 20) ? 1 : 2);
|
||||
@@ -5404,8 +5405,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
|
||||
node.setAttribute('target', '_blank');
|
||||
}
|
||||
// set non-HTML/MathML links to xlink:show=new
|
||||
if (!node.hasAttribute('target')
|
||||
&& (node.hasAttribute('xlink:href')
|
||||
if (!node.hasAttribute('target')
|
||||
&& (node.hasAttribute('xlink:href')
|
||||
|| node.hasAttribute('href'))) {
|
||||
node.setAttribute('xlink:show', 'new');
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
2
js/purify-2.3.6.js
Normal file
2
js/purify-2.3.6.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2447
js/showdown-2.0.0.js
Normal file
2447
js/showdown-2.0.0.js
Normal file
File diff suppressed because it is too large
Load Diff
5157
js/showdown.js
Normal file
5157
js/showdown.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -44,7 +44,7 @@ class Configuration
|
||||
'fileupload' => false,
|
||||
'burnafterreadingselected' => false,
|
||||
'defaultformatter' => 'plaintext',
|
||||
'syntaxhighlightingtheme' => null,
|
||||
'syntaxhighlightingtheme' => '',
|
||||
'sizelimit' => 10485760,
|
||||
'template' => 'bootstrap',
|
||||
'info' => 'More information on the <a href=\'https://privatebin.info/\'>project page</a>.',
|
||||
@@ -54,7 +54,7 @@ class Configuration
|
||||
'urlshortener' => '',
|
||||
'qrcode' => true,
|
||||
'icon' => 'identicon',
|
||||
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\' resource:; style-src \'self\'; font-src \'self\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
|
||||
'cspheader' => 'default-src \'none\'; base-uri \'self\'; form-action \'none\'; manifest-src \'self\'; connect-src * blob:; script-src \'self\' \'unsafe-eval\' resource:; style-src \'self\'; font-src \'self\'; frame-ancestors \'none\'; img-src \'self\' data: blob:; media-src blob:; object-src blob:; sandbox allow-same-origin allow-scripts allow-forms allow-popups allow-modals allow-downloads',
|
||||
'zerobincompatibility' => false,
|
||||
'httpwarning' => true,
|
||||
'compression' => 'zlib',
|
||||
@@ -101,16 +101,23 @@ class Configuration
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$basePaths = array();
|
||||
$config = array();
|
||||
$basePath = (getenv('CONFIG_PATH') !== false ? getenv('CONFIG_PATH') : PATH . 'cfg') . DIRECTORY_SEPARATOR;
|
||||
$configFile = $basePath . 'conf.php';
|
||||
|
||||
if (is_readable($configFile)) {
|
||||
$config = parse_ini_file($configFile, true);
|
||||
foreach (array('main', 'model', 'model_options') as $section) {
|
||||
if (!array_key_exists($section, $config)) {
|
||||
throw new Exception(I18n::_('PrivateBin requires configuration section [%s] to be present in configuration file.', $section), 2);
|
||||
$configPath = getenv('CONFIG_PATH');
|
||||
if ($configPath !== false && !empty($configPath)) {
|
||||
$basePaths[] = $configPath;
|
||||
}
|
||||
$basePaths[] = PATH . 'cfg';
|
||||
foreach ($basePaths as $basePath) {
|
||||
$configFile = $basePath . DIRECTORY_SEPARATOR . 'conf.php';
|
||||
if (is_readable($configFile)) {
|
||||
$config = parse_ini_file($configFile, true);
|
||||
foreach (array('main', 'model', 'model_options') as $section) {
|
||||
if (!array_key_exists($section, $config)) {
|
||||
throw new Exception(I18n::_('PrivateBin requires configuration section [%s] to be present in configuration file.', $section), 2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,11 @@ class Database extends AbstractData
|
||||
self::$_type = strtolower(
|
||||
substr($options['dsn'], 0, strpos($options['dsn'], ':'))
|
||||
);
|
||||
// MySQL uses backticks to quote identifiers by default,
|
||||
// tell it to expect ANSI SQL double quotes
|
||||
if (self::$_type === 'mysql' && defined('PDO::MYSQL_ATTR_INIT_COMMAND')) {
|
||||
$options['opt'][PDO::MYSQL_ATTR_INIT_COMMAND] = "SET sql_mode='ANSI_QUOTES'";
|
||||
}
|
||||
$tableQuery = self::_getTableQuery(self::$_type);
|
||||
self::$_db = new PDO(
|
||||
$options['dsn'],
|
||||
@@ -200,8 +205,8 @@ class Database extends AbstractData
|
||||
}
|
||||
try {
|
||||
return self::_exec(
|
||||
'INSERT INTO ' . self::_sanitizeIdentifier('paste') .
|
||||
' VALUES(?,?,?,?,?,?,?,?,?)',
|
||||
'INSERT INTO "' . self::_sanitizeIdentifier('paste') .
|
||||
'" VALUES(?,?,?,?,?,?,?,?,?)',
|
||||
array(
|
||||
$pasteid,
|
||||
$isVersion1 ? $paste['data'] : Json::encode($paste),
|
||||
@@ -235,8 +240,8 @@ class Database extends AbstractData
|
||||
self::$_cache[$pasteid] = false;
|
||||
try {
|
||||
$paste = self::_select(
|
||||
'SELECT * FROM ' . self::_sanitizeIdentifier('paste') .
|
||||
' WHERE dataid = ?', array($pasteid), true
|
||||
'SELECT * FROM "' . self::_sanitizeIdentifier('paste') .
|
||||
'" WHERE "dataid" = ?', array($pasteid), true
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
$paste = false;
|
||||
@@ -297,12 +302,12 @@ class Database extends AbstractData
|
||||
public function delete($pasteid)
|
||||
{
|
||||
self::_exec(
|
||||
'DELETE FROM ' . self::_sanitizeIdentifier('paste') .
|
||||
' WHERE dataid = ?', array($pasteid)
|
||||
'DELETE FROM "' . self::_sanitizeIdentifier('paste') .
|
||||
'" WHERE "dataid" = ?', array($pasteid)
|
||||
);
|
||||
self::_exec(
|
||||
'DELETE FROM ' . self::_sanitizeIdentifier('comment') .
|
||||
' WHERE pasteid = ?', array($pasteid)
|
||||
'DELETE FROM "' . self::_sanitizeIdentifier('comment') .
|
||||
'" WHERE "pasteid" = ?', array($pasteid)
|
||||
);
|
||||
if (
|
||||
array_key_exists($pasteid, self::$_cache)
|
||||
@@ -357,8 +362,8 @@ class Database extends AbstractData
|
||||
}
|
||||
try {
|
||||
return self::_exec(
|
||||
'INSERT INTO ' . self::_sanitizeIdentifier('comment') .
|
||||
' VALUES(?,?,?,?,?,?,?)',
|
||||
'INSERT INTO "' . self::_sanitizeIdentifier('comment') .
|
||||
'" VALUES(?,?,?,?,?,?,?)',
|
||||
array(
|
||||
$commentid,
|
||||
$pasteid,
|
||||
@@ -384,13 +389,13 @@ class Database extends AbstractData
|
||||
public function readComments($pasteid)
|
||||
{
|
||||
$rows = self::_select(
|
||||
'SELECT * FROM ' . self::_sanitizeIdentifier('comment') .
|
||||
' WHERE pasteid = ?', array($pasteid)
|
||||
'SELECT * FROM "' . self::_sanitizeIdentifier('comment') .
|
||||
'" WHERE "pasteid" = ?', array($pasteid)
|
||||
);
|
||||
|
||||
// create comment list
|
||||
$comments = array();
|
||||
if (count($rows)) {
|
||||
if (is_array($rows) && count($rows)) {
|
||||
foreach ($rows as $row) {
|
||||
$i = $this->getOpenSlot($comments, (int) $row['postdate']);
|
||||
$data = Json::decode($row['data']);
|
||||
@@ -429,8 +434,8 @@ class Database extends AbstractData
|
||||
{
|
||||
try {
|
||||
return (bool) self::_select(
|
||||
'SELECT dataid FROM ' . self::_sanitizeIdentifier('comment') .
|
||||
' WHERE pasteid = ? AND parentid = ? AND dataid = ?',
|
||||
'SELECT "dataid" FROM "' . self::_sanitizeIdentifier('comment') .
|
||||
'" WHERE "pasteid" = ? AND "parentid" = ? AND "dataid" = ?',
|
||||
array($pasteid, $parentid, $commentid), true
|
||||
);
|
||||
} catch (Exception $e) {
|
||||
@@ -458,8 +463,8 @@ class Database extends AbstractData
|
||||
}
|
||||
}
|
||||
return self::_exec(
|
||||
'UPDATE ' . self::_sanitizeIdentifier('config') .
|
||||
' SET value = ? WHERE id = ?',
|
||||
'UPDATE "' . self::_sanitizeIdentifier('config') .
|
||||
'" SET "value" = ? WHERE "id" = ?',
|
||||
array($value, strtoupper($namespace))
|
||||
);
|
||||
}
|
||||
@@ -479,8 +484,8 @@ class Database extends AbstractData
|
||||
if ($value === '') {
|
||||
// initialize the row, so that setValue can rely on UPDATE queries
|
||||
self::_exec(
|
||||
'INSERT INTO ' . self::_sanitizeIdentifier('config') .
|
||||
' VALUES(?,?)',
|
||||
'INSERT INTO "' . self::_sanitizeIdentifier('config') .
|
||||
'" VALUES(?,?)',
|
||||
array($configKey, '')
|
||||
);
|
||||
|
||||
@@ -517,11 +522,12 @@ class Database extends AbstractData
|
||||
{
|
||||
$pastes = array();
|
||||
$rows = self::_select(
|
||||
'SELECT dataid FROM ' . self::_sanitizeIdentifier('paste') .
|
||||
' WHERE expiredate < ? AND expiredate != ? LIMIT ?',
|
||||
'SELECT "dataid" FROM "' . self::_sanitizeIdentifier('paste') .
|
||||
'" WHERE "expiredate" < ? AND "expiredate" != ? ' .
|
||||
(self::$_type === 'oci' ? 'FETCH NEXT ? ROWS ONLY' : 'LIMIT ?'),
|
||||
array(time(), 0, $batchsize)
|
||||
);
|
||||
if (count($rows)) {
|
||||
if (is_array($rows) && count($rows)) {
|
||||
foreach ($rows as $row) {
|
||||
$pastes[] = $row['dataid'];
|
||||
}
|
||||
@@ -542,7 +548,17 @@ class Database extends AbstractData
|
||||
private static function _exec($sql, array $params)
|
||||
{
|
||||
$statement = self::$_db->prepare($sql);
|
||||
$result = $statement->execute($params);
|
||||
foreach ($params as $key => &$parameter) {
|
||||
$position = $key + 1;
|
||||
if (is_int($parameter)) {
|
||||
$statement->bindParam($position, $parameter, PDO::PARAM_INT);
|
||||
} elseif (strlen($parameter) >= 4000) {
|
||||
$statement->bindParam($position, $parameter, PDO::PARAM_STR, strlen($parameter));
|
||||
} else {
|
||||
$statement->bindParam($position, $parameter);
|
||||
}
|
||||
}
|
||||
$result = $statement->execute();
|
||||
$statement->closeCursor();
|
||||
return $result;
|
||||
}
|
||||
@@ -562,10 +578,24 @@ class Database extends AbstractData
|
||||
{
|
||||
$statement = self::$_db->prepare($sql);
|
||||
$statement->execute($params);
|
||||
$result = $firstOnly ?
|
||||
$statement->fetch(PDO::FETCH_ASSOC) :
|
||||
$statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
if ($firstOnly) {
|
||||
$result = $statement->fetch(PDO::FETCH_ASSOC);
|
||||
} elseif (self::$_type === 'oci') {
|
||||
// workaround for https://bugs.php.net/bug.php?id=46728
|
||||
$result = array();
|
||||
while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
|
||||
$result[] = array_map('self::_sanitizeClob', $row);
|
||||
}
|
||||
} else {
|
||||
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
$statement->closeCursor();
|
||||
if (self::$_type === 'oci' && is_array($result)) {
|
||||
// returned CLOB values are streams, convert these into strings
|
||||
$result = $firstOnly ?
|
||||
array_map('self::_sanitizeClob', $result) :
|
||||
$result;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -598,14 +628,15 @@ class Database extends AbstractData
|
||||
{
|
||||
switch ($type) {
|
||||
case 'ibm':
|
||||
$sql = 'SELECT tabname FROM SYSCAT.TABLES ';
|
||||
$sql = 'SELECT "tabname" FROM "SYSCAT"."TABLES"';
|
||||
break;
|
||||
case 'informix':
|
||||
$sql = 'SELECT tabname FROM systables ';
|
||||
$sql = 'SELECT "tabname" FROM "systables"';
|
||||
break;
|
||||
case 'mssql':
|
||||
$sql = 'SELECT name FROM sysobjects '
|
||||
. "WHERE type = 'U' ORDER BY name";
|
||||
// U: tables created by the user
|
||||
$sql = 'SELECT "name" FROM "sysobjects" '
|
||||
. 'WHERE "type" = \'U\' ORDER BY "name"';
|
||||
break;
|
||||
case 'mysql':
|
||||
$sql = 'SHOW TABLES';
|
||||
@@ -614,23 +645,23 @@ class Database extends AbstractData
|
||||
$sql = 'SELECT table_name FROM all_tables';
|
||||
break;
|
||||
case 'pgsql':
|
||||
$sql = 'SELECT c.relname AS table_name '
|
||||
. 'FROM pg_class c, pg_user u '
|
||||
. "WHERE c.relowner = u.usesysid AND c.relkind = 'r' "
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) '
|
||||
. "AND c.relname !~ '^(pg_|sql_)' "
|
||||
$sql = 'SELECT c."relname" AS "table_name" '
|
||||
. 'FROM "pg_class" c, "pg_user" u '
|
||||
. 'WHERE c."relowner" = u."usesysid" AND c."relkind" = \'r\' '
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM "pg_views" WHERE "viewname" = c."relname") '
|
||||
. "AND c.\"relname\" !~ '^(pg_|sql_)' "
|
||||
. 'UNION '
|
||||
. 'SELECT c.relname AS table_name '
|
||||
. 'FROM pg_class c '
|
||||
. "WHERE c.relkind = 'r' "
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM pg_views WHERE viewname = c.relname) '
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM pg_user WHERE usesysid = c.relowner) '
|
||||
. "AND c.relname !~ '^pg_'";
|
||||
. 'SELECT c."relname" AS "table_name" '
|
||||
. 'FROM "pg_class" c '
|
||||
. "WHERE c.\"relkind\" = 'r' "
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM "pg_views" WHERE "viewname" = c."relname") '
|
||||
. 'AND NOT EXISTS (SELECT 1 FROM "pg_user" WHERE "usesysid" = c."relowner") '
|
||||
. "AND c.\"relname\" !~ '^pg_'";
|
||||
break;
|
||||
case 'sqlite':
|
||||
$sql = "SELECT name FROM sqlite_master WHERE type='table' "
|
||||
. 'UNION ALL SELECT name FROM sqlite_temp_master '
|
||||
. "WHERE type='table' ORDER BY name";
|
||||
$sql = 'SELECT "name" FROM "sqlite_master" WHERE "type"=\'table\' '
|
||||
. 'UNION ALL SELECT "name" FROM "sqlite_temp_master" '
|
||||
. 'WHERE "type"=\'table\' ORDER BY "name"';
|
||||
break;
|
||||
default:
|
||||
throw new Exception(
|
||||
@@ -652,8 +683,8 @@ class Database extends AbstractData
|
||||
{
|
||||
try {
|
||||
$row = self::_select(
|
||||
'SELECT value FROM ' . self::_sanitizeIdentifier('config') .
|
||||
' WHERE id = ?', array($key), true
|
||||
'SELECT "value" FROM "' . self::_sanitizeIdentifier('config') .
|
||||
'" WHERE "id" = ?', array($key), true
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
return '';
|
||||
@@ -672,10 +703,14 @@ class Database extends AbstractData
|
||||
private static function _getPrimaryKeyClauses($key = 'dataid')
|
||||
{
|
||||
$main_key = $after_key = '';
|
||||
if (self::$_type === 'mysql') {
|
||||
$after_key = ", PRIMARY KEY ($key)";
|
||||
} else {
|
||||
$main_key = ' PRIMARY KEY';
|
||||
switch (self::$_type) {
|
||||
case 'mysql':
|
||||
case 'oci':
|
||||
$after_key = ", PRIMARY KEY (\"$key\")";
|
||||
break;
|
||||
default:
|
||||
$main_key = ' PRIMARY KEY';
|
||||
break;
|
||||
}
|
||||
return array($main_key, $after_key);
|
||||
}
|
||||
@@ -683,7 +718,7 @@ class Database extends AbstractData
|
||||
/**
|
||||
* get the data type, depending on the database driver
|
||||
*
|
||||
* PostgreSQL uses a different API for BLOBs then SQL, hence we use TEXT
|
||||
* PostgreSQL and OCI uses a different API for BLOBs then SQL, hence we use TEXT and CLOB
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
@@ -691,13 +726,20 @@ class Database extends AbstractData
|
||||
*/
|
||||
private static function _getDataType()
|
||||
{
|
||||
return self::$_type === 'pgsql' ? 'TEXT' : 'BLOB';
|
||||
switch (self::$_type) {
|
||||
case 'oci':
|
||||
return 'CLOB';
|
||||
case 'pgsql':
|
||||
return 'TEXT';
|
||||
default:
|
||||
return 'BLOB';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the attachment type, depending on the database driver
|
||||
*
|
||||
* PostgreSQL uses a different API for BLOBs then SQL, hence we use TEXT
|
||||
* PostgreSQL and OCI use different APIs for BLOBs then SQL, hence we use TEXT and CLOB
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
@@ -705,7 +747,33 @@ class Database extends AbstractData
|
||||
*/
|
||||
private static function _getAttachmentType()
|
||||
{
|
||||
return self::$_type === 'pgsql' ? 'TEXT' : 'MEDIUMBLOB';
|
||||
switch (self::$_type) {
|
||||
case 'oci':
|
||||
return 'CLOB';
|
||||
case 'pgsql':
|
||||
return 'TEXT';
|
||||
default:
|
||||
return 'MEDIUMBLOB';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* get the meta type, depending on the database driver
|
||||
*
|
||||
* OCI doesn't accept TEXT so it has to be VARCHAR2(4000)
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @return string
|
||||
*/
|
||||
private static function _getMetaType()
|
||||
{
|
||||
switch (self::$_type) {
|
||||
case 'oci':
|
||||
return 'VARCHAR2(4000)';
|
||||
default:
|
||||
return 'TEXT';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -719,17 +787,18 @@ class Database extends AbstractData
|
||||
list($main_key, $after_key) = self::_getPrimaryKeyClauses();
|
||||
$dataType = self::_getDataType();
|
||||
$attachmentType = self::_getAttachmentType();
|
||||
$metaType = self::_getMetaType();
|
||||
self::$_db->exec(
|
||||
'CREATE TABLE ' . self::_sanitizeIdentifier('paste') . ' ( ' .
|
||||
"dataid CHAR(16) NOT NULL$main_key, " .
|
||||
"data $attachmentType, " .
|
||||
'postdate INT, ' .
|
||||
'expiredate INT, ' .
|
||||
'opendiscussion INT, ' .
|
||||
'burnafterreading INT, ' .
|
||||
'meta TEXT, ' .
|
||||
"attachment $attachmentType, " .
|
||||
"attachmentname $dataType$after_key );"
|
||||
'CREATE TABLE "' . self::_sanitizeIdentifier('paste') . '" ( ' .
|
||||
"\"dataid\" CHAR(16) NOT NULL$main_key, " .
|
||||
"\"data\" $attachmentType, " .
|
||||
'"postdate" INT, ' .
|
||||
'"expiredate" INT, ' .
|
||||
'"opendiscussion" INT, ' .
|
||||
'"burnafterreading" INT, ' .
|
||||
"\"meta\" $metaType, " .
|
||||
"\"attachment\" $attachmentType, " .
|
||||
"\"attachmentname\" $dataType$after_key )"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -744,19 +813,35 @@ class Database extends AbstractData
|
||||
list($main_key, $after_key) = self::_getPrimaryKeyClauses();
|
||||
$dataType = self::_getDataType();
|
||||
self::$_db->exec(
|
||||
'CREATE TABLE ' . self::_sanitizeIdentifier('comment') . ' ( ' .
|
||||
"dataid CHAR(16) NOT NULL$main_key, " .
|
||||
'pasteid CHAR(16), ' .
|
||||
'parentid CHAR(16), ' .
|
||||
"data $dataType, " .
|
||||
"nickname $dataType, " .
|
||||
"vizhash $dataType, " .
|
||||
"postdate INT$after_key );"
|
||||
);
|
||||
self::$_db->exec(
|
||||
'CREATE INDEX IF NOT EXISTS comment_parent ON ' .
|
||||
self::_sanitizeIdentifier('comment') . '(pasteid);'
|
||||
'CREATE TABLE "' . self::_sanitizeIdentifier('comment') . '" ( ' .
|
||||
"\"dataid\" CHAR(16) NOT NULL$main_key, " .
|
||||
'"pasteid" CHAR(16), ' .
|
||||
'"parentid" CHAR(16), ' .
|
||||
"\"data\" $dataType, " .
|
||||
"\"nickname\" $dataType, " .
|
||||
"\"vizhash\" $dataType, " .
|
||||
"\"postdate\" INT$after_key )"
|
||||
);
|
||||
if (self::$_type === 'oci') {
|
||||
self::$_db->exec(
|
||||
'declare
|
||||
already_exists exception;
|
||||
columns_indexed exception;
|
||||
pragma exception_init( already_exists, -955 );
|
||||
pragma exception_init(columns_indexed, -1408);
|
||||
begin
|
||||
execute immediate \'create index "comment_parent" on "' . self::_sanitizeIdentifier('comment') . '" ("pasteid")\';
|
||||
exception
|
||||
when already_exists or columns_indexed then
|
||||
NULL;
|
||||
end;'
|
||||
);
|
||||
} else {
|
||||
self::$_db->exec(
|
||||
'CREATE INDEX IF NOT EXISTS "comment_parent" ON "' .
|
||||
self::_sanitizeIdentifier('comment') . '" ("pasteid")'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -768,17 +853,37 @@ class Database extends AbstractData
|
||||
private static function _createConfigTable()
|
||||
{
|
||||
list($main_key, $after_key) = self::_getPrimaryKeyClauses('id');
|
||||
$charType = self::$_type === 'oci' ? 'VARCHAR2(16)' : 'CHAR(16)';
|
||||
$textType = self::_getMetaType();
|
||||
self::$_db->exec(
|
||||
'CREATE TABLE ' . self::_sanitizeIdentifier('config') .
|
||||
" ( id CHAR(16) NOT NULL$main_key, value TEXT$after_key );"
|
||||
'CREATE TABLE "' . self::_sanitizeIdentifier('config') .
|
||||
"\" ( \"id\" $charType NOT NULL$main_key, \"value\" $textType$after_key )"
|
||||
);
|
||||
self::_exec(
|
||||
'INSERT INTO ' . self::_sanitizeIdentifier('config') .
|
||||
' VALUES(?,?)',
|
||||
'INSERT INTO "' . self::_sanitizeIdentifier('config') .
|
||||
'" VALUES(?,?)',
|
||||
array('VERSION', Controller::VERSION)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* sanitizes CLOB values used with OCI
|
||||
*
|
||||
* From: https://stackoverflow.com/questions/36200534/pdo-oci-into-a-clob-field
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
* @param int|string|resource $value
|
||||
* @return int|string
|
||||
*/
|
||||
public static function _sanitizeClob($value)
|
||||
{
|
||||
if (is_resource($value)) {
|
||||
$value = stream_get_contents($value);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* sanitizes identifiers
|
||||
*
|
||||
@@ -807,43 +912,46 @@ class Database extends AbstractData
|
||||
case '0.21':
|
||||
// create the meta column if necessary (pre 0.21 change)
|
||||
try {
|
||||
self::$_db->exec('SELECT meta FROM ' . self::_sanitizeIdentifier('paste') . ' LIMIT 1;');
|
||||
self::$_db->exec(
|
||||
'SELECT "meta" FROM "' . self::_sanitizeIdentifier('paste') . '" ' .
|
||||
(self::$_type === 'oci' ? 'FETCH NEXT 1 ROWS ONLY' : 'LIMIT 1')
|
||||
);
|
||||
} catch (PDOException $e) {
|
||||
self::$_db->exec('ALTER TABLE ' . self::_sanitizeIdentifier('paste') . ' ADD COLUMN meta TEXT;');
|
||||
self::$_db->exec('ALTER TABLE "' . self::_sanitizeIdentifier('paste') . '" ADD COLUMN "meta" TEXT');
|
||||
}
|
||||
// SQLite only allows one ALTER statement at a time...
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') .
|
||||
" ADD COLUMN attachment $attachmentType;"
|
||||
'ALTER TABLE "' . self::_sanitizeIdentifier('paste') .
|
||||
"\" ADD COLUMN \"attachment\" $attachmentType"
|
||||
);
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') . " ADD COLUMN attachmentname $dataType;"
|
||||
'ALTER TABLE "' . self::_sanitizeIdentifier('paste') . "\" ADD COLUMN \"attachmentname\" $dataType"
|
||||
);
|
||||
// SQLite doesn't support MODIFY, but it allows TEXT of similar
|
||||
// size as BLOB, so there is no need to change it there
|
||||
if (self::$_type !== 'sqlite') {
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') .
|
||||
" ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType;"
|
||||
'ALTER TABLE "' . self::_sanitizeIdentifier('paste') .
|
||||
"\" ADD PRIMARY KEY (\"dataid\"), MODIFY COLUMN \"data\" $dataType"
|
||||
);
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('comment') .
|
||||
" ADD PRIMARY KEY (dataid), MODIFY COLUMN data $dataType, " .
|
||||
"MODIFY COLUMN nickname $dataType, MODIFY COLUMN vizhash $dataType;"
|
||||
'ALTER TABLE "' . self::_sanitizeIdentifier('comment') .
|
||||
"\" ADD PRIMARY KEY (\"dataid\"), MODIFY COLUMN \"data\" $dataType, " .
|
||||
"MODIFY COLUMN \"nickname\" $dataType, MODIFY COLUMN \"vizhash\" $dataType"
|
||||
);
|
||||
} else {
|
||||
self::$_db->exec(
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS paste_dataid ON ' .
|
||||
self::_sanitizeIdentifier('paste') . '(dataid);'
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS "paste_dataid" ON "' .
|
||||
self::_sanitizeIdentifier('paste') . '" ("dataid")'
|
||||
);
|
||||
self::$_db->exec(
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS comment_dataid ON ' .
|
||||
self::_sanitizeIdentifier('comment') . '(dataid);'
|
||||
'CREATE UNIQUE INDEX IF NOT EXISTS "comment_dataid" ON "' .
|
||||
self::_sanitizeIdentifier('comment') . '" ("dataid")'
|
||||
);
|
||||
}
|
||||
self::$_db->exec(
|
||||
'CREATE INDEX IF NOT EXISTS comment_parent ON ' .
|
||||
self::_sanitizeIdentifier('comment') . '(pasteid);'
|
||||
'CREATE INDEX IF NOT EXISTS "comment_parent" ON "' .
|
||||
self::_sanitizeIdentifier('comment') . '" ("pasteid")'
|
||||
);
|
||||
// no break, continue with updates for 0.22 and later
|
||||
case '1.3':
|
||||
@@ -852,15 +960,15 @@ class Database extends AbstractData
|
||||
// to change it there
|
||||
if (self::$_type !== 'sqlite' && self::$_type !== 'pgsql') {
|
||||
self::$_db->exec(
|
||||
'ALTER TABLE ' . self::_sanitizeIdentifier('paste') .
|
||||
" MODIFY COLUMN data $attachmentType;"
|
||||
'ALTER TABLE "' . self::_sanitizeIdentifier('paste') .
|
||||
"\" MODIFY COLUMN \"data\" $attachmentType"
|
||||
);
|
||||
}
|
||||
// no break, continue with updates for all newer versions
|
||||
default:
|
||||
self::_exec(
|
||||
'UPDATE ' . self::_sanitizeIdentifier('config') .
|
||||
' SET value = ? WHERE id = ?',
|
||||
'UPDATE "' . self::_sanitizeIdentifier('config') .
|
||||
'" SET "value" = ? WHERE "id" = ?',
|
||||
array(Controller::VERSION, 'VERSION')
|
||||
);
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ class I18n
|
||||
if (count(self::$_availableLanguages) == 0) {
|
||||
$i18n = dir(self::_getPath());
|
||||
while (false !== ($file = $i18n->read())) {
|
||||
if (preg_match('/^([a-z]{2}).json$/', $file, $match) === 1) {
|
||||
if (preg_match('/^([a-z]{2,3}).json$/', $file, $match) === 1) {
|
||||
self::$_availableLanguages[] = $match[1];
|
||||
}
|
||||
}
|
||||
@@ -324,6 +324,7 @@ class I18n
|
||||
case 'he':
|
||||
return $n === 1 ? 0 : ($n === 2 ? 1 : (($n < 0 || $n > 10) && ($n % 10 === 0) ? 2 : 3));
|
||||
case 'id':
|
||||
case 'jbo':
|
||||
return 0;
|
||||
case 'lt':
|
||||
return $n % 10 === 1 && $n % 100 !== 11 ? 0 : (($n % 10 >= 2 && $n % 100 < 10 || $n % 100 >= 20) ? 1 : 2);
|
||||
|
||||
@@ -41,7 +41,7 @@ if ($SYNTAXHIGHLIGHTING) :
|
||||
endif;
|
||||
?>
|
||||
<noscript><link type="text/css" rel="stylesheet" href="css/noscript.css" /></noscript>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/jquery-3.4.1.js" integrity="sha512-bnIvzh6FU75ZKxp0GXLH9bewza/OIw6dLVh9ICg0gogclmYGguQJWl8U30WpbsGTqbIiAwxTsbe76DErLq5EDQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/jquery-3.6.0.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>
|
||||
<?php
|
||||
if ($QRCODE) :
|
||||
?>
|
||||
@@ -55,7 +55,7 @@ if ($ZEROBINCOMPATIBILITY) :
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.11.js" integrity="sha512-Yey/0yoaVmSbqMEyyff3DIu8kCPwpHvHf7tY1AuZ1lrX9NPCMg87PwzngMi+VNbe4ilCApmePeuKT869RTcyCQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/base-x-3.0.7.js" integrity="sha512-/Bi1AJIP0TtxEB+Jh6Hk809H1G7vn4iJV80qagslf0+Hm0UjUi1s3qNrn1kZULjzUYuaf6ck0ndLGJ7MxWLmgQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/base-x-4.0.0.js" integrity="sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==" 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>
|
||||
<?php
|
||||
@@ -66,13 +66,13 @@ if ($SYNTAXHIGHLIGHTING) :
|
||||
endif;
|
||||
if ($MARKDOWN) :
|
||||
?>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/showdown-1.9.1.js" integrity="sha512-nRri7kqh3iRLdHbhtjfe8w9eAQPmt+ubH5U88UZyKbz6O9Q0q4haaXF0krOUclKmRJou/kKZYulgBHvHXPqOvg==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/showdown-2.0.0.js" integrity="sha512-UB9jpMTOJLSnVzePuqlSGT34G70wEGqtIWabMeAh+Drnj4/uQ8rFkFn1zkN9vkWp/7nA51U2LmP23H5MJvBXsw==" crossorigin="anonymous"></script>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/purify-2.2.7.js" integrity="sha512-7Ka1I/nJuR2CL8wzIS5PJS4HgEMd0HJ6kfAl6fFhwFBB27rhztFbe0tS+Ex+Qg+5n4nZIT4lty4k4Di3+X9T4A==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/purify-2.3.6.js" integrity="sha512-N1GGPjbqLbwK821ZN7C925WuTwU4aDxz2CEEOXQ6/s6m6MBwVj8fh5fugiE2hzsm0xud3q7jpjZQ4ILnpMREYQ==" 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-lJwDAY69TQuYQZ7FjUFPfhgYeZ2L6y5bmGt1hR+d3kMm2sddivGr7ZDdLLSe/CBgn1JrsKMj3th9dPyXN3dLHw==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-PTOcxIWIPWCnb5vC4fmQDMqYGerwsu3AndVyPxn9NlQffIWYMPf/p28Z9SIygXsmcYjmTRmUiW5y7df63mNTfg==" 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" />
|
||||
|
||||
10
tpl/page.php
10
tpl/page.php
@@ -20,7 +20,7 @@ if ($SYNTAXHIGHLIGHTING):
|
||||
endif;
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/jquery-3.4.1.js" integrity="sha512-bnIvzh6FU75ZKxp0GXLH9bewza/OIw6dLVh9ICg0gogclmYGguQJWl8U30WpbsGTqbIiAwxTsbe76DErLq5EDQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/jquery-3.6.0.js" integrity="sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==" crossorigin="anonymous"></script>
|
||||
<?php
|
||||
if ($QRCODE):
|
||||
?>
|
||||
@@ -34,7 +34,7 @@ if ($ZEROBINCOMPATIBILITY):
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/zlib-1.2.11.js" integrity="sha512-Yey/0yoaVmSbqMEyyff3DIu8kCPwpHvHf7tY1AuZ1lrX9NPCMg87PwzngMi+VNbe4ilCApmePeuKT869RTcyCQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/base-x-3.0.7.js" integrity="sha512-/Bi1AJIP0TtxEB+Jh6Hk809H1G7vn4iJV80qagslf0+Hm0UjUi1s3qNrn1kZULjzUYuaf6ck0ndLGJ7MxWLmgQ==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/base-x-4.0.0.js" integrity="sha512-nNPg5IGCwwrveZ8cA/yMGr5HiRS5Ps2H+s0J/mKTPjCPWUgFGGw7M5nqdnPD3VsRwCVysUh3Y8OWjeSKGkEQJQ==" 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
|
||||
if ($SYNTAXHIGHLIGHTING):
|
||||
@@ -44,13 +44,13 @@ if ($SYNTAXHIGHLIGHTING):
|
||||
endif;
|
||||
if ($MARKDOWN):
|
||||
?>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/showdown-1.9.1.js" integrity="sha512-nRri7kqh3iRLdHbhtjfe8w9eAQPmt+ubH5U88UZyKbz6O9Q0q4haaXF0krOUclKmRJou/kKZYulgBHvHXPqOvg==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/showdown-2.0.0.js" integrity="sha512-UB9jpMTOJLSnVzePuqlSGT34G70wEGqtIWabMeAh+Drnj4/uQ8rFkFn1zkN9vkWp/7nA51U2LmP23H5MJvBXsw==" crossorigin="anonymous"></script>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/purify-2.2.7.js" integrity="sha512-7Ka1I/nJuR2CL8wzIS5PJS4HgEMd0HJ6kfAl6fFhwFBB27rhztFbe0tS+Ex+Qg+5n4nZIT4lty4k4Di3+X9T4A==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/purify-2.3.6.js" integrity="sha512-N1GGPjbqLbwK821ZN7C925WuTwU4aDxz2CEEOXQ6/s6m6MBwVj8fh5fugiE2hzsm0xud3q7jpjZQ4ILnpMREYQ==" 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-lJwDAY69TQuYQZ7FjUFPfhgYeZ2L6y5bmGt1hR+d3kMm2sddivGr7ZDdLLSe/CBgn1JrsKMj3th9dPyXN3dLHw==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" data-cfasync="false" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-PTOcxIWIPWCnb5vC4fmQDMqYGerwsu3AndVyPxn9NlQffIWYMPf/p28Z9SIygXsmcYjmTRmUiW5y7df63mNTfg==" 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" />
|
||||
|
||||
@@ -304,7 +304,7 @@ class StorageObjectStub extends StorageObject
|
||||
$this->_generation = $generation;
|
||||
$this->_info = $info;
|
||||
$this->_connection = $connection;
|
||||
$timeCreated = new Datetime();
|
||||
$timeCreated = new DateTime();
|
||||
$this->_info['metadata']['timeCreated'] = $timeCreated->format('Y-m-d\TH:i:s.u\Z');
|
||||
}
|
||||
|
||||
|
||||
@@ -388,4 +388,16 @@ class DatabaseTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(Controller::VERSION, $result['value']);
|
||||
Helper::rmDir($this->_path);
|
||||
}
|
||||
|
||||
public function testOciClob()
|
||||
{
|
||||
$int = (int) random_bytes(1);
|
||||
$string = random_bytes(10);
|
||||
$clob = fopen('php://memory', 'r+');
|
||||
fwrite($clob, $string);
|
||||
rewind($clob);
|
||||
$this->assertEquals($int, Database::_sanitizeClob($int));
|
||||
$this->assertEquals($string, Database::_sanitizeClob($string));
|
||||
$this->assertEquals($string, Database::_sanitizeClob($clob));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ class I18nTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
$_SERVER['HTTP_ACCEPT_LANGUAGE'] = '*';
|
||||
I18n::loadTranslations();
|
||||
$this->assertTrue(strlen(I18n::_('en')) == 2, 'browser language any');
|
||||
$this->assertTrue(strlen(I18n::_('en')) >= 2, 'browser language any');
|
||||
}
|
||||
|
||||
public function testVariableInjection()
|
||||
|
||||
5
vendor/composer/autoload_classmap.php
vendored
5
vendor/composer/autoload_classmap.php
vendored
@@ -12,6 +12,7 @@ return array(
|
||||
'IPLib\\Address\\IPv6' => $vendorDir . '/mlocati/ip-lib/src/Address/IPv6.php',
|
||||
'IPLib\\Address\\Type' => $vendorDir . '/mlocati/ip-lib/src/Address/Type.php',
|
||||
'IPLib\\Factory' => $vendorDir . '/mlocati/ip-lib/src/Factory.php',
|
||||
'IPLib\\ParseStringFlag' => $vendorDir . '/mlocati/ip-lib/src/ParseStringFlag.php',
|
||||
'IPLib\\Range\\AbstractRange' => $vendorDir . '/mlocati/ip-lib/src/Range/AbstractRange.php',
|
||||
'IPLib\\Range\\Pattern' => $vendorDir . '/mlocati/ip-lib/src/Range/Pattern.php',
|
||||
'IPLib\\Range\\RangeInterface' => $vendorDir . '/mlocati/ip-lib/src/Range/RangeInterface.php',
|
||||
@@ -19,7 +20,8 @@ return array(
|
||||
'IPLib\\Range\\Subnet' => $vendorDir . '/mlocati/ip-lib/src/Range/Subnet.php',
|
||||
'IPLib\\Range\\Type' => $vendorDir . '/mlocati/ip-lib/src/Range/Type.php',
|
||||
'IPLib\\Service\\BinaryMath' => $vendorDir . '/mlocati/ip-lib/src/Service/BinaryMath.php',
|
||||
'IPLib\\Service\\RangesFromBounradyCalculator' => $vendorDir . '/mlocati/ip-lib/src/Service/RangesFromBounradyCalculator.php',
|
||||
'IPLib\\Service\\RangesFromBoundaryCalculator' => $vendorDir . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php',
|
||||
'IPLib\\Service\\UnsignedIntegerMath' => $vendorDir . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php',
|
||||
'Identicon\\Generator\\BaseGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php',
|
||||
'Identicon\\Generator\\GdGenerator' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/GdGenerator.php',
|
||||
'Identicon\\Generator\\GeneratorInterface' => $vendorDir . '/yzalis/identicon/src/Identicon/Generator/GeneratorInterface.php',
|
||||
@@ -41,7 +43,6 @@ return array(
|
||||
'PrivateBin\\Model\\Comment' => $baseDir . '/lib/Model/Comment.php',
|
||||
'PrivateBin\\Model\\Paste' => $baseDir . '/lib/Model/Paste.php',
|
||||
'PrivateBin\\Persistence\\AbstractPersistence' => $baseDir . '/lib/Persistence/AbstractPersistence.php',
|
||||
'PrivateBin\\Persistence\\DataStore' => $baseDir . '/lib/Persistence/DataStore.php',
|
||||
'PrivateBin\\Persistence\\PurgeLimiter' => $baseDir . '/lib/Persistence/PurgeLimiter.php',
|
||||
'PrivateBin\\Persistence\\ServerSalt' => $baseDir . '/lib/Persistence/ServerSalt.php',
|
||||
'PrivateBin\\Persistence\\TrafficLimiter' => $baseDir . '/lib/Persistence/TrafficLimiter.php',
|
||||
|
||||
5
vendor/composer/autoload_static.php
vendored
5
vendor/composer/autoload_static.php
vendored
@@ -44,6 +44,7 @@ class ComposerStaticInitDontChange
|
||||
'IPLib\\Address\\IPv6' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/IPv6.php',
|
||||
'IPLib\\Address\\Type' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Address/Type.php',
|
||||
'IPLib\\Factory' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Factory.php',
|
||||
'IPLib\\ParseStringFlag' => __DIR__ . '/..' . '/mlocati/ip-lib/src/ParseStringFlag.php',
|
||||
'IPLib\\Range\\AbstractRange' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/AbstractRange.php',
|
||||
'IPLib\\Range\\Pattern' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Pattern.php',
|
||||
'IPLib\\Range\\RangeInterface' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/RangeInterface.php',
|
||||
@@ -51,7 +52,8 @@ class ComposerStaticInitDontChange
|
||||
'IPLib\\Range\\Subnet' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Subnet.php',
|
||||
'IPLib\\Range\\Type' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Range/Type.php',
|
||||
'IPLib\\Service\\BinaryMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/BinaryMath.php',
|
||||
'IPLib\\Service\\RangesFromBounradyCalculator' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/RangesFromBounradyCalculator.php',
|
||||
'IPLib\\Service\\RangesFromBoundaryCalculator' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/RangesFromBoundaryCalculator.php',
|
||||
'IPLib\\Service\\UnsignedIntegerMath' => __DIR__ . '/..' . '/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php',
|
||||
'Identicon\\Generator\\BaseGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/BaseGenerator.php',
|
||||
'Identicon\\Generator\\GdGenerator' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/GdGenerator.php',
|
||||
'Identicon\\Generator\\GeneratorInterface' => __DIR__ . '/..' . '/yzalis/identicon/src/Identicon/Generator/GeneratorInterface.php',
|
||||
@@ -73,7 +75,6 @@ class ComposerStaticInitDontChange
|
||||
'PrivateBin\\Model\\Comment' => __DIR__ . '/../..' . '/lib/Model/Comment.php',
|
||||
'PrivateBin\\Model\\Paste' => __DIR__ . '/../..' . '/lib/Model/Paste.php',
|
||||
'PrivateBin\\Persistence\\AbstractPersistence' => __DIR__ . '/../..' . '/lib/Persistence/AbstractPersistence.php',
|
||||
'PrivateBin\\Persistence\\DataStore' => __DIR__ . '/../..' . '/lib/Persistence/DataStore.php',
|
||||
'PrivateBin\\Persistence\\PurgeLimiter' => __DIR__ . '/../..' . '/lib/Persistence/PurgeLimiter.php',
|
||||
'PrivateBin\\Persistence\\ServerSalt' => __DIR__ . '/../..' . '/lib/Persistence/ServerSalt.php',
|
||||
'PrivateBin\\Persistence\\TrafficLimiter' => __DIR__ . '/../..' . '/lib/Persistence/TrafficLimiter.php',
|
||||
|
||||
@@ -21,6 +21,8 @@ interface AddressInterface
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.14.0
|
||||
*
|
||||
* @example 32 for IPv4
|
||||
* @example 128 for IPv6
|
||||
*/
|
||||
@@ -51,6 +53,8 @@ interface AddressInterface
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.14.0
|
||||
*
|
||||
* @example For localhost: For IPv4 you'll get '01111111000000000000000000000001' (32 digits), for IPv6 '00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001' (128 digits)
|
||||
*/
|
||||
public function getBits();
|
||||
@@ -66,6 +70,8 @@ interface AddressInterface
|
||||
* Get the default RFC reserved range type.
|
||||
*
|
||||
* @return int One of the \IPLib\Range\Type::T_... constants
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static function getDefaultReservedRangeType();
|
||||
|
||||
@@ -73,6 +79,8 @@ interface AddressInterface
|
||||
* Get the RFC reserved ranges (except the ones of type getDefaultReservedRangeType).
|
||||
*
|
||||
* @return \IPLib\Address\AssignedRange[] ranges are sorted
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static function getReservedRanges();
|
||||
|
||||
@@ -99,10 +107,28 @@ interface AddressInterface
|
||||
*/
|
||||
public function matches(RangeInterface $range);
|
||||
|
||||
/**
|
||||
* Get the address at a certain distance from this address.
|
||||
*
|
||||
* @param int $n the distance of the address (can be negative)
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or if the final address would be invalid
|
||||
*
|
||||
* @since 1.15.0
|
||||
*
|
||||
* @example passing 1 to the address 127.0.0.1 will result in 127.0.0.2
|
||||
* @example passing -1 to the address 127.0.0.1 will result in 127.0.0.0
|
||||
* @example passing -1 to the address 0.0.0.0 will result in NULL
|
||||
*/
|
||||
public function getAddressAtOffset($n);
|
||||
|
||||
/**
|
||||
* Get the address right after this IP address (if available).
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
*
|
||||
* @see \IPLib\Address\AddressInterface::getAddressAtOffset()
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public function getNextAddress();
|
||||
|
||||
@@ -110,6 +136,9 @@ interface AddressInterface
|
||||
* Get the address right before this IP address (if available).
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
*
|
||||
* @see \IPLib\Address\AddressInterface::getAddressAtOffset()
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public function getPreviousAddress();
|
||||
|
||||
@@ -118,6 +147,8 @@ interface AddressInterface
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.12.0
|
||||
*
|
||||
* @example for IPv4 it returns something like x.x.x.x.in-addr.arpa
|
||||
* @example for IPv6 it returns something like x.x.x.x..x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.ip6.arpa
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,8 @@ use IPLib\Range\RangeInterface;
|
||||
|
||||
/**
|
||||
* Represents an IP address range with an assigned range type.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class AssignedRange
|
||||
{
|
||||
|
||||
178
vendor/mlocati/ip-lib/src/Address/IPv4.php
vendored
178
vendor/mlocati/ip-lib/src/Address/IPv4.php
vendored
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace IPLib\Address;
|
||||
|
||||
use IPLib\ParseStringFlag;
|
||||
use IPLib\Range\RangeInterface;
|
||||
use IPLib\Range\Subnet;
|
||||
use IPLib\Range\Type as RangeType;
|
||||
@@ -46,7 +47,7 @@ class IPv4 implements AddressInterface
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
private static $reservedRanges = null;
|
||||
private static $reservedRanges;
|
||||
|
||||
/**
|
||||
* Initializes the instance.
|
||||
@@ -82,52 +83,94 @@ class IPv4 implements AddressInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and returns an IPv4 instance if the string is valid, or null otherwise.
|
||||
* @deprecated since 1.17.0: use the parseString() method instead.
|
||||
* For upgrading:
|
||||
* - if $mayIncludePort is true, use the ParseStringFlag::MAY_INCLUDE_PORT flag
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string|mixed $address the address to parse
|
||||
* @param bool $mayIncludePort set to false to avoid parsing addresses with ports
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param bool $mayIncludePort
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\Address\IPv4::parseString()
|
||||
* @since 1.1.0 added the $mayIncludePort argument
|
||||
* @since 1.10.0 added the $supportNonDecimalIPv4 argument
|
||||
*/
|
||||
public static function fromString($address, $mayIncludePort = true, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
if (!is_string($address) || !strpos($address, '.')) {
|
||||
return static::parseString($address, 0 | ($mayIncludePort ? ParseStringFlag::MAY_INCLUDE_PORT : 0) | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and returns an IPv4 instance if the string is valid, or null otherwise.
|
||||
*
|
||||
* @param string|mixed $address the address to parse
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function parseString($address, $flags = 0)
|
||||
{
|
||||
if (!is_string($address)) {
|
||||
return null;
|
||||
}
|
||||
$rxChunk = '0?[0-9]{1,3}';
|
||||
if ($supportNonDecimalIPv4) {
|
||||
$rxChunk = "(?:0[Xx]0*[0-9A-Fa-f]{1,2})|(?:{$rxChunk})";
|
||||
$flags = (int) $flags;
|
||||
$matches = null;
|
||||
if ($flags & ParseStringFlag::ADDRESS_MAYBE_RDNS) {
|
||||
if (preg_match('/^([12]?[0-9]{1,2}\.[12]?[0-9]{1,2}\.[12]?[0-9]{1,2}\.[12]?[0-9]{1,2})\.in-addr\.arpa\.?$/i', $address, $matches)) {
|
||||
$address = implode('.', array_reverse(explode('.', $matches[1])));
|
||||
$flags = $flags & ~(ParseStringFlag::IPV4_MAYBE_NON_DECIMAL | ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED);
|
||||
}
|
||||
}
|
||||
$rx = "0*?({$rxChunk})\.0*?({$rxChunk})\.0*?({$rxChunk})\.0*?({$rxChunk})";
|
||||
if ($mayIncludePort) {
|
||||
if ($flags & ParseStringFlag::IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED) {
|
||||
if (strpos($address, '.') === 0) {
|
||||
return null;
|
||||
}
|
||||
$lengthNonHex = '{1,11}';
|
||||
$lengthHex = '{1,8}';
|
||||
$chunk234Optional = true;
|
||||
} else {
|
||||
if (!strpos($address, '.')) {
|
||||
return null;
|
||||
}
|
||||
$lengthNonHex = '{1,3}';
|
||||
$lengthHex = '{1,2}';
|
||||
$chunk234Optional = false;
|
||||
}
|
||||
$rxChunk1 = "0?[0-9]{$lengthNonHex}";
|
||||
if ($flags & ParseStringFlag::IPV4_MAYBE_NON_DECIMAL) {
|
||||
$rxChunk1 = "(?:0[Xx]0*[0-9A-Fa-f]{$lengthHex})|(?:{$rxChunk1})";
|
||||
$onlyDecimal = false;
|
||||
} else {
|
||||
$onlyDecimal = true;
|
||||
}
|
||||
$rxChunk1 = "0*?({$rxChunk1})";
|
||||
$rxChunk234 = "\.{$rxChunk1}";
|
||||
if ($chunk234Optional) {
|
||||
$rxChunk234 = "(?:{$rxChunk234})?";
|
||||
}
|
||||
$rx = "{$rxChunk1}{$rxChunk234}{$rxChunk234}{$rxChunk234}";
|
||||
if ($flags & ParseStringFlag::MAY_INCLUDE_PORT) {
|
||||
$rx .= '(?::\d+)?';
|
||||
}
|
||||
$matches = null;
|
||||
if (!preg_match('/^' . $rx . '$/', $address, $matches)) {
|
||||
return null;
|
||||
}
|
||||
$math = new \IPLib\Service\UnsignedIntegerMath();
|
||||
$nums = array();
|
||||
for ($i = 1; $i <= 4; $i++) {
|
||||
$s = $matches[$i];
|
||||
if ($supportNonDecimalIPv4) {
|
||||
if (stripos($s, '0x') === 0) {
|
||||
$n = hexdec(substr($s, 2));
|
||||
} elseif ($s[0] === '0') {
|
||||
if (!preg_match('/^[0-7]+$/', $s)) {
|
||||
return null;
|
||||
}
|
||||
$n = octdec(substr($s, 1));
|
||||
} else {
|
||||
$n = (int) $s;
|
||||
}
|
||||
} else {
|
||||
$n = (int) $s;
|
||||
}
|
||||
if ($n < 0 || $n > 255) {
|
||||
$maxChunkIndex = count($matches) - 1;
|
||||
for ($i = 1; $i <= $maxChunkIndex; $i++) {
|
||||
$numBytes = $i === $maxChunkIndex ? 5 - $i : 1;
|
||||
$chunkBytes = $math->getBytes($matches[$i], $numBytes, $onlyDecimal);
|
||||
if ($chunkBytes === null) {
|
||||
return null;
|
||||
}
|
||||
$nums[] = (string) $n;
|
||||
$nums = array_merge($nums, $chunkBytes);
|
||||
}
|
||||
|
||||
return new static(implode('.', $nums));
|
||||
@@ -179,6 +222,8 @@ class IPv4 implements AddressInterface
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.10.0
|
||||
*
|
||||
* @example if $long == false: if the decimal representation is '0.7.8.255': '0.7.010.0377'
|
||||
* @example if $long == true: if the decimal representation is '0.7.8.255': '0000.0007.0010.0377'
|
||||
*/
|
||||
@@ -203,6 +248,8 @@ class IPv4 implements AddressInterface
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.10.0
|
||||
*
|
||||
* @example if $long == false: if the decimal representation is '0.9.10.255': '0.9.0xa.0xff'
|
||||
* @example if $long == true: if the decimal representation is '0.9.10.255': '0x00.0x09.0x0a.0xff'
|
||||
*/
|
||||
@@ -318,10 +365,10 @@ class IPv4 implements AddressInterface
|
||||
$exceptions = array();
|
||||
if (isset($data[1])) {
|
||||
foreach ($data[1] as $exceptionRange => $exceptionType) {
|
||||
$exceptions[] = new AssignedRange(Subnet::fromString($exceptionRange), $exceptionType);
|
||||
$exceptions[] = new AssignedRange(Subnet::parseString($exceptionRange), $exceptionType);
|
||||
}
|
||||
}
|
||||
$reservedRanges[] = new AssignedRange(Subnet::fromString($range), $data[0], $exceptions);
|
||||
$reservedRanges[] = new AssignedRange(Subnet::parseString($range), $data[0], $exceptions);
|
||||
}
|
||||
self::$reservedRanges = $reservedRanges;
|
||||
}
|
||||
@@ -359,13 +406,15 @@ class IPv4 implements AddressInterface
|
||||
{
|
||||
$myBytes = $this->getBytes();
|
||||
|
||||
return IPv6::fromString('2002:' . sprintf('%02x', $myBytes[0]) . sprintf('%02x', $myBytes[1]) . ':' . sprintf('%02x', $myBytes[2]) . sprintf('%02x', $myBytes[3]) . '::');
|
||||
return IPv6::parseString('2002:' . sprintf('%02x', $myBytes[0]) . sprintf('%02x', $myBytes[1]) . ':' . sprintf('%02x', $myBytes[2]) . sprintf('%02x', $myBytes[3]) . '::');
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an IPv6 representation of this address (in IPv6 IPv4-mapped notation).
|
||||
*
|
||||
* @return \IPLib\Address\IPv6
|
||||
*
|
||||
* @since 1.11.0
|
||||
*/
|
||||
public function toIPv6IPv4Mapped()
|
||||
{
|
||||
@@ -400,6 +449,37 @@ class IPv4 implements AddressInterface
|
||||
return $range->contains($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Address\AddressInterface::getAddressAtOffset()
|
||||
*/
|
||||
public function getAddressAtOffset($n)
|
||||
{
|
||||
if (!is_int($n)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$boundary = 256;
|
||||
$mod = $n;
|
||||
$bytes = $this->getBytes();
|
||||
for ($i = count($bytes) - 1; $i >= 0; $i--) {
|
||||
$tmp = ($bytes[$i] + $mod) % $boundary;
|
||||
$mod = (int) floor(($bytes[$i] + $mod) / $boundary);
|
||||
if ($tmp < 0) {
|
||||
$tmp += $boundary;
|
||||
}
|
||||
|
||||
$bytes[$i] = $tmp;
|
||||
}
|
||||
|
||||
if ($mod !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return static::fromBytes($bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
@@ -407,22 +487,7 @@ class IPv4 implements AddressInterface
|
||||
*/
|
||||
public function getNextAddress()
|
||||
{
|
||||
$overflow = false;
|
||||
$bytes = $this->getBytes();
|
||||
for ($i = count($bytes) - 1; $i >= 0; $i--) {
|
||||
if ($bytes[$i] === 255) {
|
||||
if ($i === 0) {
|
||||
$overflow = true;
|
||||
break;
|
||||
}
|
||||
$bytes[$i] = 0;
|
||||
} else {
|
||||
$bytes[$i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $overflow ? null : static::fromBytes($bytes);
|
||||
return $this->getAddressAtOffset(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -432,22 +497,7 @@ class IPv4 implements AddressInterface
|
||||
*/
|
||||
public function getPreviousAddress()
|
||||
{
|
||||
$overflow = false;
|
||||
$bytes = $this->getBytes();
|
||||
for ($i = count($bytes) - 1; $i >= 0; $i--) {
|
||||
if ($bytes[$i] === 0) {
|
||||
if ($i === 0) {
|
||||
$overflow = true;
|
||||
break;
|
||||
}
|
||||
$bytes[$i] = 255;
|
||||
} else {
|
||||
$bytes[$i]--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $overflow ? null : static::fromBytes($bytes);
|
||||
return $this->getAddressAtOffset(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
128
vendor/mlocati/ip-lib/src/Address/IPv6.php
vendored
128
vendor/mlocati/ip-lib/src/Address/IPv6.php
vendored
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace IPLib\Address;
|
||||
|
||||
use IPLib\ParseStringFlag;
|
||||
use IPLib\Range\RangeInterface;
|
||||
use IPLib\Range\Subnet;
|
||||
use IPLib\Range\Type as RangeType;
|
||||
@@ -55,7 +56,7 @@ class IPv6 implements AddressInterface
|
||||
*
|
||||
* @var array|null
|
||||
*/
|
||||
private static $reservedRanges = null;
|
||||
private static $reservedRanges;
|
||||
|
||||
/**
|
||||
* Initializes the instance.
|
||||
@@ -92,32 +93,69 @@ class IPv6 implements AddressInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and returns an IPv6 instance if the string is valid, or null otherwise.
|
||||
* @deprecated since 1.17.0: use the parseString() method instead.
|
||||
* For upgrading:
|
||||
* - if $mayIncludePort is true, use the ParseStringFlag::MAY_INCLUDE_PORT flag
|
||||
* - if $mayIncludeZoneID is true, use the ParseStringFlag::MAY_INCLUDE_ZONEID flag
|
||||
*
|
||||
* @param string|mixed $address the address to parse
|
||||
* @param bool $mayIncludePort set to false to avoid parsing addresses with ports
|
||||
* @param bool $mayIncludeZoneID set to false to avoid parsing addresses with zone IDs (see RFC 4007)
|
||||
* @param string|mixed $address
|
||||
* @param bool $mayIncludePort
|
||||
* @param bool $mayIncludeZoneID
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\Address\IPv6::parseString()
|
||||
* @since 1.1.0 added the $mayIncludePort argument
|
||||
* @since 1.3.0 added the $mayIncludeZoneID argument
|
||||
*/
|
||||
public static function fromString($address, $mayIncludePort = true, $mayIncludeZoneID = true)
|
||||
{
|
||||
return static::parseString($address, 0 | ($mayIncludePort ? ParseStringFlag::MAY_INCLUDE_PORT : 0) | ($mayIncludeZoneID ? ParseStringFlag::MAY_INCLUDE_ZONEID : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a string and returns an IPv6 instance if the string is valid, or null otherwise.
|
||||
*
|
||||
* @param string|mixed $address the address to parse
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function parseString($address, $flags = 0)
|
||||
{
|
||||
if (!is_string($address)) {
|
||||
return null;
|
||||
}
|
||||
$matches = null;
|
||||
$flags = (int) $flags;
|
||||
if ($flags & ParseStringFlag::ADDRESS_MAYBE_RDNS) {
|
||||
if (preg_match('/^([0-9a-f](?:\.[0-9a-f]){31})\.ip6\.arpa\.?/i', $address, $matches)) {
|
||||
$nibbles = array_reverse(explode('.', $matches[1]));
|
||||
$quibbles = array();
|
||||
foreach (array_chunk($nibbles, 4) as $n) {
|
||||
$quibbles[] = implode('', $n);
|
||||
}
|
||||
$address = implode(':', $quibbles);
|
||||
}
|
||||
}
|
||||
$result = null;
|
||||
if (is_string($address) && strpos($address, ':') !== false && strpos($address, ':::') === false) {
|
||||
$matches = null;
|
||||
if ($mayIncludePort && $address[0] === '[' && preg_match('/^\[(.+)]:\d+$/', $address, $matches)) {
|
||||
if ($flags & ParseStringFlag::MAY_INCLUDE_PORT && $address[0] === '[' && preg_match('/^\[(.+)]:\d+$/', $address, $matches)) {
|
||||
$address = $matches[1];
|
||||
}
|
||||
if ($mayIncludeZoneID) {
|
||||
if ($flags & ParseStringFlag::MAY_INCLUDE_ZONEID) {
|
||||
$percentagePos = strpos($address, '%');
|
||||
if ($percentagePos > 0) {
|
||||
$address = substr($address, 0, $percentagePos);
|
||||
}
|
||||
}
|
||||
if (preg_match('/^((?:[0-9a-f]*:+)+)(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/i', $address, $matches)) {
|
||||
$address6 = static::fromString($matches[1] . '0:0', false);
|
||||
$address6 = static::parseString($matches[1] . '0:0');
|
||||
if ($address6 !== null) {
|
||||
$address4 = IPv4::fromString($matches[2], false);
|
||||
$address4 = IPv4::parseString($matches[2]);
|
||||
if ($address4 !== null) {
|
||||
$bytes4 = $address4->getBytes();
|
||||
$address6->longAddress = substr($address6->longAddress, 0, -9) . sprintf('%02x%02x:%02x%02x', $bytes4[0], $bytes4[1], $bytes4[2], $bytes4[3]);
|
||||
@@ -401,10 +439,10 @@ class IPv6 implements AddressInterface
|
||||
$exceptions = array();
|
||||
if (isset($data[1])) {
|
||||
foreach ($data[1] as $exceptionRange => $exceptionType) {
|
||||
$exceptions[] = new AssignedRange(Subnet::fromString($exceptionRange), $exceptionType);
|
||||
$exceptions[] = new AssignedRange(Subnet::parseString($exceptionRange), $exceptionType);
|
||||
}
|
||||
}
|
||||
$reservedRanges[] = new AssignedRange(Subnet::fromString($range), $data[0], $exceptions);
|
||||
$reservedRanges[] = new AssignedRange(Subnet::parseString($range), $data[0], $exceptions);
|
||||
}
|
||||
self::$reservedRanges = $reservedRanges;
|
||||
}
|
||||
@@ -471,6 +509,7 @@ class IPv6 implements AddressInterface
|
||||
* @example '0000:0000:0000:0000:0000:0000:013.001.068.003' when $ipV6Long and $ipV4Long are true
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc4291#section-2.2 point 3.
|
||||
* @since 1.9.0
|
||||
*/
|
||||
public function toMixedIPv6IPv4String($ipV6Long = false, $ipV4Long = false)
|
||||
{
|
||||
@@ -503,6 +542,37 @@ class IPv6 implements AddressInterface
|
||||
return $range->contains($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Address\AddressInterface::getAddressAtOffset()
|
||||
*/
|
||||
public function getAddressAtOffset($n)
|
||||
{
|
||||
if (!is_int($n)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$boundary = 0x10000;
|
||||
$mod = $n;
|
||||
$words = $this->getWords();
|
||||
for ($i = count($words) - 1; $i >= 0; $i--) {
|
||||
$tmp = ($words[$i] + $mod) % $boundary;
|
||||
$mod = (int) floor(($words[$i] + $mod) / $boundary);
|
||||
if ($tmp < 0) {
|
||||
$tmp += $boundary;
|
||||
}
|
||||
|
||||
$words[$i] = $tmp;
|
||||
}
|
||||
|
||||
if ($mod !== 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return static::fromWords($words);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
@@ -510,22 +580,7 @@ class IPv6 implements AddressInterface
|
||||
*/
|
||||
public function getNextAddress()
|
||||
{
|
||||
$overflow = false;
|
||||
$words = $this->getWords();
|
||||
for ($i = count($words) - 1; $i >= 0; $i--) {
|
||||
if ($words[$i] === 0xffff) {
|
||||
if ($i === 0) {
|
||||
$overflow = true;
|
||||
break;
|
||||
}
|
||||
$words[$i] = 0;
|
||||
} else {
|
||||
$words[$i]++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $overflow ? null : static::fromWords($words);
|
||||
return $this->getAddressAtOffset(1);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -535,22 +590,7 @@ class IPv6 implements AddressInterface
|
||||
*/
|
||||
public function getPreviousAddress()
|
||||
{
|
||||
$overflow = false;
|
||||
$words = $this->getWords();
|
||||
for ($i = count($words) - 1; $i >= 0; $i--) {
|
||||
if ($words[$i] === 0) {
|
||||
if ($i === 0) {
|
||||
$overflow = true;
|
||||
break;
|
||||
}
|
||||
$words[$i] = 0xffff;
|
||||
} else {
|
||||
$words[$i]--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return $overflow ? null : static::fromWords($words);
|
||||
return $this->getAddressAtOffset(-1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
2
vendor/mlocati/ip-lib/src/Address/Type.php
vendored
2
vendor/mlocati/ip-lib/src/Address/Type.php
vendored
@@ -27,6 +27,8 @@ class Type
|
||||
* @param int $type
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @since 1.1.0
|
||||
*/
|
||||
public static function getName($type)
|
||||
{
|
||||
|
||||
149
vendor/mlocati/ip-lib/src/Factory.php
vendored
149
vendor/mlocati/ip-lib/src/Factory.php
vendored
@@ -4,7 +4,7 @@ namespace IPLib;
|
||||
|
||||
use IPLib\Address\AddressInterface;
|
||||
use IPLib\Range\Subnet;
|
||||
use IPLib\Service\RangesFromBounradyCalculator;
|
||||
use IPLib\Service\RangesFromBoundaryCalculator;
|
||||
|
||||
/**
|
||||
* Factory methods to build class instances.
|
||||
@@ -12,23 +12,48 @@ use IPLib\Service\RangesFromBounradyCalculator;
|
||||
class Factory
|
||||
{
|
||||
/**
|
||||
* Parse an IP address string.
|
||||
* @deprecated since 1.17.0: use the parseAddressString() method instead.
|
||||
* For upgrading:
|
||||
* - if $mayIncludePort is true, use the ParseStringFlag::MAY_INCLUDE_PORT flag
|
||||
* - if $mayIncludeZoneID is true, use the ParseStringFlag::MAY_INCLUDE_ZONEID flag
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string $address the address to parse
|
||||
* @param bool $mayIncludePort set to false to avoid parsing addresses with ports
|
||||
* @param bool $mayIncludeZoneID set to false to avoid parsing IPv6 addresses with zone IDs (see RFC 4007)
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param string|mixed $address
|
||||
* @param bool $mayIncludePort
|
||||
* @param bool $mayIncludeZoneID
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
*
|
||||
* @see \IPLib\Factory::parseAddressString()
|
||||
* @since 1.1.0 added the $mayIncludePort argument
|
||||
* @since 1.3.0 added the $mayIncludeZoneID argument
|
||||
* @since 1.10.0 added the $supportNonDecimalIPv4 argument
|
||||
*/
|
||||
public static function addressFromString($address, $mayIncludePort = true, $mayIncludeZoneID = true, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
return static::parseAddressString($address, 0 + ($mayIncludePort ? ParseStringFlag::MAY_INCLUDE_PORT : 0) + ($mayIncludeZoneID ? ParseStringFlag::MAY_INCLUDE_ZONEID : 0) + ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an IP address string.
|
||||
*
|
||||
* @param string|mixed $address the address to parse
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function parseAddressString($address, $flags = 0)
|
||||
{
|
||||
$result = null;
|
||||
if ($result === null) {
|
||||
$result = Address\IPv4::fromString($address, $mayIncludePort, $supportNonDecimalIPv4);
|
||||
$result = Address\IPv4::parseString($address, $flags);
|
||||
}
|
||||
if ($result === null) {
|
||||
$result = Address\IPv6::fromString($address, $mayIncludePort, $mayIncludeZoneID);
|
||||
$result = Address\IPv6::parseString($address, $flags);
|
||||
}
|
||||
|
||||
return $result;
|
||||
@@ -54,59 +79,125 @@ class Factory
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.17.0: use the parseRangeString() method instead.
|
||||
* For upgrading:
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string|mixed $address
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
*
|
||||
* @see \IPLib\Factory::parseRangeString()
|
||||
* @since 1.10.0 added the $supportNonDecimalIPv4 argument
|
||||
*/
|
||||
public static function rangeFromString($address, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
return static::parseRangeString($address, $supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an IP range string.
|
||||
*
|
||||
* @param string $range
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return \IPLib\Range\RangeInterface|null
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function rangeFromString($range, $supportNonDecimalIPv4 = false)
|
||||
public static function parseRangeString($range, $flags = 0)
|
||||
{
|
||||
$result = null;
|
||||
if ($result === null) {
|
||||
$result = Range\Subnet::fromString($range, $supportNonDecimalIPv4);
|
||||
$result = Range\Subnet::parseString($range, $flags);
|
||||
}
|
||||
if ($result === null) {
|
||||
$result = Range\Pattern::fromString($range, $supportNonDecimalIPv4);
|
||||
$result = Range\Pattern::parseString($range, $flags);
|
||||
}
|
||||
if ($result === null) {
|
||||
$result = Range\Single::fromString($range, $supportNonDecimalIPv4);
|
||||
$result = Range\Single::parseString($range, $flags);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the smallest address range that comprises two addresses.
|
||||
* @deprecated since 1.17.0: use the getRangeFromBoundaries() method instead.
|
||||
* For upgrading:
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string|\IPLib\Address\AddressInterface $from
|
||||
* @param string|\IPLib\Address\AddressInterface $to
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param string|\IPLib\Address\AddressInterface|mixed $from
|
||||
* @param string|\IPLib\Address\AddressInterface|mixed $to
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return \IPLib\Range\RangeInterface|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types
|
||||
* @return \IPLib\Address\AddressInterface|null
|
||||
*
|
||||
* @see \IPLib\Factory::getRangeFromBoundaries()
|
||||
* @since 1.2.0
|
||||
* @since 1.10.0 added the $supportNonDecimalIPv4 argument
|
||||
*/
|
||||
public static function rangeFromBoundaries($from, $to, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
list($from, $to) = self::parseBoundaries($from, $to, $supportNonDecimalIPv4);
|
||||
return static::getRangeFromBoundaries($from, $to, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the smallest address range that comprises two addresses.
|
||||
*
|
||||
* @param string|\IPLib\Address\AddressInterface|mixed $from
|
||||
* @param string|\IPLib\Address\AddressInterface|mixed $to
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return \IPLib\Range\RangeInterface|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function getRangeFromBoundaries($from, $to, $flags = 0)
|
||||
{
|
||||
list($from, $to) = self::parseBoundaries($from, $to, $flags);
|
||||
|
||||
return $from === false || $to === false ? null : static::rangeFromBoundaryAddresses($from, $to);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.17.0: use the getRangesFromBoundaries() method instead.
|
||||
* For upgrading:
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string|\IPLib\Address\AddressInterface|mixed $from
|
||||
* @param string|\IPLib\Address\AddressInterface|mixed $to
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return \IPLib\Range\Subnet[]|null
|
||||
*
|
||||
* @see \IPLib\Factory::getRangesFromBoundaries()
|
||||
* @since 1.14.0
|
||||
*/
|
||||
public static function rangesFromBoundaries($from, $to, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
return static::getRangesFromBoundaries($from, $to, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a list of Range instances that exactly describes all the addresses between the two provided addresses.
|
||||
*
|
||||
* @param string|\IPLib\Address\AddressInterface $from
|
||||
* @param string|\IPLib\Address\AddressInterface $to
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return \IPLib\Range\Subnet[]|null return NULL if $from and/or $to are invalid addresses, or if both are NULL or empty strings, or if they are addresses of different types
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function rangesFromBoundaries($from, $to, $supportNonDecimalIPv4 = false)
|
||||
public static function getRangesFromBoundaries($from, $to, $flags = 0)
|
||||
{
|
||||
list($from, $to) = self::parseBoundaries($from, $to, $supportNonDecimalIPv4);
|
||||
if (($from === false || $to === false) || ($from === null && $to === null)) {
|
||||
list($from, $to) = self::parseBoundaries($from, $to, $flags);
|
||||
if ($from === false || $to === false || ($from === null && $to === null)) {
|
||||
return null;
|
||||
}
|
||||
if ($from === null || $to === null) {
|
||||
@@ -118,7 +209,7 @@ class Factory
|
||||
if ($to->getNumberOfBits() !== $numberOfBits) {
|
||||
return null;
|
||||
}
|
||||
$calculator = new RangesFromBounradyCalculator($numberOfBits);
|
||||
$calculator = new RangesFromBoundaryCalculator($numberOfBits);
|
||||
|
||||
return $calculator->getRanges($from, $to);
|
||||
}
|
||||
@@ -128,6 +219,8 @@ class Factory
|
||||
* @param \IPLib\Address\AddressInterface $to
|
||||
*
|
||||
* @return \IPLib\Range\RangeInterface|null
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
protected static function rangeFromBoundaryAddresses(AddressInterface $from = null, AddressInterface $to = null)
|
||||
{
|
||||
@@ -163,7 +256,7 @@ class Factory
|
||||
break;
|
||||
}
|
||||
}
|
||||
$result = static::rangeFromString($from->toString(true) . '/' . (string) $sameBits);
|
||||
$result = static::parseRangeString($from->toString() . '/' . (string) $sameBits);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,11 +267,11 @@ class Factory
|
||||
/**
|
||||
* @param string|\IPLib\Address\AddressInterface $from
|
||||
* @param string|\IPLib\Address\AddressInterface $to
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
* @param int $flags
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface[]|null[]|false[]
|
||||
*/
|
||||
private static function parseBoundaries($from, $to, $supportNonDecimalIPv4 = false)
|
||||
private static function parseBoundaries($from, $to, $flags = 0)
|
||||
{
|
||||
$result = array();
|
||||
foreach (array('from', 'to') as $param) {
|
||||
@@ -188,7 +281,7 @@ class Factory
|
||||
if ($value === '') {
|
||||
$value = null;
|
||||
} else {
|
||||
$value = static::addressFromString($value, true, true, $supportNonDecimalIPv4);
|
||||
$value = static::parseAddressString($value, $flags);
|
||||
if ($value === null) {
|
||||
$value = false;
|
||||
}
|
||||
|
||||
79
vendor/mlocati/ip-lib/src/ParseStringFlag.php
vendored
Normal file
79
vendor/mlocati/ip-lib/src/ParseStringFlag.php
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace IPLib;
|
||||
|
||||
/**
|
||||
* Flags for the parseString() methods.
|
||||
*
|
||||
* @since 1.17.0
|
||||
*/
|
||||
class ParseStringFlag
|
||||
{
|
||||
/**
|
||||
* Use this flag if the input string may include the port.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MAY_INCLUDE_PORT = 1;
|
||||
|
||||
/**
|
||||
* Use this flag if the input string may include a zone ID.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MAY_INCLUDE_ZONEID = 2;
|
||||
|
||||
/**
|
||||
* Use this flag if IPv4 addresses may be in decimal/octal/hexadecimal format.
|
||||
* This notation is accepted by the implementation of inet_aton and inet_addr of the libc implementation of GNU, Windows and Mac (but not Musl), but not by inet_pton and ip2long.
|
||||
*
|
||||
* @var int
|
||||
*
|
||||
* @example 1.08.0x10.0 => 5.0.0.1
|
||||
* @example 5.256 => 5.0.1.0
|
||||
* @example 5.0.256 => 5.0.1.0
|
||||
* @example 123456789 => 7.91.205.21
|
||||
*/
|
||||
const IPV4_MAYBE_NON_DECIMAL = 4;
|
||||
|
||||
/**
|
||||
* Use this flag if IPv4 subnet ranges may be in compact form.
|
||||
*
|
||||
* @example 127/24 => 127.0.0.0/24
|
||||
* @example 10/8 => 10.0.0.0/8
|
||||
* @example 10/24 => 10.0.0.0/24
|
||||
* @example 10.10.10/24 => 10.10.10.0/24
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const IPV4SUBNET_MAYBE_COMPACT = 8;
|
||||
|
||||
/**
|
||||
* Use this flag if IPv4 addresses may be in non quad-dotted notation.
|
||||
* This notation is accepted by the implementation of inet_aton and inet_addr of the libc implementation of GNU, Windows and Mac (but not Musl), but not by inet_pton and ip2long.
|
||||
*
|
||||
* @var int
|
||||
*
|
||||
* @example 5.1 => 5.0.0.1
|
||||
* @example 5.256 => 5.0.1.0
|
||||
* @example 5.0.256 => 5.0.1.0
|
||||
* @example 123456789 => 7.91.205.21
|
||||
*
|
||||
* @see https://man7.org/linux/man-pages/man3/inet_addr.3.html#DESCRIPTION
|
||||
* @see https://www.freebsd.org/cgi/man.cgi?query=inet_net&sektion=3&apropos=0&manpath=FreeBSD+12.2-RELEASE+and+Ports#end
|
||||
* @see http://git.musl-libc.org/cgit/musl/tree/src/network/inet_aton.c?h=v1.2.2
|
||||
*/
|
||||
const IPV4ADDRESS_MAYBE_NON_QUAD_DOTTED = 16;
|
||||
|
||||
/**
|
||||
* Use this flag if you want to accept parsing IPv4/IPv6 addresses in Reverse DNS Lookup Address format.
|
||||
*
|
||||
* @var int
|
||||
*
|
||||
* @since 1.18.0
|
||||
*
|
||||
* @example 140.13.12.10.in-addr.arpa => 10.12.13.140
|
||||
* @example b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.4.ip6.arpa => 4321:0:1:2:3:4:567:89ab
|
||||
*/
|
||||
const ADDRESS_MAYBE_RDNS = 32;
|
||||
}
|
||||
@@ -8,6 +8,9 @@ use IPLib\Address\IPv6;
|
||||
use IPLib\Address\Type as AddressType;
|
||||
use IPLib\Factory;
|
||||
|
||||
/**
|
||||
* Base class for range classes.
|
||||
*/
|
||||
abstract class AbstractRange implements RangeInterface
|
||||
{
|
||||
/**
|
||||
@@ -20,7 +23,7 @@ abstract class AbstractRange implements RangeInterface
|
||||
if ($this->rangeType === null) {
|
||||
$addressType = $this->getAddressType();
|
||||
if ($addressType === AddressType::T_IPv6 && Subnet::get6to4()->containsRange($this)) {
|
||||
$this->rangeType = Factory::rangeFromBoundaries($this->fromAddress->toIPv4(), $this->toAddress->toIPv4())->getRangeType();
|
||||
$this->rangeType = Factory::getRangeFromBoundaries($this->fromAddress->toIPv4(), $this->toAddress->toIPv4())->getRangeType();
|
||||
} else {
|
||||
switch ($addressType) {
|
||||
case AddressType::T_IPv4:
|
||||
@@ -48,6 +51,33 @@ abstract class AbstractRange implements RangeInterface
|
||||
return $this->rangeType === false ? null : $this->rangeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::getAddressAtOffset()
|
||||
*/
|
||||
public function getAddressAtOffset($n)
|
||||
{
|
||||
if (!is_int($n)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$address = null;
|
||||
if ($n >= 0) {
|
||||
$start = Factory::parseAddressString($this->getComparableStartString());
|
||||
$address = $start->getAddressAtOffset($n);
|
||||
} else {
|
||||
$end = Factory::parseAddressString($this->getComparableEndString());
|
||||
$address = $end->getAddressAtOffset($n + 1);
|
||||
}
|
||||
|
||||
if ($address === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->contains($address) ? $address : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
|
||||
71
vendor/mlocati/ip-lib/src/Range/Pattern.php
vendored
71
vendor/mlocati/ip-lib/src/Range/Pattern.php
vendored
@@ -6,6 +6,7 @@ use IPLib\Address\AddressInterface;
|
||||
use IPLib\Address\IPv4;
|
||||
use IPLib\Address\IPv6;
|
||||
use IPLib\Address\Type as AddressType;
|
||||
use IPLib\ParseStringFlag;
|
||||
|
||||
/**
|
||||
* Represents an address range in pattern format (only ending asterisks are supported).
|
||||
@@ -40,6 +41,8 @@ class Pattern extends AbstractRange
|
||||
* The type of the range of this IP range.
|
||||
*
|
||||
* @var int|false|null false if this range crosses multiple range types, null if yet to be determined
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
protected $rangeType;
|
||||
|
||||
@@ -67,24 +70,45 @@ class Pattern extends AbstractRange
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.17.0: use the parseString() method instead.
|
||||
* For upgrading:
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string|mixed $range
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\Range\Pattern::parseString()
|
||||
* @since 1.10.0 added the $supportNonDecimalIPv4 argument
|
||||
*/
|
||||
public static function fromString($range, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Try get the range instance starting from its string representation.
|
||||
*
|
||||
* @param string|mixed $range
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @since 1.17.0
|
||||
* @see \IPLib\ParseStringFlag
|
||||
*/
|
||||
public static function fromString($range, $supportNonDecimalIPv4 = false)
|
||||
public static function parseString($range, $flags = 0)
|
||||
{
|
||||
if (!is_string($range) || strpos($range, '*') === false) {
|
||||
return null;
|
||||
}
|
||||
if ($range === '*.*.*.*') {
|
||||
return new static(IPv4::fromString('0.0.0.0'), IPv4::fromString('255.255.255.255'), 4);
|
||||
return new static(IPv4::parseString('0.0.0.0'), IPv4::parseString('255.255.255.255'), 4);
|
||||
}
|
||||
if ($range === '*:*:*:*:*:*:*:*') {
|
||||
return new static(IPv6::fromString('::'), IPv6::fromString('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 8);
|
||||
return new static(IPv6::parseString('::'), IPv6::parseString('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff'), 8);
|
||||
}
|
||||
$matches = null;
|
||||
if (strpos($range, '.') !== false && preg_match('/^[^*]+((?:\.\*)+)$/', $range, $matches)) {
|
||||
@@ -96,7 +120,7 @@ class Pattern extends AbstractRange
|
||||
$asterisksCount += $missingDots;
|
||||
}
|
||||
}
|
||||
$fromAddress = IPv4::fromString(str_replace('*', '0', $range), true, $supportNonDecimalIPv4);
|
||||
$fromAddress = IPv4::parseString(str_replace('*', '0', $range), $flags);
|
||||
if ($fromAddress === null) {
|
||||
return null;
|
||||
}
|
||||
@@ -108,7 +132,7 @@ class Pattern extends AbstractRange
|
||||
}
|
||||
if (strpos($range, ':') !== false && preg_match('/^[^*]+((?::\*)+)$/', $range, $matches)) {
|
||||
$asterisksCount = strlen($matches[1]) >> 1;
|
||||
$fromAddress = IPv6::fromString(str_replace('*', '0', $range));
|
||||
$fromAddress = IPv6::parseString(str_replace('*', '0', $range));
|
||||
if ($fromAddress === null) {
|
||||
return null;
|
||||
}
|
||||
@@ -217,15 +241,11 @@ class Pattern extends AbstractRange
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::asSubnet()
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public function asSubnet()
|
||||
{
|
||||
switch ($this->getAddressType()) {
|
||||
case AddressType::T_IPv4:
|
||||
return new Subnet($this->getStartAddress(), $this->getEndAddress(), 8 * (4 - $this->asterisksCount));
|
||||
case AddressType::T_IPv6:
|
||||
return new Subnet($this->getStartAddress(), $this->getEndAddress(), 16 * (8 - $this->asterisksCount));
|
||||
}
|
||||
return new Subnet($this->getStartAddress(), $this->getEndAddress(), $this->getNetworkPrefix());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -272,4 +292,31 @@ class Pattern extends AbstractRange
|
||||
{
|
||||
return $this->asterisksCount === 0 ? array($this->getStartAddress()->getReverseDNSLookupName()) : $this->asSubnet()->getReverseDNSLookupName();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::getSize()
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
$fromAddress = $this->fromAddress;
|
||||
$maxPrefix = $fromAddress::getNumberOfBits();
|
||||
$prefix = $this->getNetworkPrefix();
|
||||
|
||||
return pow(2, ($maxPrefix - $prefix));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return float|int
|
||||
*/
|
||||
private function getNetworkPrefix()
|
||||
{
|
||||
switch ($this->getAddressType()) {
|
||||
case AddressType::T_IPv4:
|
||||
return 8 * (4 - $this->asterisksCount);
|
||||
case AddressType::T_IPv6:
|
||||
return 16 * (8 - $this->asterisksCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,9 +38,26 @@ interface RangeInterface
|
||||
* Get the type of range of the IP address.
|
||||
*
|
||||
* @return int One of the \IPLib\Range\Type::T_... constants
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function getRangeType();
|
||||
|
||||
/**
|
||||
* Get the address at a certain offset of this range.
|
||||
*
|
||||
* @param int $n the offset of the address (support negative offset)
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface|null return NULL if $n is not an integer or if the offset out of range
|
||||
*
|
||||
* @since 1.15.0
|
||||
*
|
||||
* @example passing 256 to the range 127.0.0.0/16 will result in 127.0.1.0
|
||||
* @example passing -1 to the range 127.0.1.0/16 will result in 127.0.255.255
|
||||
* @example passing 256 to the range 127.0.0.0/24 will result in NULL
|
||||
*/
|
||||
public function getAddressAtOffset($n);
|
||||
|
||||
/**
|
||||
* Check if this range contains an IP address.
|
||||
*
|
||||
@@ -56,6 +73,8 @@ interface RangeInterface
|
||||
* @param \IPLib\Range\RangeInterface $range
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public function containsRange(RangeInterface $range);
|
||||
|
||||
@@ -63,6 +82,8 @@ interface RangeInterface
|
||||
* Get the initial address contained in this range.
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public function getStartAddress();
|
||||
|
||||
@@ -70,6 +91,8 @@ interface RangeInterface
|
||||
* Get the final address contained in this range.
|
||||
*
|
||||
* @return \IPLib\Address\AddressInterface
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
public function getEndAddress();
|
||||
|
||||
@@ -91,6 +114,8 @@ interface RangeInterface
|
||||
* Get the subnet mask representing this range (only for IPv4 ranges).
|
||||
*
|
||||
* @return \IPLib\Address\IPv4|null return NULL if the range is an IPv6 range, the subnet mask otherwise
|
||||
*
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public function getSubnetMask();
|
||||
|
||||
@@ -98,6 +123,8 @@ interface RangeInterface
|
||||
* Get the subnet/CIDR representation of this range.
|
||||
*
|
||||
* @return \IPLib\Range\Subnet
|
||||
*
|
||||
* @since 1.13.0
|
||||
*/
|
||||
public function asSubnet();
|
||||
|
||||
@@ -105,6 +132,8 @@ interface RangeInterface
|
||||
* Get the pattern/asterisk representation (if applicable) of this range.
|
||||
*
|
||||
* @return \IPLib\Range\Pattern|null return NULL if this range can't be represented by a pattern notation
|
||||
*
|
||||
* @since 1.13.0
|
||||
*/
|
||||
public function asPattern();
|
||||
|
||||
@@ -113,8 +142,19 @@ interface RangeInterface
|
||||
*
|
||||
* @return string[]
|
||||
*
|
||||
* @since 1.13.0
|
||||
*
|
||||
* @example for IPv4 it returns something like array('x.x.x.x.in-addr.arpa', 'x.x.x.x.in-addr.arpa') (where the number of 'x.' ranges from 1 to 4)
|
||||
* @example for IPv6 it returns something like array('x.x.x.x..x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.ip6.arpa', 'x.x.x.x..x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.ip6.arpa') (where the number of 'x.' ranges from 1 to 32)
|
||||
*/
|
||||
public function getReverseDNSLookupName();
|
||||
|
||||
/**
|
||||
* Get the count of addresses this IP range contains.
|
||||
*
|
||||
* @return int|float Return float as for huge IPv6 networks, int is not enough
|
||||
*
|
||||
* @since 1.16.0
|
||||
*/
|
||||
public function getSize();
|
||||
}
|
||||
|
||||
58
vendor/mlocati/ip-lib/src/Range/Single.php
vendored
58
vendor/mlocati/ip-lib/src/Range/Single.php
vendored
@@ -6,6 +6,7 @@ use IPLib\Address\AddressInterface;
|
||||
use IPLib\Address\IPv4;
|
||||
use IPLib\Address\Type as AddressType;
|
||||
use IPLib\Factory;
|
||||
use IPLib\ParseStringFlag;
|
||||
|
||||
/**
|
||||
* Represents a single address (eg a range that contains just one address).
|
||||
@@ -41,17 +42,39 @@ class Single extends AbstractRange
|
||||
}
|
||||
|
||||
/**
|
||||
* Try get the range instance starting from its string representation.
|
||||
* @deprecated since 1.17.0: use the parseString() method instead.
|
||||
* For upgrading:
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string|mixed $range
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\Range\Single::parseString()
|
||||
* @since 1.10.0 added the $supportNonDecimalIPv4 argument
|
||||
*/
|
||||
public static function fromString($range, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Try get the range instance starting from its string representation.
|
||||
*
|
||||
* @param string|mixed $range
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function parseString($range, $flags = 0)
|
||||
{
|
||||
$result = null;
|
||||
$address = Factory::addressFromString($range, true, true, $supportNonDecimalIPv4);
|
||||
$flags = (int) $flags;
|
||||
$address = Factory::parseAddressString($range, $flags);
|
||||
if ($address !== null) {
|
||||
$result = new static($address);
|
||||
}
|
||||
@@ -65,6 +88,8 @@ class Single extends AbstractRange
|
||||
* @param \IPLib\Address\AddressInterface $address
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @since 1.2.0
|
||||
*/
|
||||
public static function fromAddress(AddressInterface $address)
|
||||
{
|
||||
@@ -118,23 +143,6 @@ class Single extends AbstractRange
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::containsRange()
|
||||
*/
|
||||
public function containsRange(RangeInterface $range)
|
||||
{
|
||||
$result = false;
|
||||
if ($range->getAddressType() === $this->getAddressType()) {
|
||||
if ($range->toString(false) === $this->toString(false)) {
|
||||
$result = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
@@ -223,4 +231,14 @@ class Single extends AbstractRange
|
||||
{
|
||||
return array($this->getStartAddress()->getReverseDNSLookupName());
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::getSize()
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
63
vendor/mlocati/ip-lib/src/Range/Subnet.php
vendored
63
vendor/mlocati/ip-lib/src/Range/Subnet.php
vendored
@@ -4,9 +4,9 @@ namespace IPLib\Range;
|
||||
|
||||
use IPLib\Address\AddressInterface;
|
||||
use IPLib\Address\IPv4;
|
||||
use IPLib\Address\IPv6;
|
||||
use IPLib\Address\Type as AddressType;
|
||||
use IPLib\Factory;
|
||||
use IPLib\ParseStringFlag;
|
||||
|
||||
/**
|
||||
* Represents an address range in subnet format (eg CIDR).
|
||||
@@ -41,6 +41,8 @@ class Subnet extends AbstractRange
|
||||
* The type of the range of this IP range.
|
||||
*
|
||||
* @var int|null
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
protected $rangeType;
|
||||
|
||||
@@ -77,15 +79,36 @@ class Subnet extends AbstractRange
|
||||
return $this->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.17.0: use the parseString() method instead.
|
||||
* For upgrading:
|
||||
* - if $supportNonDecimalIPv4 is true, use the ParseStringFlag::IPV4_MAYBE_NON_DECIMAL flag
|
||||
*
|
||||
* @param string|mixed $range
|
||||
* @param bool $supportNonDecimalIPv4
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\Range\Subnet::parseString()
|
||||
* @since 1.10.0 added the $supportNonDecimalIPv4 argument
|
||||
*/
|
||||
public static function fromString($range, $supportNonDecimalIPv4 = false)
|
||||
{
|
||||
return static::parseString($range, ParseStringFlag::MAY_INCLUDE_PORT | ParseStringFlag::MAY_INCLUDE_ZONEID | ($supportNonDecimalIPv4 ? ParseStringFlag::IPV4_MAYBE_NON_DECIMAL : 0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Try get the range instance starting from its string representation.
|
||||
*
|
||||
* @param string|mixed $range
|
||||
* @param bool $supportNonDecimalIPv4 set to true to support parsing non decimal (that is, octal and hexadecimal) IPv4 addresses
|
||||
* @param int $flags A combination or zero or more flags
|
||||
*
|
||||
* @return static|null
|
||||
*
|
||||
* @see \IPLib\ParseStringFlag
|
||||
* @since 1.17.0
|
||||
*/
|
||||
public static function fromString($range, $supportNonDecimalIPv4 = false)
|
||||
public static function parseString($range, $flags = 0)
|
||||
{
|
||||
if (!is_string($range)) {
|
||||
return null;
|
||||
@@ -94,7 +117,14 @@ class Subnet extends AbstractRange
|
||||
if (count($parts) !== 2) {
|
||||
return null;
|
||||
}
|
||||
$address = Factory::addressFromString($parts[0], true, true, $supportNonDecimalIPv4);
|
||||
$flags = (int) $flags;
|
||||
if (strpos($parts[0], ':') === false && $flags & ParseStringFlag::IPV4SUBNET_MAYBE_COMPACT) {
|
||||
$missingDots = 3 - substr_count($parts[0], '.');
|
||||
if ($missingDots > 0) {
|
||||
$parts[0] .= str_repeat('.0', $missingDots);
|
||||
}
|
||||
}
|
||||
$address = Factory::parseAddressString($parts[0], $flags);
|
||||
if ($address === null) {
|
||||
return null;
|
||||
}
|
||||
@@ -197,9 +227,10 @@ class Subnet extends AbstractRange
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the pattern (asterisk) representation (if applicable) of this range.
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @return \IPLib\Range\Pattern|null return NULL if this range can't be represented by a pattern notation
|
||||
* @see \IPLib\Range\RangeInterface::asPattern()
|
||||
* @since 1.8.0
|
||||
*/
|
||||
public function asPattern()
|
||||
{
|
||||
@@ -217,11 +248,13 @@ class Subnet extends AbstractRange
|
||||
* Get the 6to4 address IPv6 address range.
|
||||
*
|
||||
* @return self
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
public static function get6to4()
|
||||
{
|
||||
if (self::$sixToFour === null) {
|
||||
self::$sixToFour = self::fromString('2002::/16');
|
||||
self::$sixToFour = self::parseString('2002::/16');
|
||||
}
|
||||
|
||||
return self::$sixToFour;
|
||||
@@ -231,6 +264,8 @@ class Subnet extends AbstractRange
|
||||
* Get subnet prefix.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public function getNetworkPrefix()
|
||||
{
|
||||
@@ -302,4 +337,18 @@ class Subnet extends AbstractRange
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @see \IPLib\Range\RangeInterface::getSize()
|
||||
*/
|
||||
public function getSize()
|
||||
{
|
||||
$fromAddress = $this->fromAddress;
|
||||
$maxPrefix = $fromAddress::getNumberOfBits();
|
||||
$prefix = $this->getNetworkPrefix();
|
||||
|
||||
return pow(2, ($maxPrefix - $prefix));
|
||||
}
|
||||
}
|
||||
|
||||
2
vendor/mlocati/ip-lib/src/Range/Type.php
vendored
2
vendor/mlocati/ip-lib/src/Range/Type.php
vendored
@@ -102,6 +102,8 @@ class Type
|
||||
* Carrier-grade NAT address.
|
||||
*
|
||||
* @var int
|
||||
*
|
||||
* @since 1.10.0
|
||||
*/
|
||||
const T_CGNAT = 14;
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace IPLib\Service;
|
||||
|
||||
/**
|
||||
* Helper class to work with unsigned binary integers.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class BinaryMath
|
||||
{
|
||||
|
||||
@@ -7,12 +7,14 @@ use IPLib\Factory;
|
||||
use IPLib\Range\Subnet;
|
||||
|
||||
/**
|
||||
* Helper class to calculate the subnets describing all (and only all) the addresses between two bouundaries.
|
||||
* Helper class to calculate the subnets describing all (and only all) the addresses between two boundaries.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class RangesFromBounradyCalculator
|
||||
class RangesFromBoundaryCalculator
|
||||
{
|
||||
/**
|
||||
* The BinaryMath instance to be used to perform bitwise poerations.
|
||||
* The BinaryMath instance to be used to perform bitwise operations.
|
||||
*
|
||||
* @var \IPLib\Service\BinaryMath
|
||||
*/
|
||||
@@ -53,7 +55,7 @@ class RangesFromBounradyCalculator
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate the subnets describing all (and only all) the addresses between two bouundaries.
|
||||
* Calculate the subnets describing all (and only all) the addresses between two boundaries.
|
||||
*
|
||||
* @param \IPLib\Address\AddressInterface $from
|
||||
* @param \IPLib\Address\AddressInterface $to
|
||||
@@ -154,8 +156,13 @@ class RangesFromBounradyCalculator
|
||||
*/
|
||||
private function subnetFromBits($bits, $networkPrefix)
|
||||
{
|
||||
$address = $this->addressFromBits($bits);
|
||||
$startAddress = $this->addressFromBits($bits);
|
||||
$numOnes = $this->numBits - $networkPrefix;
|
||||
if ($numOnes === 0) {
|
||||
return new Subnet($startAddress, $startAddress, $networkPrefix);
|
||||
}
|
||||
$endAddress = $this->addressFromBits(substr($bits, 0, -$numOnes) . str_repeat('1', $numOnes));
|
||||
|
||||
return new Subnet($address, $address, $networkPrefix);
|
||||
return new Subnet($startAddress, $endAddress, $networkPrefix);
|
||||
}
|
||||
}
|
||||
171
vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php
vendored
Normal file
171
vendor/mlocati/ip-lib/src/Service/UnsignedIntegerMath.php
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?php
|
||||
|
||||
namespace IPLib\Service;
|
||||
|
||||
/**
|
||||
* Helper class to work with unsigned integers.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class UnsignedIntegerMath
|
||||
{
|
||||
/**
|
||||
* Convert a string containing a decimal, octal or hexadecimal number into its bytes.
|
||||
*
|
||||
* @param string $value
|
||||
* @param int $numBytes the wanted number of bytes
|
||||
* @param bool $onlyDecimal Only parse decimal numbers
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
public function getBytes($value, $numBytes, $onlyDecimal = false)
|
||||
{
|
||||
$m = null;
|
||||
if ($onlyDecimal) {
|
||||
if (preg_match('/^0*(\d+)$/', $value, $m)) {
|
||||
return $this->getBytesFromDecimal($m[1], $numBytes);
|
||||
}
|
||||
} else {
|
||||
if (preg_match('/^0[Xx]0*([0-9A-Fa-f]+)$/', $value, $m)) {
|
||||
return $this->getBytesFromHexadecimal($m[1], $numBytes);
|
||||
}
|
||||
if (preg_match('/^0+([0-7]*)$/', $value, $m)) {
|
||||
return $this->getBytesFromOctal($m[1], $numBytes);
|
||||
}
|
||||
if (preg_match('/^[1-9][0-9]*$/', $value)) {
|
||||
return $this->getBytesFromDecimal($value, $numBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Not a valid number
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
protected function getMaxSignedInt()
|
||||
{
|
||||
return PHP_INT_MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value never zero-length, never extra leading zeroes
|
||||
* @param int $numBytes
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
private function getBytesFromBits($value, $numBytes)
|
||||
{
|
||||
$valueLength = strlen($value);
|
||||
if ($valueLength > $numBytes << 3) {
|
||||
// overflow
|
||||
return null;
|
||||
}
|
||||
$remainderBits = $valueLength % 8;
|
||||
if ($remainderBits !== 0) {
|
||||
$value = str_pad($value, $valueLength + 8 - $remainderBits, '0', STR_PAD_LEFT);
|
||||
}
|
||||
$bytes = array_map('bindec', str_split($value, 8));
|
||||
|
||||
return array_pad($bytes, -$numBytes, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value may be zero-length, never extra leading zeroes
|
||||
* @param int $numBytes
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
private function getBytesFromOctal($value, $numBytes)
|
||||
{
|
||||
if ($value === '') {
|
||||
return array_fill(0, $numBytes, 0);
|
||||
}
|
||||
$bits = implode(
|
||||
'',
|
||||
array_map(
|
||||
function ($octalDigit) {
|
||||
return str_pad(decbin(octdec($octalDigit)), 3, '0', STR_PAD_LEFT);
|
||||
},
|
||||
str_split($value, 1)
|
||||
)
|
||||
);
|
||||
$bits = ltrim($bits, '0');
|
||||
|
||||
return $bits === '' ? array_fill(0, $numBytes, 0) : static::getBytesFromBits($bits, $numBytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value never zero-length, never extra leading zeroes
|
||||
* @param int $numBytes
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
private function getBytesFromDecimal($value, $numBytes)
|
||||
{
|
||||
$valueLength = strlen($value);
|
||||
$maxSignedIntLength = strlen((string) $this->getMaxSignedInt());
|
||||
if ($valueLength < $maxSignedIntLength) {
|
||||
return $this->getBytesFromBits(decbin((int) $value), $numBytes);
|
||||
}
|
||||
// Divide by two, so that we have 1 less bit
|
||||
$carry = 0;
|
||||
$halfValue = ltrim(
|
||||
implode(
|
||||
'',
|
||||
array_map(
|
||||
function ($digit) use (&$carry) {
|
||||
$number = $carry + (int) $digit;
|
||||
$carry = ($number % 2) * 10;
|
||||
|
||||
return (string) $number >> 1;
|
||||
},
|
||||
str_split($value, 1)
|
||||
)
|
||||
),
|
||||
'0'
|
||||
);
|
||||
$halfValueBytes = $this->getBytesFromDecimal($halfValue, $numBytes);
|
||||
if ($halfValueBytes === null) {
|
||||
return null;
|
||||
}
|
||||
$carry = $carry === 0 ? 0 : 1;
|
||||
$result = array_fill(0, $numBytes, 0);
|
||||
for ($index = $numBytes - 1; $index >= 0; $index--) {
|
||||
$byte = $carry + ($halfValueBytes[$index] << 1);
|
||||
if ($byte <= 0xFF) {
|
||||
$carry = 0;
|
||||
} else {
|
||||
$carry = ($byte & ~0xFF) >> 8;
|
||||
$byte -= 0x100;
|
||||
}
|
||||
$result[$index] = $byte;
|
||||
}
|
||||
if ($carry !== 0) {
|
||||
// Overflow
|
||||
return null;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $value never zero-length, never extra leading zeroes
|
||||
* @param int $numBytes
|
||||
*
|
||||
* @return int[]|null
|
||||
*/
|
||||
private function getBytesFromHexadecimal($value, $numBytes)
|
||||
{
|
||||
$valueLength = strlen($value);
|
||||
if ($valueLength > $numBytes << 1) {
|
||||
// overflow
|
||||
return null;
|
||||
}
|
||||
$value = str_pad($value, $valueLength + $valueLength % 2, '0', STR_PAD_LEFT);
|
||||
$bytes = array_map('hexdec', str_split($value, 2));
|
||||
|
||||
return array_pad($bytes, -$numBytes, 0);
|
||||
}
|
||||
}
|
||||
@@ -183,7 +183,7 @@ if (!is_callable('random_bytes')) {
|
||||
try {
|
||||
$RandomCompatCOMtest = new COM('CAPICOM.Utilities.1');
|
||||
/** @psalm-suppress TypeDoesNotContainType */
|
||||
if (method_exists($RandomCompatCOMtest, 'GetRandom')) {
|
||||
if (is_callable(array($RandomCompatCOMtest, 'GetRandom'))) {
|
||||
// See random_bytes_com_dotnet.php
|
||||
require_once $RandomCompatDIR.DIRECTORY_SEPARATOR.'random_bytes_com_dotnet.php';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user