mirror of
https://github.com/joyieldInc/predixy.git
synced 2026-02-05 01:42:24 +08:00
Handle vsnprintf errors in buffer
This commit is contained in:
parent
33601ea2f0
commit
2a431ccee6
@ -82,6 +82,10 @@ Buffer* Buffer::fappend(const char* fmt, ...)
|
|||||||
int len = room();
|
int len = room();
|
||||||
int n = vsnprintf(dat, len, fmt, ap);
|
int n = vsnprintf(dat, len, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
if (n < 0) {
|
||||||
|
// Formatting failed; keep buffer length unchanged.
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (n >= len) {
|
if (n >= len) {
|
||||||
if (n > MaxBufFmtAppendLen) {
|
if (n > MaxBufFmtAppendLen) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -104,6 +108,11 @@ Buffer* Buffer::vfappend(const char* fmt, va_list ap)
|
|||||||
va_list aq;
|
va_list aq;
|
||||||
va_copy(aq, ap);
|
va_copy(aq, ap);
|
||||||
int n = vsnprintf(dat, len, fmt, ap);
|
int n = vsnprintf(dat, len, fmt, ap);
|
||||||
|
if (n < 0) {
|
||||||
|
// Formatting failed; keep buffer length unchanged.
|
||||||
|
va_end(aq);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (n >= len) {
|
if (n >= len) {
|
||||||
if (n > MaxBufFmtAppendLen) {
|
if (n > MaxBufFmtAppendLen) {
|
||||||
va_end(aq);
|
va_end(aq);
|
||||||
|
|||||||
20
test/buffer_vsnprintf.cpp
Normal file
20
test/buffer_vsnprintf.cpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Minimal test for Buffer::fappend negative vsnprintf handling.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../src/Buffer.h"
|
||||||
|
#include "../src/Logger.h"
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Logger::gInst = nullptr;
|
||||||
|
Buffer* buf = BufferAlloc::create();
|
||||||
|
int before = buf->length();
|
||||||
|
Buffer* ret = buf->fappend("%");
|
||||||
|
if (ret && ret->length() < before) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (buf->length() < before) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
49
test/buffer_vsnprintf.py
Normal file
49
test/buffer_vsnprintf.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
#
|
||||||
|
# Build and run the Buffer::fappend vsnprintf edge-case test.
|
||||||
|
#
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
from test_util import parse_args, exit_with_result
|
||||||
|
|
||||||
|
|
||||||
|
def run_test(project_root):
|
||||||
|
src = os.path.join(project_root, "test", "buffer_vsnprintf.cpp")
|
||||||
|
if not os.path.exists(src):
|
||||||
|
print("FAIL: buffer_vsnprintf.cpp not found")
|
||||||
|
return False
|
||||||
|
|
||||||
|
with tempfile.TemporaryDirectory() as tmp:
|
||||||
|
exe = os.path.join(tmp, "buffer_vsnprintf")
|
||||||
|
cmd = [
|
||||||
|
"g++",
|
||||||
|
"-std=c++11",
|
||||||
|
src,
|
||||||
|
os.path.join(project_root, "src", "Buffer.cpp"),
|
||||||
|
os.path.join(project_root, "src", "Alloc.cpp"),
|
||||||
|
os.path.join(project_root, "src", "Logger.cpp"),
|
||||||
|
os.path.join(project_root, "src", "LogFileSink.cpp"),
|
||||||
|
os.path.join(project_root, "src", "Timer.cpp"),
|
||||||
|
"-o",
|
||||||
|
exe,
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
except Exception as exc:
|
||||||
|
print("FAIL: compile buffer_vsnprintf:", exc)
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
subprocess.check_call([exe], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
except subprocess.CalledProcessError as exc:
|
||||||
|
print("FAIL: buffer_vsnprintf returned", exc.returncode)
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
_ = parse_args("Buffer vsnprintf test")
|
||||||
|
root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||||
|
success = run_test(root)
|
||||||
|
exit_with_result(success, "buffer vsnprintf", "buffer vsnprintf")
|
||||||
@ -145,6 +145,7 @@ TESTS=(
|
|||||||
"test/response_parser_error_log.py"
|
"test/response_parser_error_log.py"
|
||||||
"test/request_parser_long_command.py"
|
"test/request_parser_long_command.py"
|
||||||
"test/signal_handling.py"
|
"test/signal_handling.py"
|
||||||
|
"test/buffer_vsnprintf.py"
|
||||||
"test/pubsub_long_name.py"
|
"test/pubsub_long_name.py"
|
||||||
"test/pubsub_large_message.py"
|
"test/pubsub_large_message.py"
|
||||||
"test/transaction_forbid.py"
|
"test/transaction_forbid.py"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user