Got SIGABRT when b64decode to a preallocated buffer
LuminousXLB opened this issue · 0 comments
LuminousXLB commented
I'm trying to decode a string, which is a b64encoded 64-byte signature, to a preallocated buffer.
Since its length is known exactly, it might not be a good practice to allocate a buffer bigger than that.
But the decoded_max_size
requires 2 more bytes.
Is it possible to give a more precise calculation on the length of output?
If not, what about throw a concise exception?
#include <cppcodec/base64_rfc4648.hpp>
#include <cppcodec/hex_lower.hpp>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
using base64 = cppcodec::base64_rfc4648;
using hex = cppcodec::hex_lower;
#define uint8_p(x) reinterpret_cast<uint8_t*>(x)
string s = "JHeNMtgqWq51F+MyZlz+tA5HywxhLSH3Cq+gTFs6M8iJWgONT7Ll9t1NwH2m2hCXWpoeWT90w3+LkIG/wNaiEg==";
void try_1()
{
auto signature = base64::decode(s);
cout << signature.size() << endl;
puts(hex::encode(signature).c_str());
}
void try_2()
{
uint8_t signature[64];
base64::decode(signature, sizeof(signature), s);
puts(hex::encode(signature, 64).c_str());
}
int main()
{
cout << base64::decoded_max_size(s.size()) << endl; // 66
try_1();
try_2();
}
$ ./main
66
64
24778d32d82a5aae7517e332665cfeb40e47cb0c612d21f70aafa04c5b3a33c8895a038d4fb2e5f6dd4dc07da6da10975a9a1e593f74c37f8b9081bfc0d6a212
[1] 13521 abort (core dumped) ./main
$ valgrind ./main
==13588== Memcheck, a memory error detector
==13588== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==13588== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==13588== Command: ./main
==13588==
66
64
24778d32d82a5aae7517e332665cfeb40e47cb0c612d21f70aafa04c5b3a33c8895a038d4fb2e5f6dd4dc07da6da10975a9a1e593f74c37f8b9081bfc0d6a212
==13588==
==13588== Process terminating with default action of signal 6 (SIGABRT)
==13588== at 0x5C84E97: raise (raise.c:51)
==13588== by 0x5C86800: abort (abort.c:79)
==13588== by 0x40472B: init<cppcodec::data::raw_result_buffer> (include/cppcodec/detail/../data/raw_result_buffer.hpp:61)
==13588== by 0x40472B: void cppcodec::detail::codec<cppcodec::detail::base64<cppcodec::detail::base64_rfc4648> >::decode<cppcodec::data::raw_result_buffer>(cppcodec::data::raw_result_buffer&, char const*, unsigned long) (include/cppcodec/detail/codec.hpp:268)
==13588== by 0x404659: cppcodec::detail::codec<cppcodec::detail::base64<cppcodec::detail::base64_rfc4648> >::decode(char*, unsigned long, char const*, unsigned long) (include/cppcodec/detail/codec.hpp:298)
==13588== by 0x404618: unsigned long cppcodec::detail::codec<cppcodec::detail::base64<cppcodec::detail::base64_rfc4648> >::decode<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(char*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (include/cppcodec/detail/codec.hpp:314)
==13588== by 0x401BD4: unsigned long cppcodec::detail::codec<cppcodec::detail::base64<cppcodec::detail::base64_rfc4648> >::decode<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >(unsigned char*, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) (include/cppcodec/detail/codec.hpp:307)
==13588== by 0x4018AB: try_2() (main.cpp:26)
==13588== by 0x401970: main (main.cpp:34)
==13588==
==13588== HEAP SUMMARY:
==13588== in use at exit: 89 bytes in 1 blocks
==13588== total heap usage: 5 allocs, 4 frees, 74,012 bytes allocated
==13588==
==13588== LEAK SUMMARY:
==13588== definitely lost: 0 bytes in 0 blocks
==13588== indirectly lost: 0 bytes in 0 blocks
==13588== possibly lost: 0 bytes in 0 blocks
==13588== still reachable: 89 bytes in 1 blocks
==13588== suppressed: 0 bytes in 0 blocks
==13588== Rerun with --leak-check=full to see details of leaked memory
==13588==
==13588== For counts of detected and suppressed errors, rerun with: -v
==13588== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
[1] 13588 abort (core dumped) valgrind ./main
Here's my comiler
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)