THRIFT-5932: bound saferealpath() output on Windows
Client: cpp
Author: Pengpeng Hou <pengpeng@iscas.ac.cn>
This closes #3357
diff --git a/compiler/cpp/src/thrift/main.cc b/compiler/cpp/src/thrift/main.cc
index dfd22e9..38d764d 100644
--- a/compiler/cpp/src/thrift/main.cc
+++ b/compiler/cpp/src/thrift/main.cc
@@ -32,6 +32,7 @@
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
+#include <cstring>
#include <string>
#include <algorithm>
#include <sys/types.h>
@@ -164,27 +165,35 @@
* Win32 doesn't have realpath, so use fallback implementation in that case,
* otherwise this just calls through to realpath
*/
-char* saferealpath(const char* path, char* resolved_path) {
+char* saferealpath(const char* path, char* resolved_path, size_t resolved_path_size) {
#ifdef _WIN32
char buf[MAX_PATH];
char* basename;
+ const char* source;
+ size_t source_len;
DWORD len = GetFullPathNameA(path, MAX_PATH, buf, &basename);
if (len == 0 || len > MAX_PATH - 1) {
- strcpy(resolved_path, path);
+ source = path;
} else {
- strcpy(resolved_path, buf);
+ source = buf;
}
+ source_len = strlen(source);
+ if (source_len >= resolved_path_size) {
+ return nullptr;
+ }
+ strcpy(resolved_path, source);
+
// Replace backslashes with forward slashes so the
// rest of the code behaves correctly.
- size_t resolved_len = strlen(resolved_path);
- for (size_t i = 0; i < resolved_len; i++) {
+ for (size_t i = 0; i < source_len; i++) {
if (resolved_path[i] == '\\') {
resolved_path[i] = '/';
}
}
return resolved_path;
#else
+ (void) resolved_path_size;
return realpath(path, resolved_path);
#endif
}
@@ -337,7 +346,7 @@
// Realpath!
char rp[THRIFT_PATH_MAX];
// cppcheck-suppress uninitvar
- if (saferealpath(filename.c_str(), rp) == nullptr) {
+ if (saferealpath(filename.c_str(), rp, THRIFT_PATH_MAX) == nullptr) {
pwarning(0, "Cannot open include file %s\n", filename.c_str());
return std::string();
}
@@ -360,7 +369,7 @@
// Realpath!
char rp[THRIFT_PATH_MAX];
// cppcheck-suppress uninitvar
- if (saferealpath(sfilename.c_str(), rp) == nullptr) {
+ if (saferealpath(sfilename.c_str(), rp, THRIFT_PATH_MAX) == nullptr) {
continue;
}
@@ -1174,7 +1183,7 @@
char old_thrift_file_rp[THRIFT_PATH_MAX];
// cppcheck-suppress uninitvar
- if (saferealpath(arg, old_thrift_file_rp) == nullptr) {
+ if (saferealpath(arg, old_thrift_file_rp, THRIFT_PATH_MAX) == nullptr) {
failure("Could not open input file with realpath: %s", arg);
}
old_input_file = string(old_thrift_file_rp);
@@ -1232,7 +1241,7 @@
usage();
}
// cppcheck-suppress uninitvar
- if (saferealpath(argv[i], new_thrift_file_rp) == nullptr) {
+ if (saferealpath(argv[i], new_thrift_file_rp, THRIFT_PATH_MAX) == nullptr) {
failure("Could not open input file with realpath: %s", argv[i]);
}
string new_input_file(new_thrift_file_rp);
@@ -1258,7 +1267,7 @@
usage();
}
// cppcheck-suppress uninitvar
- if (saferealpath(argv[i], rp) == nullptr) {
+ if (saferealpath(argv[i], rp, THRIFT_PATH_MAX) == nullptr) {
failure("Could not open input file with realpath: %s", argv[i]);
}
string input_file(rp);