From 3b74c65a7d25e509e84ae32896f7ac595ade9673 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Fri, 7 Jun 2019 20:55:18 +0000 Subject: [PATCH] Bug 1556136 - Fix misuse of readline() leading to a minor memory leak in the JS shell. r=jwalden Differential Revision: https://phabricator.services.mozilla.com/D33529 --HG-- extra : moz-landing-system : lando --- js/src/shell/js.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 48f7396a0b64..d541369cfed2 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -17,6 +17,7 @@ #include "mozilla/ScopeExit.h" #include "mozilla/Sprintf.h" #include "mozilla/TimeStamp.h" +#include "mozilla/UniquePtrExtensions.h" // UniqueFreePtr #include "mozilla/Unused.h" #include "mozilla/Utf8.h" #include "mozilla/Variant.h" @@ -676,14 +677,14 @@ static void TraceGrayRoots(JSTracer* trc, void* data) { } } -static char* GetLine(FILE* file, const char* prompt) { +static mozilla::UniqueFreePtr GetLine(FILE* file, const char* prompt) { #ifdef EDITLINE /* * Use readline only if file is stdin, because there's no way to specify * another handle. Are other filehandles interactive? */ if (file == stdin) { - char* linep = readline(prompt); + mozilla::UniqueFreePtr linep(readline(prompt)); /* * We set it to zero to avoid complaining about inappropriate ioctl * for device in the case of EOF. Looks like errno == 251 if line is @@ -697,7 +698,7 @@ static char* GetLine(FILE* file, const char* prompt) { return nullptr; } if (linep[0] != '\0') { - add_history(linep); + add_history(linep.get()); } return linep; } @@ -710,25 +711,24 @@ static char* GetLine(FILE* file, const char* prompt) { } size_t size = 80; - char* buffer = static_cast(malloc(size)); + mozilla::UniqueFreePtr buffer(static_cast(malloc(size))); if (!buffer) { return nullptr; } - char* current = buffer; + char* current = buffer.get(); do { while (true) { if (fgets(current, size - len, file)) { break; } if (errno != EINTR) { - free(buffer); return nullptr; } } len += strlen(current); - char* t = buffer + len - 1; + char* t = buffer.get() + len - 1; if (*t == '\n') { /* Line was read. We remove '\n' and exit. */ *t = '\0'; @@ -737,14 +737,15 @@ static char* GetLine(FILE* file, const char* prompt) { if (len + 1 == size) { size = size * 2; - char* tmp = static_cast(realloc(buffer, size)); + char* raw = buffer.release(); + char* tmp = static_cast(realloc(raw, size)); if (!tmp) { - free(buffer); + free(raw); return nullptr; } - buffer = tmp; + buffer.reset(tmp); } - current = buffer + len; + current = buffer.get() + len; } while (true); return buffer; } @@ -1359,7 +1360,8 @@ static MOZ_MUST_USE bool ReadEvalPrintLoop(JSContext* cx, FILE* in, sc->serviceInterrupt = false; errno = 0; - char* line = GetLine(in, startline == lineno ? "js> " : ""); + mozilla::UniqueFreePtr line = + GetLine(in, startline == lineno ? "js> " : ""); if (!line) { if (errno) { /* @@ -1373,7 +1375,8 @@ static MOZ_MUST_USE bool ReadEvalPrintLoop(JSContext* cx, FILE* in, break; } - if (!buffer.append(line, strlen(line)) || !buffer.append('\n')) { + if (!buffer.append(line.get(), strlen(line.get())) || + !buffer.append('\n')) { return false; }