yencode 1.1.3 → 1.1.4

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/src/platform.cc CHANGED
@@ -2,12 +2,6 @@
2
2
  #ifdef PLATFORM_ARM
3
3
  # ifdef __ANDROID__
4
4
  # include <cpu-features.h>
5
- # elif defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD__ >= 12)
6
- # include <sys/auxv.h>
7
- # include <asm/hwcap.h>
8
- # elif (defined(__FreeBSD__) && __FreeBSD__ < 12)
9
- # include <sys/sysctl.h>
10
- # include <asm/hwcap.h>
11
5
  # elif defined(_WIN32)
12
6
  # define WIN32_LEAN_AND_MEAN
13
7
  # define NOMINMAX
@@ -15,6 +9,13 @@
15
9
  # elif defined(__APPLE__)
16
10
  # include <sys/types.h>
17
11
  # include <sys/sysctl.h>
12
+ # elif defined(__has_include)
13
+ # if __has_include(<sys/auxv.h>)
14
+ # include <sys/auxv.h>
15
+ # if __has_include(<asm/hwcap.h>)
16
+ # include <asm/hwcap.h>
17
+ # endif
18
+ # endif
18
19
  # endif
19
20
  bool cpu_supports_neon() {
20
21
  # if defined(AT_HWCAP)
@@ -48,7 +49,11 @@ bool cpu_supports_neon() {
48
49
  return false;
49
50
  return (bool)supported;
50
51
  # endif
51
- return true; // assume NEON support, if compiled as such, otherwise (I think Windows and iOS require it)
52
+ # ifdef __aarch64__
53
+ return true; // assume NEON support on AArch64
54
+ # else
55
+ return false;
56
+ # endif
52
57
  }
53
58
  #endif
54
59
 
@@ -121,13 +126,32 @@ int cpu_supports_isa() {
121
126
  return ret | ISA_LEVEL_SSSE3;
122
127
 
123
128
  if(flags[2] & 0x80000) { // SSE4.1
124
- if((flags[2] & 0x18800000) == 0x18800000) { // POPCNT + OSXSAVE + AVX
129
+ if((flags[2] & 0x1C800000) == 0x1C800000) { // POPCNT + OSXSAVE + XSAVE + AVX
125
130
  int xcr = _GET_XCR() & 0xff; // ignore unused bits
126
131
  if((xcr & 6) == 6) { // AVX enabled
127
132
  int cpuInfo[4];
128
133
  _cpuidX(cpuInfo, 7, 0);
129
134
  if((cpuInfo[1] & 0x128) == 0x128 && (ret & ISA_FEATURE_LZCNT)) { // BMI2 + AVX2 + BMI1
135
+
136
+ // check AVX10
137
+ int cpuInfo2[4];
138
+ _cpuidX(cpuInfo2, 7, 1);
139
+ if(cpuInfo2[3] & 0x80000) {
140
+ _cpuidX(cpuInfo2, 0x24, 0);
141
+ if((cpuInfo2[2] & 0xff) >= 1 && ( // minimum AVX10.1
142
+ #ifdef YENC_DISABLE_AVX256
143
+ cpuInfo2[2] & 0x10000 // AVX10/128
144
+ #else
145
+ cpuInfo2[2] & 0x20000 // AVX10/256
146
+ #endif
147
+ )) {
148
+ if(((xcr & 0xE0) == 0xE0) && (cpuInfo2[2] & 0x40000)) ret |= ISA_FEATURE_EVEX512;
149
+ return ret | ISA_LEVEL_VBMI2;
150
+ }
151
+ }
152
+
130
153
  if(((xcr & 0xE0) == 0xE0) && (cpuInfo[1] & 0xC0010000) == 0xC0010000) { // AVX512BW + AVX512VL + AVX512F
154
+ ret |= ISA_FEATURE_EVEX512;
131
155
  if(cpuInfo[2] & 0x40)
132
156
  return ret | ISA_LEVEL_VBMI2;
133
157
  return ret | ISA_LEVEL_AVX3;
@@ -150,7 +174,7 @@ int cpu_supports_crc_isa() {
150
174
  _cpuid1(flags);
151
175
 
152
176
  if((flags[2] & 0x80202) == 0x80202) { // SSE4.1 + SSSE3 + CLMUL
153
- if((flags[2] & 0x18000000) == 0x18000000) { // OSXSAVE + AVX
177
+ if((flags[2] & 0x1C000000) == 0x1C000000) { // AVX + OSXSAVE + XSAVE
154
178
  int xcr = _GET_XCR() & 0xff; // ignore unused bits
155
179
  if((xcr & 6) == 6) { // AVX enabled
156
180
  int cpuInfo[4];
@@ -166,3 +190,27 @@ int cpu_supports_crc_isa() {
166
190
  }
167
191
 
168
192
  #endif // PLATFORM_X86
193
+
194
+ #ifdef __riscv
195
+ # if defined(__has_include)
196
+ # if __has_include(<sys/auxv.h>)
197
+ # include <sys/auxv.h>
198
+ # if __has_include(<asm/hwcap.h>)
199
+ # include <asm/hwcap.h>
200
+ # endif
201
+ # endif
202
+ # endif
203
+ bool cpu_supports_rvv() {
204
+ # if defined(AT_HWCAP)
205
+ unsigned long ret;
206
+ # ifdef __FreeBSD__
207
+ elf_aux_info(AT_HWCAP, &ret, sizeof(ret));
208
+ # else
209
+ ret = getauxval(AT_HWCAP);
210
+ # endif
211
+ return (ret & 0x20112D) == 0x20112D; // IMAFDCV; TODO: how to detect Z* features of 'G'?
212
+ # endif
213
+ return false;
214
+ }
215
+ #endif
216
+
@@ -0,0 +1,6 @@
1
+ // used by GYP to test if posix_memalign needs declarations
2
+ #include "common.h"
3
+ void f() {
4
+ void* p;
5
+ ALIGN_ALLOC(p, 16, 16);
6
+ }
@@ -5,31 +5,32 @@ var trials = 8;
5
5
  var asyncWait = 1000;
6
6
 
7
7
  var maxSize = require('./_maxsize');
8
- var decimal = (''+1.1).substr(1, 1);
8
+ var allocBuffer = (Buffer.allocUnsafe || Buffer);
9
+ var decimal = (''+1.1).substring(1, 2);
9
10
  var fmtSpeed = function(size, time) {
10
11
  var rate = ('' + (Math.round(100*(size/1048576)/time)/100)).split(decimal);
11
12
 
12
- return (' ' + rate[0]).substr(-8) + decimal + ((rate[1]|0) + '00').substr(0, 2) + ' MiB/s';
13
+ return (' ' + rate[0]).slice(-8) + decimal + ((rate[1]|0) + '00').substring(0, 2) + ' MiB/s';
13
14
  };
14
15
  var initBuffers = function() {
15
- module.exports.bufWorst = new Buffer(sz);
16
- module.exports.bufBest = new Buffer(sz);
16
+ module.exports.bufWorst = allocBuffer(sz);
17
+ module.exports.bufBest = allocBuffer(sz);
17
18
  module.exports.bufAvg = [];
18
19
  module.exports.bufAvg2x = [];
19
- module.exports.bufTarget = new Buffer(maxSize(sz));
20
+ module.exports.bufTarget = allocBuffer(maxSize(sz));
20
21
 
21
22
  module.exports.bufWorst.fill(224);
22
23
  module.exports.bufBest.fill(0);
23
24
 
24
25
  // use cipher as a fast, consistent RNG
25
- var cipher = require('crypto').createCipher;
26
- [['aes-128-cbc', 'my_incredibly_strong_password'],
27
- ['rc4', 'my_incredibly_strong_password'],
28
- ['aes-128-cbc', '9h8a08b08qpklnac']
26
+ var cipher = require('crypto').createCipheriv;
27
+ [['aes-128-cbc', 'my_incredible_pw', ' '],
28
+ ['aes-128-cbc', 'nfa807g2lablzxk1', ' '],
29
+ ['aes-128-cbc', '3h89sdg923jnkbas', ' ']
29
30
  ].forEach(function(cargs) {
30
31
  var rand = cipher.apply(null, cargs);
31
32
  var data = Buffer.concat([rand.update(module.exports.bufBest), rand.final()]).slice(0, sz);
32
- module.exports.bufAvg.push(new Buffer(data));
33
+ module.exports.bufAvg.push(Buffer.concat([data]));
33
34
 
34
35
  // all yEnc special characters exist in range 0-61 (post shift) or 214-19 (pre-shift)
35
36
  // to generate biased data, we'll pack the range down (64-191 will get packed to 192-63)
@@ -83,7 +84,7 @@ module.exports = {
83
84
  run: function(name, fn, sz2) {
84
85
  var time = module.exports.bench(fn);
85
86
  console.log(
86
- (name+' ').substr(0, 25) + ':'
87
+ (name+' ').substring(0, 25) + ':'
87
88
  + fmtSpeed(sz*rounds, time)
88
89
  + (sz2 ? (' ' + fmtSpeed(sz2*rounds, time)) : '')
89
90
  );
package/test/speeddec.js CHANGED
@@ -1,17 +1,18 @@
1
1
  var y = require('../build/Release/yencode');
2
2
  var _ = require('./_speedbase');
3
+ var allocBuffer = (Buffer.allocUnsafe || Buffer);
3
4
 
4
5
  var bufSize = _.bufTarget.length;
5
6
 
6
- var mWorst = new Buffer(bufSize);
7
+ var mWorst = allocBuffer(bufSize);
7
8
  var mAvg = _.bufAvg.map(function() {
8
- return new Buffer(bufSize);
9
+ return allocBuffer(bufSize);
9
10
  });
10
11
  var mAvg2x = _.bufAvg2x.map(function() {
11
- return new Buffer(bufSize);
12
+ return allocBuffer(bufSize);
12
13
  });
13
- var mBest = new Buffer(bufSize);
14
- var mBest2 = new Buffer(_.size);
14
+ var mBest = allocBuffer(bufSize);
15
+ var mBest2 = allocBuffer(_.size);
15
16
  mBest2.fill(32);
16
17
 
17
18
  var lenWorst = y.encodeTo(_.bufWorst, mWorst);
package/test/testdec.js CHANGED
@@ -1,5 +1,8 @@
1
1
  // a basic script to test that raw yEnc works as expected
2
2
 
3
+ var allocBuffer = (Buffer.allocUnsafe || Buffer);
4
+ var toBuffer = (Buffer.alloc ? Buffer.from : Buffer);
5
+
3
6
  var assert = require('assert');
4
7
  var y = (function() {
5
8
  try {
@@ -14,12 +17,12 @@ var ord = function(c) {
14
17
  // slow reference yEnc implementation
15
18
  var refYDec = function(src, findEnd) {
16
19
  var ret = [];
17
- if(findEnd && chr(src[0]) == '=' && chr(src[1]) == 'y') return new Buffer(0);
20
+ if(findEnd && chr(src[0]) == '=' && chr(src[1]) == 'y') return allocBuffer(0);
18
21
  for (var i = 0; i < src.length; i++) {
19
22
  switch(chr(src[i])) {
20
23
  case '\r':
21
24
  if(findEnd && chr(src[i+1]) == '\n' && chr(src[i+2]) == '=' && chr(src[i+3]) == 'y')
22
- return new Buffer(ret);
25
+ return toBuffer(ret);
23
26
  case '\n': continue;
24
27
  case '=':
25
28
  i++;
@@ -30,7 +33,7 @@ var refYDec = function(src, findEnd) {
30
33
  }
31
34
  ret.push((src[i] - 42) & 0xFF);
32
35
  }
33
- return new Buffer(ret);
36
+ return toBuffer(ret);
34
37
  };
35
38
  var refYDecRaw = function(src, findEnd) {
36
39
  // undo NNTP layer
@@ -39,7 +42,7 @@ var refYDecRaw = function(src, findEnd) {
39
42
  if(src[0] == ord('.')) {
40
43
  i++;
41
44
  if(findEnd && src[1] == ord('\r') && src[2] == ord('\n'))
42
- return new Buffer(0);
45
+ return allocBuffer(0);
43
46
  }
44
47
  // TODO: do leading/trailing spaces/tabs need to be trimmed?
45
48
  for(; i<src.length; i++) {
@@ -61,17 +64,24 @@ var refYDecRaw = function(src, findEnd) {
61
64
  var testFuncs = [
62
65
  {l: 'nntp', r: refYDecRaw, a: function(s) {
63
66
  return y.decode(s, true);
67
+ }, i: function(b) {
68
+ return y.decodeTo(b, b, true);
69
+ }},
70
+ {l: 'plain', r: refYDec, a: y.decode, i: function(b) {
71
+ return y.decodeTo(b, b, false);
64
72
  }},
65
- {l: 'plain', r: refYDec, a: y.decode},
66
73
  {l: 'nntp-end', r: function(s) {
67
74
  return refYDecRaw(s, true);
68
75
  }, a: function(s) {
69
76
  if(!s.length) return Buffer(0);
70
77
  return y.decodeIncr(s).output;
78
+ }, i: function(b) {
79
+ if(!b.length) return 0;
80
+ return y.decodeIncr(b, 0, b).written;
71
81
  }}
72
82
  ];
73
83
  var doTest = function(msg, data, expected) {
74
- data = new Buffer(data);
84
+ data = toBuffer(data);
75
85
 
76
86
  var prepad = 48, postpad = 48;
77
87
  if(data.length > 1024) {
@@ -80,17 +90,17 @@ var doTest = function(msg, data, expected) {
80
90
  }
81
91
 
82
92
  for(var i=0; i<prepad; i++) {
83
- var pre = new Buffer(i);
93
+ var pre = allocBuffer(i);
84
94
  pre.fill(1);
85
95
  for(var j=0; j<postpad; j++) {
86
96
  testFuncs.forEach(function(f) {
87
- var post = new Buffer(j);
97
+ var post = allocBuffer(j);
88
98
  post.fill(1);
89
99
 
90
100
  var testData = Buffer.concat([pre, data, post]);
91
101
  var x;
92
102
  if(expected === undefined) x = f.r(testData).toString('hex');
93
- else x = new Buffer(expected).toString('hex').replace(/ /g, '');
103
+ else x = toBuffer(expected).toString('hex').replace(/ /g, '');
94
104
  var actual = f.a(testData).toString('hex');
95
105
  if(actual != x) {
96
106
  console.log('Actual:', actual);
@@ -98,6 +108,14 @@ var doTest = function(msg, data, expected) {
98
108
  console.log('Source:', data.toString('hex'));
99
109
  assert.equal(actual, x, msg + ' [' + i + '/' + j + ' ' + f.l + ']');
100
110
  }
111
+ // also test in-situ decoding
112
+ var ilen = f.i(testData);
113
+ actual = testData.slice(0, ilen).toString('hex');
114
+ if(actual != x) {
115
+ console.log('Actual:', actual);
116
+ console.log('Expect:', x);
117
+ assert.equal(actual, x, msg + ' (in-situ) [' + i + '/' + j + ' ' + f.l + ']');
118
+ }
101
119
  });
102
120
  if(expected !== undefined) return; // if given expected string, only do one test
103
121
 
@@ -137,7 +155,7 @@ doTest('Bad escape, Yenc end sequence', '=\r\n=y');
137
155
 
138
156
 
139
157
  // longer tests
140
- var b = new Buffer(256);
158
+ var b = allocBuffer(256);
141
159
  b.fill(0);
142
160
  doTest('Long no escaping', b);
143
161
  b.fill('='.charCodeAt(0));
@@ -155,9 +173,7 @@ b.fill(223);
155
173
  doTest('Long all tabs', b);
156
174
 
157
175
  // test for past bug in ARMv8 NEON decoder where nextMask wasn't properly compensated for
158
- doTest('Extra null issue', new Buffer('2e900a4fb6054c9126171cdc196dc41237bb1b76da9191aa5e85c1d2a2a5c638fe39054a210e8c799473cd510541fd118f3904b242a9938558c879238aae1d3bdab32e287cedb820b494f54ffae6dd0b13f73a4a9499df486a7845c612182bcef72a6e50a8e98351c35765d26c605115dc8c5c56a5e3f20ae6da8dcd78536e6d1601eb1fc3ddc774', 'hex'));
159
- // end detection bug
160
- doTest('End detect', new Buffer('612e6161610d610d612e793d3d0d0d2e612e2e0a0d0d61792e3d3d61612e0d0a2e0d2e0a0d79612e0a3d2e2e793d2e610a0d0a0a2e793d790d612e61612e0a3d792e2e3d2e7961793d792e0a61790a0d0a2e0d0a3d0a0d0d0d0a610a0a6161792e3d2e0a2e0d0d0d613d610a0a0a793d613d3d0a3d790d3d0a0a2e2e7979796179613d0d2e792e793d3d61792e612e2e2e793d616161790d0d2e0d0d793d0d790a0a3d0d617979790d2e0d792e612e610a0a0a0a0a79790d0a610d612e0d0a0d3d0a61792e2e0a790d0d792e790d0a2e79612e3d0a79790a0d0d3d0a0a0d3d0a7961610a2e613d792e0a612e613d610a2e0a0a79613d2e2e0d3d3d2e793d792e792e0d0d610d2e2e0d2e79610d2e790d790d3d2e3d790a0a0d0a0a0a612e2e79612e0d2e3d793d2e0a2e3d790a2e3d792e2e610d3d2e0d3d3d0a3d2e0d613d2e0d61610a3d0a2e0a0a3d3d612e3d790d6161613d3d612e3d0d0a2e0d0d0d616179790a2e3d610d612e0d2e3d0d0a3d610d0d61610a7961613d2e790d613d610a3d612e0a2e0d79790d0a610a2e2e0a2e612e2e0d792e61610a2e0d610d3d0a793d613d0d3d0a3d0d0a613d2e0a3d610a3d0d793d0d7979792e3d613d0a2e61610d793d2e0a0a2e612e0d2e2e792e0d2e613d0d790a0d2e610d2e0a2e61793d0d0d0a0a0d0d2e2e0d2e793d3d79612e0a610a610a0d610d0d2e2e790', 'hex'));
176
+ doTest('Extra null issue', toBuffer('2e900a4fb6054c9126171cdc196dc41237bb1b76da9191aa5e85c1d2a2a5c638fe39054a210e8c799473cd510541fd118f3904b242a9938558c879238aae1d3bdab32e287cedb820b494f54ffae6dd0b13f73a4a9499df486a7845c612182bcef72a6e50a8e98351c35765d26c605115dc8c5c56a5e3f20ae6da8dcd78536e6d1601eb1fc3ddc774', 'hex'));
161
177
 
162
178
  // random tests
163
179
  for(var i=0; i<32; i++) {
@@ -168,7 +184,7 @@ for(var i=0; i<32; i++) {
168
184
  // targeted random tests
169
185
  var charset = '=\r\n.ay';
170
186
  var randStr = function(n) {
171
- var ret = new Buffer(n);
187
+ var ret = allocBuffer(n);
172
188
  for(var i=0; i<n; i++)
173
189
  ret[i] = ord(charset[(Math.random() * charset.length) | 0]);
174
190
  return ret;
package/test/testenc.js CHANGED
@@ -1,6 +1,9 @@
1
1
  // a basic script to test that raw yEnc works as expected
2
2
 
3
3
  var assert = require('assert');
4
+ var allocBuffer = (Buffer.allocUnsafe || Buffer);
5
+ var toBuffer = (Buffer.alloc ? Buffer.from : Buffer);
6
+
4
7
  var y = (function() {
5
8
  try {
6
9
  return require('../build/Debug/yencode.node');
@@ -47,10 +50,10 @@ var refYEnc = function(src, line_size, col) {
47
50
  ret.push((c+64) & 0xFF);
48
51
  }
49
52
 
50
- return new Buffer(ret);
53
+ return toBuffer(ret);
51
54
  };
52
55
  var doTest = function(msg, test, expected) {
53
- test[0] = new Buffer(test[0]);
56
+ test[0] = toBuffer(test[0]);
54
57
  if(!test[1]) test[1] = 128; // line size
55
58
  if(!test[2]) test[2] = 0; // column offset
56
59
 
@@ -64,7 +67,7 @@ var doTest = function(msg, test, expected) {
64
67
  assert.equal(actual, expected, msg);
65
68
  }
66
69
 
67
- var buf = new Buffer(maxSize(test[0].length, test[1]));
70
+ var buf = allocBuffer(maxSize(test[0].length, test[1]));
68
71
  var len = y.encodeTo.apply(null, [test[0], buf].concat(test.slice(1)));
69
72
  assert.equal(buf.slice(0, len).toString('hex'), expected, msg);
70
73
  };
@@ -97,7 +100,7 @@ var runLineSizes = function(fn) {
97
100
  // simple tests
98
101
  runLineSizes(function(ls, offs) {
99
102
  var infoStr = ' [ls='+ls+', offs='+offs+']';
100
- var b = new Buffer(256);
103
+ var b = allocBuffer(256);
101
104
  b.fill(0);
102
105
  doTest('Long no escaping' + infoStr, [b, ls]);
103
106
  b.fill(227);
@@ -110,7 +113,7 @@ runLineSizes(function(ls, offs) {
110
113
 
111
114
  // case tests
112
115
  var padLens = range(0, 35).concat(range(46, 51)).concat(range(62, 67));
113
- var padding = new Buffer(128);
116
+ var padding = allocBuffer(128);
114
117
  padding.fill(97); // 'a'
115
118
  [ ['Empty test', [[]], ''],
116
119
  ['Simple test', [[0,1,2,3,224,4]]],
@@ -127,7 +130,7 @@ padding.fill(97); // 'a'
127
130
  // if no defined result, try padding the data to make it long enough to invoke SIMD behaviour
128
131
  padLens.forEach(function(prepad) {
129
132
  padLens.forEach(function(postpad) {
130
- var newBuf = Buffer.concat([padding.slice(0, prepad), new Buffer(test[1][0]), padding.slice(0, postpad)]);
133
+ var newBuf = Buffer.concat([padding.slice(0, prepad), toBuffer(test[1][0]), padding.slice(0, postpad)]);
131
134
  var newTest = test.slice();
132
135
  newTest[1] = [newBuf].concat(newTest[1].slice(1));
133
136
  doTest.apply(null, newTest);
@@ -147,7 +150,7 @@ for(var i=0; i<32; i++) {
147
150
  // targeted random tests
148
151
  var charset = 'a\xd6\xdf\xe0\xe3\xf6\x04\x13';
149
152
  var randStr = function(n) {
150
- var ret = new Buffer(n);
153
+ var ret = allocBuffer(n);
151
154
  for(var i=0; i<n; i++)
152
155
  ret[i] = charset[(Math.random() * charset.length) | 0].charCodeAt(0);
153
156
  return ret;
@@ -1,6 +1,7 @@
1
1
 
2
2
  var assert = require('assert');
3
3
  var y = require('../index.js');
4
+ var toBuffer = (Buffer.alloc ? Buffer.from : Buffer);
4
5
 
5
6
  var assertObjectHas = function(obj, required) {
6
7
  for(var k in required) {
@@ -23,7 +24,7 @@ postData = [
23
24
  '=yend size=10 part=5 pcrc32=97f4bd52',
24
25
  ''
25
26
  ].join('\r\n');
26
- post = y.from_post(new Buffer(postData));
27
+ post = y.from_post(toBuffer(postData));
27
28
  assertObjectHas(post, {
28
29
  yencStart: 0,
29
30
  dataStart: postData.indexOf('...'),
@@ -59,7 +60,7 @@ postData = [
59
60
  '.... data',
60
61
  '=yend size=2 pcrc32=invalid pcrc32=invalid invalid_prop',
61
62
  ].join('\r\n');
62
- post = y.from_post(new Buffer(postData));
63
+ post = y.from_post(toBuffer(postData));
63
64
  assertObjectHas(post, {
64
65
  yencStart: postData.indexOf('=ybegin'),
65
66
  dataStart: postData.indexOf('...'),
@@ -97,7 +98,7 @@ postData = [
97
98
  '=yend size=0',
98
99
  ''
99
100
  ].join('\r\n');
100
- post = y.from_post(new Buffer(postData));
101
+ post = y.from_post(toBuffer(postData));
101
102
  assertObjectHas(post, {
102
103
  yencStart: 0,
103
104
  dataStart: undefined,
@@ -117,9 +118,9 @@ assertObjectHas(post, {
117
118
 
118
119
 
119
120
  // test parse errors
120
- post = y.from_post(new Buffer('invalid post'));
121
+ post = y.from_post(toBuffer('invalid post'));
121
122
  assert.equal(post.code, 'no_start_found');
122
- post = y.from_post(new Buffer('=ybegin abc=def'));
123
+ post = y.from_post(toBuffer('=ybegin abc=def'));
123
124
  assert.equal(post.code, 'no_end_found');
124
125
 
125
126