Skip to content

Commit

Permalink
[FIX] fixed an issue where the encoding data was not working correctl…
Browse files Browse the repository at this point in the history
…y as the base library was using a fast encoding/decoding algorithm which doesn't work correctly for higher UTF code-points. The fix simply delegates to standard TextEncoder/TextDecoder. (#238)

FIX #237
  • Loading branch information
aricart committed Dec 20, 2021
1 parent d698a5a commit 5daf26f
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 27 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
environment: CI
strategy:
matrix:
deno-version: [1.16.3]
deno-version: [1.17.0]

steps:
- name: Git Checkout Deno Module
Expand Down
40 changes: 23 additions & 17 deletions nats-base-client/encoders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,37 @@ import { Empty } from "./types.ts";
export const TE = new TextEncoder();
export const TD = new TextDecoder();

export function fastEncoder(...a: string[]): Uint8Array {
let len = 0;
function concat(...bufs: Uint8Array[]): Uint8Array {
let max = 0;
for (let i = 0; i < bufs.length; i++) {
max += bufs[i].length;
}
const out = new Uint8Array(max);
let index = 0;
for (let i = 0; i < bufs.length; i++) {
out.set(bufs[i], index);
index += bufs[i].length;
}
return out;
}

export function encode(...a: string[]): Uint8Array {
const bufs = [];
for (let i = 0; i < a.length; i++) {
len += a[i] ? a[i].length : 0;
bufs.push(TE.encode(a[i]));
}
if (len === 0) {
if (bufs.length === 0) {
return Empty;
}
const buf = new Uint8Array(len);
let c = 0;
for (let i = 0; i < a.length; i++) {
const s = a[i];
if (s) {
for (let j = 0; j < s.length; j++) {
buf[c] = s.charCodeAt(j);
c++;
}
}
if (bufs.length === 1) {
return bufs[0];
}
return buf;
return concat(...bufs);
}

export function fastDecoder(a: Uint8Array): string {
export function decode(a: Uint8Array): string {
if (!a || a.length === 0) {
return "";
}
return String.fromCharCode(...a);
return TD.decode(a);
}
16 changes: 8 additions & 8 deletions nats-base-client/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import type { Request } from "./request.ts";
import { Heartbeat, PH } from "./heartbeats.ts";
import { Kind, MsgArg, Parser, ParserEvent } from "./parser.ts";
import { MsgImpl } from "./msg.ts";
import { fastDecoder, fastEncoder } from "./encoders.ts";
import { decode, encode } from "./encoders.ts";

const FLUSH_THRESHOLD = 1024 * 32;

Expand All @@ -67,8 +67,8 @@ export function createInbox(prefix = ""): string {
return `${prefix}.${nuid.next()}`;
}

const PONG_CMD = fastEncoder("PONG\r\n");
const PING_CMD = fastEncoder("PING\r\n");
const PONG_CMD = encode("PONG\r\n");
const PING_CMD = encode("PING\r\n");

export class Connect {
echo?: boolean;
Expand Down Expand Up @@ -413,7 +413,7 @@ export class ProtocolHandler implements Dispatcher<ParserEvent> {
}

async processError(m: Uint8Array) {
const s = fastDecoder(m);
const s = decode(m);
const err = ProtocolHandler.toError(s);
const handled = this.subscriptions.handleError(err);
if (!handled) {
Expand Down Expand Up @@ -455,7 +455,7 @@ export class ProtocolHandler implements Dispatcher<ParserEvent> {
}

processInfo(m: Uint8Array) {
const info = JSON.parse(fastDecoder(m));
const info = JSON.parse(decode(m));
this.info = info;
const updates = this.options && this.options.ignoreClusterUpdates
? undefined
Expand All @@ -480,7 +480,7 @@ export class ProtocolHandler implements Dispatcher<ParserEvent> {
}
const cs = JSON.stringify(c);
this.transport.send(
fastEncoder(`CONNECT ${cs}${CR_LF}`),
encode(`CONNECT ${cs}${CR_LF}`),
);
this.transport.send(PING_CMD);
} catch (err) {
Expand Down Expand Up @@ -531,7 +531,7 @@ export class ProtocolHandler implements Dispatcher<ParserEvent> {
const len = this.outbound.length();
let buf: Uint8Array;
if (typeof cmd === "string") {
buf = fastEncoder(cmd);
buf = encode(cmd);
} else {
buf = cmd as Uint8Array;
}
Expand Down Expand Up @@ -669,7 +669,7 @@ export class ProtocolHandler implements Dispatcher<ParserEvent> {
}
});
if (cmds.length) {
this.transport.send(fastEncoder(cmds.join("")));
this.transport.send(encode(cmds.join("")));
}
}

Expand Down
17 changes: 17 additions & 0 deletions tests/auth_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ Deno.test("auth - bad", async () => {
await ns.stop();
});

Deno.test("auth - weird chars", async () => {
const pass = "§12§12§12";
const ns = await NatsServer.start({
authorization: {
username: "admin",
password: pass,
},
});

const nc = await connect(
{ port: ns.port, user: "admin", pass: pass },
);
await nc.flush;
await nc.close();
await ns.stop();
});

Deno.test("auth - un/pw", async () => {
const ns = await NatsServer.start(conf);
const nc = await connect(
Expand Down
5 changes: 4 additions & 1 deletion tests/tls_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,10 @@ Deno.test("tls - custom ca fails without root", async () => {
.catch((err) => {
// this is a bogus error name - but at least we know we are rejected
assertEquals(err.name, "InvalidData");
assertEquals(err.message, "invalid certificate: UnknownIssuer");
assertEquals(
err.message,
"invalid peer certificate contents: invalid peer certificate: UnknownIssuer",
);
lock.unlock();
});

Expand Down

0 comments on commit 5daf26f

Please sign in to comment.