Skip to content

Commit

Permalink
Fix crash and memory leak in watch calls
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucaber committed Feb 28, 2024
1 parent e66f8e9 commit 104409c
Showing 1 changed file with 29 additions and 18 deletions.
47 changes: 29 additions & 18 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ export class KubernetesRESTClient implements IKubernetesRESTClient {
};
const request = client.request(requestHeaders);

let body = "";
let lastResponse = "";
let buffer = "";

request.on("error", (err: any) => {
Expand Down Expand Up @@ -227,7 +227,7 @@ export class KubernetesRESTClient implements IKubernetesRESTClient {
}

try {
const parsedBody = JSON.parse(body);
const parsedBody = JSON.parse(lastResponse);

if (isStatus(parsedBody) && parsedBody.status === "Failure") {
debug("watch: failed with status %O", parsedBody);
Expand All @@ -249,28 +249,39 @@ export class KubernetesRESTClient implements IKubernetesRESTClient {
debug("WATCH request on %o received %d bytes of data", absoluteURL, chunk.length);

buffer += chunk;
body += chunk;

let parts = buffer.split('\n');

// the last part is either empty or a part of the following incomplete line
buffer = parts.pop() ?? "";

if (buffer !== "") {
lastResponse = buffer
} else if (parts.length > 0) {
lastResponse = parts[parts.length - 1]
}

// Line is not yet complete; wait for next chunk.
if (!buffer.endsWith("\n")) {
if (parts.length === 0) {
return;
}

try {
const obj: WatchEvent<R> = JSON.parse(buffer);
buffer = "";

const resourceVersion = obj.object.metadata.resourceVersion
? parseInt(obj.object.metadata.resourceVersion, 10)
: -1;
if (resourceVersion > lastVersion) {
debug(`watch: emitting ${obj.type} event for ${obj.object.metadata.name}`);

lastVersion = resourceVersion;
onUpdate(obj).catch(onError);
for (const part of parts) {
try {
const obj: WatchEvent<R> = JSON.parse(part);

const resourceVersion = obj.object.metadata.resourceVersion
? parseInt(obj.object.metadata.resourceVersion, 10)
: -1;
if (resourceVersion > lastVersion) {
debug(`watch: emitting ${obj.type} event for ${obj.object.metadata.name}`);

lastVersion = resourceVersion;
onUpdate(obj).catch(onError);
}
} catch (err) {
onError(err);
}
} catch (err) {
onError(err);
}
});
});
Expand Down

0 comments on commit 104409c

Please sign in to comment.