Skip to content

Commit dec878d

Browse files
authored
Merge branch 'main' into decode_case_insensitive
2 parents 766be66 + baa6683 commit dec878d

File tree

8 files changed

+114
-42
lines changed

8 files changed

+114
-42
lines changed

.github/workflows/main.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: run-checks
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
build:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- name: Checkout
16+
uses: actions/checkout@v2
17+
- name: Set up Node.js
18+
uses: actions/setup-node@v3
19+
with:
20+
node-version-file: '.nvmrc'
21+
- name: Install dependencies
22+
run: npm install
23+
- name: Build
24+
run: npm run build
25+
- name: Test
26+
run: npm test

.github/workflows/publish-on-tag.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: publish-on-tag
2+
3+
on:
4+
push:
5+
tags:
6+
- '*'
7+
8+
jobs:
9+
publish:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Checkout
13+
uses: actions/checkout@v2
14+
- name: Set up Node.js
15+
uses: actions/setup-node@v3
16+
with:
17+
node-version-file: '.nvmrc'
18+
- name: Install dependencies
19+
run: npm install
20+
- name: Build
21+
run: npm run build
22+
- name: Test
23+
run: npm test
24+
- name: Publish punycode package
25+
env:
26+
NPM_TOKEN: ${{secrets.NPM_TOKEN_PUNYCODE}}
27+
run: |
28+
npm config set registry 'https://wombat-dressing-room.appspot.com/'
29+
npm config set '//wombat-dressing-room.appspot.com/:_authToken' '${NPM_TOKEN}'
30+
npm publish
31+
- name: Publish punycode.js package
32+
env:
33+
NPM_TOKEN: ${{secrets.NPM_TOKEN_PUNYCODE_JS}}
34+
run: |
35+
npm config set registry 'https://wombat-dressing-room.appspot.com/'
36+
npm config set '//wombat-dressing-room.appspot.com/:_authToken' '${NPM_TOKEN}'
37+
npm publish

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
14

.travis.yml

Lines changed: 0 additions & 11 deletions
This file was deleted.

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Punycode.js [![Build status](https://travis-ci.org/bestiejs/punycode.js.svg?branch=master)](https://travis-ci.org/bestiejs/punycode.js) [![Code coverage status](http://img.shields.io/codecov/c/github/bestiejs/punycode.js.svg)](https://codecov.io/gh/bestiejs/punycode.js) [![Dependency status](https://gemnasium.com/bestiejs/punycode.js.svg)](https://gemnasium.com/bestiejs/punycode.js)
1+
# Punycode.js [![punycode on npm](https://img.shields.io/npm/v/punycode)](https://www.npmjs.com/package/emoji-test-regex-pattern) [![](https://data.jsdelivr.com/v1/package/npm/punycode/badge)](https://www.jsdelivr.com/package/npm/punycode)
22

33
Punycode.js is a robust Punycode converter that fully complies to [RFC 3492](https://tools.ietf.org/html/rfc3492) and [RFC 5891](https://tools.ietf.org/html/rfc5891).
44

@@ -12,7 +12,7 @@ This JavaScript library is the result of comparing, optimizing and documenting d
1212

1313
This project was [bundled](https://github.com/joyent/node/blob/master/lib/punycode.js) with Node.js from [v0.6.2+](https://github.com/joyent/node/compare/975f1930b1...61e796decc) until [v7](https://github.com/nodejs/node/pull/7941) (soft-deprecated).
1414

15-
The current version supports recent versions of Node.js only. It provides a CommonJS module and an ES6 module. For the old version that offers the same functionality with broader support, including Rhino, Ringo, Narwhal, and web browsers, see [v1.4.1](https://github.com/bestiejs/punycode.js/releases/tag/v1.4.1).
15+
This project provides a CommonJS module that uses ES2015+ features and JavaScript module, which work in modern Node.js versions and browsers. For the old Punycode.js version that offers the same functionality in a UMD build with support for older pre-ES2015 runtimes, including Rhino, Ringo, and Narwhal, see [v1.4.1](https://github.com/mathiasbynens/punycode.js/releases/tag/v1.4.1).
1616

1717
## Installation
1818

@@ -24,8 +24,12 @@ npm install punycode --save
2424

2525
In [Node.js](https://nodejs.org/):
2626

27+
> ⚠️ Note that userland modules don't hide core modules.
28+
> For example, `require('punycode')` still imports the deprecated core module even if you executed `npm install punycode`.
29+
> Use `require('punycode/')` to import userland modules rather than core modules.
30+
2731
```js
28-
const punycode = require('punycode');
32+
const punycode = require('punycode/');
2933
```
3034

3135
## API

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "punycode",
3-
"version": "2.1.1",
3+
"version": "2.2.1",
44
"description": "A robust Punycode converter that fully complies to RFC 3492 and RFC 5891, and works on nearly all JavaScript platforms.",
55
"homepage": "https://mths.be/punycode",
66
"main": "punycode.js",
@@ -31,22 +31,22 @@
3131
],
3232
"repository": {
3333
"type": "git",
34-
"url": "https://github.com/bestiejs/punycode.js.git"
34+
"url": "https://github.com/mathiasbynens/punycode.js.git"
3535
},
36-
"bugs": "https://github.com/bestiejs/punycode.js/issues",
36+
"bugs": "https://github.com/mathiasbynens/punycode.js/issues",
3737
"files": [
3838
"LICENSE-MIT.txt",
3939
"punycode.js",
4040
"punycode.es6.js"
4141
],
4242
"scripts": {
4343
"test": "mocha tests",
44-
"prepublish": "node scripts/prepublish.js"
44+
"build": "node scripts/prepublish.js"
4545
},
4646
"devDependencies": {
4747
"codecov": "^1.0.1",
4848
"istanbul": "^0.4.1",
49-
"mocha": "^2.5.3"
49+
"mocha": "^10.2.0"
5050
},
5151
"jspm": {
5252
"map": {

punycode.js

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const delimiter = '-'; // '\x2D'
1515

1616
/** Regular expressions */
1717
const regexPunycode = /^xn--/i;
18-
const regexNonASCII = /[^\0-\x7E]/; // non-ASCII chars
18+
const regexNonASCII = /[^\0-\x7F]/; // Note: U+007F DEL is excluded too.
1919
const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators
2020

2121
/** Error messages */
@@ -50,11 +50,11 @@ function error(type) {
5050
* item.
5151
* @returns {Array} A new array of values returned by the callback function.
5252
*/
53-
function map(array, fn) {
53+
function map(array, callback) {
5454
const result = [];
5555
let length = array.length;
5656
while (length--) {
57-
result[length] = fn(array[length]);
57+
result[length] = callback(array[length]);
5858
}
5959
return result;
6060
}
@@ -66,22 +66,22 @@ function map(array, fn) {
6666
* @param {String} domain The domain name or email address.
6767
* @param {Function} callback The function that gets called for every
6868
* character.
69-
* @returns {Array} A new string of characters returned by the callback
69+
* @returns {String} A new string of characters returned by the callback
7070
* function.
7171
*/
72-
function mapDomain(string, fn) {
73-
const parts = string.split('@');
72+
function mapDomain(domain, callback) {
73+
const parts = domain.split('@');
7474
let result = '';
7575
if (parts.length > 1) {
7676
// In email addresses, only the domain name should be punycoded. Leave
7777
// the local part (i.e. everything up to `@`) intact.
7878
result = parts[0] + '@';
79-
string = parts[1];
79+
domain = parts[1];
8080
}
8181
// Avoid `split(regex)` for IE8 compatibility. See #17.
82-
string = string.replace(regexSeparators, '\x2E');
83-
const labels = string.split('.');
84-
const encoded = map(labels, fn).join('.');
82+
domain = domain.replace(regexSeparators, '\x2E');
83+
const labels = domain.split('.');
84+
const encoded = map(labels, callback).join('.');
8585
return result + encoded;
8686
}
8787

@@ -130,7 +130,7 @@ function ucs2decode(string) {
130130
* @param {Array} codePoints The array of numeric code points.
131131
* @returns {String} The new Unicode string (UCS-2).
132132
*/
133-
const ucs2encode = array => String.fromCodePoint(...array);
133+
const ucs2encode = codePoints => String.fromCodePoint(...codePoints);
134134

135135
/**
136136
* Converts a basic code point into a digit/integer.
@@ -142,13 +142,13 @@ const ucs2encode = array => String.fromCodePoint(...array);
142142
* the code point does not represent a value.
143143
*/
144144
const basicToDigit = function(codePoint) {
145-
if (codePoint - 0x30 < 0x0A) {
146-
return codePoint - 0x16;
145+
if (codePoint >= 0x30 && codePoint < 0x3A) {
146+
return 26 + (codePoint - 0x30);
147147
}
148-
if (codePoint - 0x41 < 0x1A) {
148+
if (codePoint >= 0x41 && codePoint < 0x5B) {
149149
return codePoint - 0x41;
150150
}
151-
if (codePoint - 0x61 < 0x1A) {
151+
if (codePoint >= 0x61 && codePoint < 0x7B) {
152152
return codePoint - 0x61;
153153
}
154154
return base;
@@ -228,7 +228,7 @@ const decode = function(input) {
228228
// which gets added to `i`. The overflow checking is easier
229229
// if we increase `i` as we go, then subtract off its starting
230230
// value at the end to obtain `delta`.
231-
let oldi = i;
231+
const oldi = i;
232232
for (let w = 1, k = base; /* no condition */; k += base) {
233233

234234
if (index >= inputLength) {
@@ -237,7 +237,10 @@ const decode = function(input) {
237237

238238
const digit = basicToDigit(input.charCodeAt(index++));
239239

240-
if (digit >= base || digit > floor((maxInt - i) / w)) {
240+
if (digit >= base) {
241+
error('invalid-input');
242+
}
243+
if (digit > floor((maxInt - i) / w)) {
241244
error('overflow');
242245
}
243246

@@ -291,7 +294,7 @@ const encode = function(input) {
291294
input = ucs2decode(input);
292295

293296
// Cache the length.
294-
let inputLength = input.length;
297+
const inputLength = input.length;
295298

296299
// Initialize the state.
297300
let n = initialN;
@@ -305,7 +308,7 @@ const encode = function(input) {
305308
}
306309
}
307310

308-
let basicLength = output.length;
311+
const basicLength = output.length;
309312
let handledCPCount = basicLength;
310313

311314
// `handledCPCount` is the number of code points that have been handled;
@@ -342,7 +345,7 @@ const encode = function(input) {
342345
if (currentValue < n && ++delta > maxInt) {
343346
error('overflow');
344347
}
345-
if (currentValue == n) {
348+
if (currentValue === n) {
346349
// Represent delta as a generalized variable-length integer.
347350
let q = delta;
348351
for (let k = base; /* no condition */; k += base) {
@@ -359,7 +362,7 @@ const encode = function(input) {
359362
}
360363

361364
output.push(stringFromCharCode(digitToBasic(q, 0)));
362-
bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
365+
bias = adapt(delta, handledCPCountPlusOne, handledCPCount === basicLength);
363366
delta = 0;
364367
++handledCPCount;
365368
}

tests/tests.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ const testData = {
7878
* `b1abfaaepdrnnbgefbaDotcwatmq2g4l`
7979
* Without mixed-case annotation it has to encode to:
8080
* `b1abfaaepdrnnbgefbadotcwatmq2g4l`
81-
* https://github.com/bestiejs/punycode.js/issues/3
81+
* https://github.com/mathiasbynens/punycode.js/issues/3
8282
*/
8383
{
8484
'description': 'Russian (Cyrillic)',
@@ -178,7 +178,7 @@ const testData = {
178178
'decoded': 'ma\xF1ana.com',
179179
'encoded': 'xn--maana-pta.com'
180180
},
181-
{ // https://github.com/bestiejs/punycode.js/issues/17
181+
{ // https://github.com/mathiasbynens/punycode.js/issues/17
182182
'decoded': 'example.com.',
183183
'encoded': 'example.com.'
184184
},
@@ -220,6 +220,10 @@ const testData = {
220220
'description': 'Email address',
221221
'decoded': '\u0434\u0436\u0443\u043C\u043B\u0430@\u0434\u0436p\u0443\u043C\u043B\u0430\u0442\u0435\u0441\u0442.b\u0440\u0444a',
222222
'encoded': '\u0434\u0436\u0443\u043C\u043B\[email protected]'
223+
},
224+
{ // https://github.com/mathiasbynens/punycode.js/pull/115
225+
'decoded': 'foo\x7F.example',
226+
'encoded': 'foo\x7F.example'
223227
}
224228
],
225229
'separators': [
@@ -303,6 +307,14 @@ describe('punycode.decode', function() {
303307
it('handles uppercase Z', function() {
304308
assert.deepEqual(punycode.decode('ZZZ'), '\u7BA5');
305309
});
310+
it('throws RangeError: Invalid input', function() {
311+
assert.throws(
312+
function() {
313+
punycode.decode('ls8h=');
314+
},
315+
RangeError
316+
);
317+
});
306318
});
307319

308320
describe('punycode.encode', function() {

0 commit comments

Comments
 (0)