Skip to content

Commit d924d96

Browse files
committed
Merge remote-tracking branch 'origin/master' into delete-project-data
2 parents 55e1d43 + 6ef6835 commit d924d96

File tree

147 files changed

+6147
-2332
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

147 files changed

+6147
-2332
lines changed

src/compute/compute/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"@types/ws": "^8.5.9",
4141
"awaiting": "^3.0.0",
4242
"cookie": "^1.0.0",
43-
"debug": "^4.3.2",
43+
"debug": "^4.4.0",
4444
"websocketfs": "^0.17.4",
4545
"ws": "^8.18.0"
4646
},
@@ -52,6 +52,6 @@
5252
"devDependencies": {
5353
"@types/cookie": "^0.6.0",
5454
"@types/node": "^18.16.14",
55-
"typescript": "^5.6.3"
55+
"typescript": "^5.7.3"
5656
}
5757
}

src/compute/pnpm-lock.yaml

Lines changed: 34 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/packages/backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"@types/watchpack": "^2.4.4",
3737
"awaiting": "^3.0.0",
3838
"chokidar": "^3.6.0",
39-
"debug": "^4.3.2",
39+
"debug": "^4.4.0",
4040
"fs-extra": "^11.2.0",
4141
"lodash": "^4.17.21",
4242
"lru-cache": "^7.18.3",

src/packages/backend/sha1.test.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,32 @@
11
import { sha1, uuidsha1 } from "./sha1";
22

3+
const cocalc = "CoCalc";
4+
const hash = "c898c97dca68742a5a6331f9fa0ca02483cbfd25";
5+
const uuid = "c898c97d-ca68-4742-a5a6-331f9fa0ca02";
6+
37
describe("compute some sha1 hashes", () => {
4-
it("computes sha1 hash of old SageMathCloud", () => {
8+
// This is mainly for long term backwards compatibility
9+
it("SageMathCloud/string", () => {
510
expect(sha1("SageMathCloud")).toBe(
6-
"31acd8ca91346abcf6a49d2b1d88333f439d57a6"
11+
"31acd8ca91346abcf6a49d2b1d88333f439d57a6",
712
);
813
});
914

10-
it("computes sha1 hash of new CoCalc", () => {
11-
expect(sha1("CoCalc")).toBe("c898c97dca68742a5a6331f9fa0ca02483cbfd25");
15+
it("CoCalc/string", () => {
16+
expect(sha1(cocalc)).toBe(hash);
17+
});
18+
19+
it("CoCalc/Buffer", () => {
20+
expect(sha1(Buffer.from(cocalc))).toBe(hash);
1221
});
1322
});
1423

15-
describe("compute some uuids", () => {
16-
it("computes uuid associated to 'CoCalc'", () => {
17-
expect(uuidsha1("CoCalc")).toBe("c898c97d-ca68-4742-a5a6-331f9fa0ca02");
24+
describe("UUIDs", () => {
25+
it("CoCalc/string", () => {
26+
expect(uuidsha1(cocalc)).toBe(uuid);
27+
});
28+
29+
it("CoCalc/Buffer", () => {
30+
expect(uuidsha1(Buffer.from(cocalc))).toBe(uuid);
1831
});
1932
});

src/packages/backend/sha1.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,20 @@ import { createHash } from "crypto";
66

77
// compute sha1 hash of data in hex
88
export function sha1(data: Buffer | string): string {
9+
const sha1sum = createHash("sha1");
10+
911
if (typeof data === "string") {
10-
// CRITICAL: Code below assumes data is a Buffer; it will seem to work on a string, but give
11-
// the wrong result where wrong means that it doesn't agree with the frontend version defined
12-
// in misc.
13-
data = Buffer.from(data);
12+
sha1sum.update(data, "utf8");
13+
} else {
14+
// Convert Buffer to Uint8Array
15+
const uint8Array = new Uint8Array(
16+
data.buffer,
17+
data.byteOffset,
18+
data.byteLength,
19+
);
20+
sha1sum.update(uint8Array);
1421
}
15-
const sha1sum = createHash("sha1");
16-
sha1sum.update(data);
22+
1723
return sha1sum.digest("hex");
1824
}
1925

src/packages/backend/tcp/enable-messaging-protocol.ts

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Enable two new functions write_mesg and recv_mesg on a TCP socket.
99
1010
*/
1111

12+
import { Buffer } from "node:buffer";
1213
import { Socket } from "node:net";
1314

1415
import getLogger from "@cocalc/backend/logger";
@@ -43,54 +44,56 @@ export interface CoCalcSocket extends Socket {
4344
write_mesg: (
4445
type: Type,
4546
mesg: Message,
46-
cb?: (err?: string | Error) => void
47+
cb?: (err?: string | Error) => void,
4748
) => void;
4849
recv_mesg: (opts: RecvMesgOpts) => void;
4950
}
5051

5152
export default function enable(socket: CoCalcSocket, desc: string = "") {
5253
socket.setMaxListeners(500); // we use a lot of listeners for listening for messages
5354

54-
let buf: Buffer | null = null;
55+
let buf: Uint8Array | null = null;
5556
let bufTargetLength = -1;
5657

57-
const listenForMesg = (data: Buffer) => {
58-
buf = buf == null ? data : Buffer.concat([buf, data]);
58+
const listenForMesg = (data: Uint8Array) => {
59+
buf = buf == null ? data : new Uint8Array([...buf, ...data]);
5960
while (true) {
6061
if (bufTargetLength === -1) {
6162
// starting to read a new message
6263
if (buf.length >= 4) {
63-
bufTargetLength = buf.readUInt32BE(0) + 4;
64+
const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
65+
bufTargetLength = dv.getUint32(0) + 4;
6466
} else {
6567
return; // have to wait for more data to find out message length
6668
}
6769
}
6870
if (bufTargetLength <= buf.length) {
6971
// read a new message from our buffer
70-
const type = buf.slice(4, 5).toString();
72+
const type = String.fromCharCode(buf[4]);
7173
const mesg = buf.slice(5, bufTargetLength);
74+
75+
const textDecoder = new TextDecoder();
7276
switch (type) {
7377
case "j": // JSON
74-
const s = mesg.toString();
75-
let obj;
78+
const s = textDecoder.decode(mesg);
7679
try {
7780
// Do not use "obj = JSON.parse(s)"
78-
obj = from_json_socket(s); // this properly parses Date objects
81+
const obj = from_json_socket(s); // this properly parses Date objects
82+
socket.emit("mesg", "json", obj);
7983
} catch (err) {
8084
winston.debug(
8185
`WARNING: failed to parse JSON message='${trunc(
8286
s,
83-
512
84-
)}' on socket ${desc} - ${err}`
87+
512,
88+
)}' on socket ${desc} - ${err}`,
8589
);
8690
// skip it.
8791
return;
8892
}
89-
socket.emit("mesg", "json", obj);
9093
break;
9194
case "b": // BLOB (tagged by a uuid)
9295
socket.emit("mesg", "blob", {
93-
uuid: mesg.slice(0, 36).toString(),
96+
uuid: textDecoder.decode(mesg.slice(0, 36)),
9497
blob: mesg.slice(36),
9598
});
9699
break;
@@ -117,36 +120,34 @@ export default function enable(socket: CoCalcSocket, desc: string = "") {
117120
socket.write_mesg = (
118121
type: Type,
119122
data: Message,
120-
cb?: (err?: string | Error) => void
123+
cb?: (err?: string | Error) => void,
121124
): void => {
122125
if (data == null) {
123126
// uncomment this to get a traceback to see what might be causing this...
124127
//throw Error(`write_mesg(type='${type}': data must be defined`);
125128
cb?.(`write_mesg(type='${type}': data must be defined`);
126129
return;
127130
}
128-
const send = function (s: string | Buffer): void {
129-
const buf = Buffer.alloc(4);
131+
const send = function (s: string | ArrayBuffer): void {
132+
const length: Uint8Array = new Uint8Array(4);
130133
// This line was 4 hours of work. It is absolutely
131134
// *critical* to change the (possibly a string) s into a
132135
// buffer before computing its length and sending it!!
133136
// Otherwise unicode characters will cause trouble.
134-
if (typeof s === "string") {
135-
s = Buffer.from(s);
136-
}
137-
buf.writeInt32BE(s.length, 0);
138-
if (!socket.writable) {
139-
cb?.("socket not writable");
140-
return;
141-
} else {
142-
socket.write(buf);
143-
}
137+
const data: Uint8Array = new Uint8Array(
138+
typeof s === "string" ? Buffer.from(s) : s,
139+
);
140+
141+
const lengthView = new DataView(length.buffer);
142+
// this was buf.writeInt32BE, i.e. big endian
143+
lengthView.setInt32(0, data.byteLength, false); // false for big-endian
144144

145145
if (!socket.writable) {
146146
cb?.("socket not writable");
147147
return;
148148
} else {
149-
socket.write(s, cb);
149+
socket.write(length);
150+
socket.write(data, cb);
150151
}
151152
};
152153

@@ -164,11 +165,13 @@ export default function enable(socket: CoCalcSocket, desc: string = "") {
164165
return;
165166
}
166167
send(
167-
Buffer.concat([
168-
Buffer.from("b"),
169-
Buffer.from(data.uuid),
170-
Buffer.from(data.blob),
171-
])
168+
new Uint8Array([
169+
...Buffer.from("b"),
170+
...Buffer.from(data.uuid),
171+
...(Buffer.isBuffer(data.blob)
172+
? data.blob
173+
: Buffer.from(data.blob)),
174+
]).buffer,
172175
);
173176
return;
174177
default:

0 commit comments

Comments
 (0)