Fix EscapeSequence::encode returning a StringRef pointing to stack memory.

This commit is contained in:
Frederich Munch 2017-02-15 16:35:00 -05:00 committed by sftnight
parent e66b1ce62f
commit 5c66b41851
3 changed files with 26 additions and 8 deletions

View File

@ -10,8 +10,9 @@
#ifndef CLING_UTILS_UTF8_H
#define CLING_UTILS_UTF8_H
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/raw_ostream.h"
#include <locale>
#include <string>
namespace cling {
@ -64,6 +65,7 @@ namespace cling {
public:
EscapeSequence();
///\brief Encode the bytes from Str into a representation capable of
/// being printed in the current locale without data loss.
/// When Str begins with any of the C++ unicode string literal
@ -71,8 +73,16 @@ namespace cling {
///
/// \param [in] Str - Start of bytes to convert
/// \param [in] N - Number of bytes to convert
/// \param [in] Output - Ouput stream to write to
///
llvm::StringRef encode(const char* const Str, size_t N);
/// \return 'Output' to allow: EscapeSequence().encode(...) << "";
///
llvm::raw_ostream& encode(const char* const Str, size_t N,
llvm::raw_ostream& Output);
///\brief Overload for above returning a std::string.
///
std::string encode(const char* const Str, size_t N);
};
}
}

View File

@ -250,8 +250,8 @@ namespace cling {
case '\"':
if (N > 2 && Data[N-1] == '\"') {
// Drop the terminating " so Utf-8 errors can be detected ("\xeA")
Out << Type << ' '
<< utils::utf8::EscapeSequence().encode(Data, N-1) << "\"\n";
Out << Type << ' ';
utils::utf8::EscapeSequence().encode(Data, N-1, Out) << "\"\n";
return;
}
default:

View File

@ -7,11 +7,11 @@
// LICENSE.TXT for details.
//------------------------------------------------------------------------------
#include "cling/Utils/Output.h"
#include "cling/Utils/UTF8.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
#ifdef LLVM_ON_WIN32
#include <Shlwapi.h>
@ -254,7 +254,8 @@ EscapeSequence::EscapeSequence() : m_Utf8Out(false) {
#endif
}
llvm::StringRef EscapeSequence::encode(const char* const Start, size_t N) {
llvm::raw_ostream& EscapeSequence::encode(const char* const Start, size_t N,
llvm::raw_ostream& Output) {
const char* Ptr = Start;
const char* const End = Start + N;
@ -271,7 +272,7 @@ llvm::StringRef EscapeSequence::encode(const char* const Start, size_t N) {
// Simple printable string, just return it now.
if (isPrint)
return llvm::StringRef(Start, N);
return Output << llvm::StringRef(Start, N);
Ptr = Start;
} else {
@ -305,7 +306,7 @@ llvm::StringRef EscapeSequence::encode(const char* const Start, size_t N) {
}
}
if (Hex != kEnd)
return Strm.str();
return Output << Strm.str();
Ptr = Start + LastGood;
Dump.buf().resize(LastGood);
@ -315,6 +316,13 @@ llvm::StringRef EscapeSequence::encode(const char* const Start, size_t N) {
llvm::raw_svector_ostream Strm(Dump.buf());
while (Ptr < End)
Dump(Ptr, Strm, true);
return Output << Strm.str();
}
std::string EscapeSequence::encode(const char* const Start, size_t N) {
stdstrstream Strm;
encode(Start, N, Strm);
return Strm.str();
}