libmime 4.1.3 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.eslintrc CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "rules": {
3
- "indent": 0
3
+ "indent": 0,
4
+ "no-prototype-builtins": 0
4
5
  },
5
- "extends": "nodemailer"
6
+ "extends": "nodemailer"
6
7
  }
@@ -0,0 +1,4 @@
1
+ # These are supported funding model platforms
2
+
3
+ github: [andris9] # enable once enrolled
4
+ custom: ['https://www.paypal.me/nodemailer']
package/.prettierrc.js CHANGED
@@ -1,5 +1,8 @@
1
1
  module.exports = {
2
2
  printWidth: 160,
3
3
  tabWidth: 4,
4
- singleQuote: true
4
+ singleQuote: true,
5
+ endOfLine: 'lf',
6
+ trailingComma: 'none',
7
+ arrowParens: 'avoid'
5
8
  };
package/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.0.0 2020-07-22
4
+
5
+ - Removed optional node-iconv support
6
+ - Bumped dependencies
7
+ - Updated Travis test matrix, dropped Node 8
8
+
9
+ ## v4.2.1 2019-10-28
10
+
11
+ - Replace jconv with more recent encoding-japanese
12
+
13
+ ## v4.2.0 2019-10-28
14
+
15
+ - Use jconv module to parse ISO-2022-JP by default
16
+
17
+ ## v4.1.4 2019-10-28
18
+
19
+ - decodeWords should also decode empty content part [WeiAnAn](9bbcfd2)
20
+ - fix decode base64 ending with = [WeiAnAn](6e656e2)
21
+
3
22
  ## v4.1.0 2019-05-01
4
23
 
5
24
  - Experimental support for node-iconv
package/lib/charset.js CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  const iconv = require('iconv-lite');
4
+ const encodingJapanese = require('encoding-japanese');
4
5
  const charsets = require('./charsets');
5
6
 
6
7
  /**
@@ -25,10 +26,9 @@ const charset = (module.exports = {
25
26
  *
26
27
  * @param {Buffer} buf Binary data to be decoded
27
28
  * @param {String} [fromCharset='UTF-8'] Binary data is decoded into string using this charset
28
- * @param {Function} [Iconv] node-iconv function
29
29
  * @return {String} Decded string
30
30
  */
31
- decode(buf, fromCharset, Iconv) {
31
+ decode(buf, fromCharset) {
32
32
  fromCharset = charset.normalizeCharset(fromCharset || 'UTF-8');
33
33
 
34
34
  if (/^(us-)?ascii|utf-8|7bit$/i.test(fromCharset)) {
@@ -36,10 +36,25 @@ const charset = (module.exports = {
36
36
  }
37
37
 
38
38
  try {
39
- if (typeof Iconv === 'function') {
40
- let decoder = new Iconv(fromCharset, 'UTF-8');
41
- return decoder.convert(buf).toString();
39
+ if (/^jis|^iso-?2022-?jp|^EUCJP/i.test(fromCharset)) {
40
+ if (typeof buf === 'string') {
41
+ buf = Buffer.from(buf);
42
+ }
43
+ try {
44
+ let output = encodingJapanese.convert(buf, {
45
+ to: 'UNICODE',
46
+ from: fromCharset,
47
+ type: 'string'
48
+ });
49
+ if (typeof output === 'string') {
50
+ output = Buffer.from(output);
51
+ }
52
+ return output;
53
+ } catch (err) {
54
+ // ignore, defaults to iconv-lite on error
55
+ }
42
56
  }
57
+
43
58
  return iconv.decode(buf, fromCharset);
44
59
  } catch (err) {
45
60
  // enforce utf-8, data loss might occur
@@ -54,7 +69,7 @@ const charset = (module.exports = {
54
69
  * @param {String} [fromCharset='UTF-8'] Source encoding for the string
55
70
  * @return {Buffer} UTF-8 encoded typed array
56
71
  */
57
- convert(data, fromCharset, Iconv) {
72
+ convert(data, fromCharset) {
58
73
  fromCharset = charset.normalizeCharset(fromCharset || 'UTF-8');
59
74
 
60
75
  let bufString;
@@ -64,7 +79,7 @@ const charset = (module.exports = {
64
79
  return data;
65
80
  }
66
81
 
67
- bufString = charset.decode(data, fromCharset, Iconv);
82
+ bufString = charset.decode(data, fromCharset);
68
83
  return charset.encode(bufString);
69
84
  }
70
85
  return charset.encode(data);
package/lib/libmime.js CHANGED
@@ -112,11 +112,7 @@ class Libmime {
112
112
  * @return {String} Single or several mime words joined together
113
113
  */
114
114
  encodeWord(data, mimeWordEncoding, maxLength) {
115
- mimeWordEncoding = (mimeWordEncoding || 'Q')
116
- .toString()
117
- .toUpperCase()
118
- .trim()
119
- .charAt(0);
115
+ mimeWordEncoding = (mimeWordEncoding || 'Q').toString().toUpperCase().trim().charAt(0);
120
116
  maxLength = maxLength || 0;
121
117
 
122
118
  let encodedStr;
@@ -129,10 +125,7 @@ class Libmime {
129
125
  if (mimeWordEncoding === 'Q') {
130
126
  // https://tools.ietf.org/html/rfc2047#section-5 rule (3)
131
127
  encodedStr = libqp.encode(data).replace(/[^a-z0-9!*+\-/=]/gi, chr => {
132
- let ord = chr
133
- .charCodeAt(0)
134
- .toString(16)
135
- .toUpperCase();
128
+ let ord = chr.charCodeAt(0).toString(16).toUpperCase();
136
129
  if (chr === ' ') {
137
130
  return '_';
138
131
  } else {
@@ -223,13 +216,18 @@ class Libmime {
223
216
  }
224
217
  str = Buffer.from(bytes);
225
218
  } else if (encoding === 'B') {
226
- str = Buffer.from(str, 'base64');
219
+ str = Buffer.concat(
220
+ str
221
+ .split('=')
222
+ .filter(s => s !== '') // filter empty string
223
+ .map(str => Buffer.from(str, 'base64'))
224
+ );
227
225
  } else {
228
226
  // keep as is, convert Buffer to unicode string, assume utf8
229
227
  str = Buffer.from(str);
230
228
  }
231
229
 
232
- return libcharset.decode(str, charset, this.config.Iconv);
230
+ return libcharset.decode(str, charset);
233
231
  }
234
232
 
235
233
  /**
@@ -249,7 +247,7 @@ class Libmime {
249
247
 
250
248
  maxLength = maxLength || 0;
251
249
 
252
- let decodedValue = libcharset.decode(libcharset.convert(data || '', fromCharset, this.config.Iconv), this.config.Iconv);
250
+ let decodedValue = libcharset.decode(libcharset.convert(data || '', fromCharset));
253
251
  let encodedValue;
254
252
 
255
253
  let firstMatch = decodedValue.match(/(?:^|\s)([^\s]*[\u0080-\uFFFF])/);
@@ -289,7 +287,7 @@ class Libmime {
289
287
  (str || '')
290
288
  .toString()
291
289
  // find base64 words that can be joined
292
- .replace(/(=\?([^?]+)\?[Bb]\?[^?]+[^^=]\?=)\s*(?==\?([^?]+)\?[Bb]\?[^?]+\?=)/g, (match, left, chLeft, chRight) => {
290
+ .replace(/(=\?([^?]+)\?[Bb]\?[^?]*\?=)\s*(?==\?([^?]+)\?[Bb]\?[^?]*\?=)/g, (match, left, chLeft, chRight) => {
293
291
  // only mark b64 chunks to be joined if charsets match
294
292
  if (libcharset.normalizeCharset(chLeft || '') === libcharset.normalizeCharset(chRight || '')) {
295
293
  // set a joiner marker
@@ -298,7 +296,7 @@ class Libmime {
298
296
  return match;
299
297
  })
300
298
  // find QP words that can be joined
301
- .replace(/(=\?([^?]+)\?[Qq]\?[^?]+\?=)\s*(?==\?([^?]+)\?[Qq]\?[^?]+\?=)/g, (match, left, chLeft, chRight) => {
299
+ .replace(/(=\?([^?]+)\?[Qq]\?[^?]*\?=)\s*(?==\?([^?]+)\?[Qq]\?[^?]*\?=)/g, (match, left, chLeft, chRight) => {
302
300
  // only mark QP chunks to be joined if charsets match
303
301
  if (libcharset.normalizeCharset(chLeft || '') === libcharset.normalizeCharset(chRight || '')) {
304
302
  // set a joiner marker
@@ -309,9 +307,9 @@ class Libmime {
309
307
  // join base64 encoded words
310
308
  .replace(/(\?=)?__\x00JOIN\x00__(=\?([^?]+)\?[QqBb]\?)?/g, '')
311
309
  // remove spaces between mime encoded words
312
- .replace(/(=\?[^?]+\?[QqBb]\?[^?]+\?=)\s+(?==\?[^?]+\?[QqBb]\?[^?]+\?=)/g, '$1')
310
+ .replace(/(=\?[^?]+\?[QqBb]\?[^?]*\?=)\s+(?==\?[^?]+\?[QqBb]\?[^?]*\?=)/g, '$1')
313
311
  // decode words
314
- .replace(/=\?([\w_\-*]+)\?([QqBb])\?([^?]+)\?=/g, (m, charset, encoding, text) => this.decodeWord(charset, encoding, text))
312
+ .replace(/=\?([\w_\-*]+)\?([QqBb])\?([^?]*)\?=/g, (m, charset, encoding, text) => this.decodeWord(charset, encoding, text))
315
313
  );
316
314
  }
317
315
 
@@ -718,10 +716,7 @@ class Libmime {
718
716
  * @return {String} File extension
719
717
  */
720
718
  detectExtension(mimeType) {
721
- mimeType = (mimeType || '')
722
- .toString()
723
- .toLowerCase()
724
- .replace(/\s/g, '');
719
+ mimeType = (mimeType || '').toString().toLowerCase().replace(/\s/g, '');
725
720
  if (!(mimeType in mimetypes.list)) {
726
721
  return 'bin';
727
722
  }
@@ -751,13 +746,7 @@ class Libmime {
751
746
  * @return {String} File extension
752
747
  */
753
748
  detectMimeType(extension) {
754
- extension = (extension || '')
755
- .toString()
756
- .toLowerCase()
757
- .replace(/\s/g, '')
758
- .replace(/^\./g, '')
759
- .split('.')
760
- .pop();
749
+ extension = (extension || '').toString().toLowerCase().replace(/\s/g, '').replace(/^\./g, '').split('.').pop();
761
750
 
762
751
  if (!(extension in mimetypes.extensions)) {
763
752
  return 'application/octet-stream';
@@ -877,10 +866,7 @@ class Libmime {
877
866
 
878
867
  encodeURICharComponent(chr) {
879
868
  let res = '';
880
- let ord = chr
881
- .charCodeAt(0)
882
- .toString(16)
883
- .toUpperCase();
869
+ let ord = chr.charCodeAt(0).toString(16).toUpperCase();
884
870
 
885
871
  if (ord.length % 2) {
886
872
  ord = '0' + ord;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "libmime",
3
3
  "description": "Encode and decode quoted printable and base64 strings",
4
- "version": "4.1.3",
4
+ "version": "5.0.0",
5
5
  "main": "lib/libmime",
6
6
  "homepage": "https://github.com/andris9/libmime",
7
7
  "repository": {
@@ -19,19 +19,19 @@
19
19
  "test": "grunt"
20
20
  },
21
21
  "dependencies": {
22
- "iconv-lite": "0.4.24",
23
- "libbase64": "1.0.3",
22
+ "encoding-japanese": "1.0.30",
23
+ "iconv-lite": "0.6.2",
24
+ "libbase64": "1.2.1",
24
25
  "libqp": "1.1.0"
25
26
  },
26
27
  "devDependencies": {
27
28
  "chai": "4.2.0",
28
29
  "eslint-config-nodemailer": "1.2.0",
29
- "eslint-config-prettier": "4.3.0",
30
- "grunt": "1.0.4",
30
+ "eslint-config-prettier": "6.11.0",
31
+ "grunt": "1.2.1",
31
32
  "grunt-cli": "1.3.2",
32
- "grunt-eslint": "21.0.0",
33
+ "grunt-eslint": "23.0.0",
33
34
  "grunt-mocha-test": "0.13.3",
34
- "iconv": "^2.3.4",
35
- "mocha": "6.1.4"
35
+ "mocha": "8.0.1"
36
36
  }
37
37
  }