Also
const will solve this for every case, it is a remedy for now and will make these undefined behavior disappear for wide range cases but not all ! keep that in mind
The problem with untyped, is that they allow you to pass almost anything, in case combining strings with array it will work as the refcount is at the same place, the problem spur with when unmanaged typed passed as untyped parameter than casted away as managed type, now the compiler with its final destination will
access the refcount which doesn't exist and will grab what ever there either on stack or on the heap then the fun starts.
In different example passing integer as untyped parameter to "TDECCipherModes.Encode(const Source;" then casted ( in this case it is not casted right away as it is passed as pointer "PUInt8Array" using "@Source", now "TDECCipherModes.EncodeGCM(Source, Dest: PUInt8Array;" will
handle the original integer with no refcount or Count/Size as it should have, these will be right before the pointer that passed, most likely on the stack, now we are in the unknown, if the stack hold 0 or $FFFFFFFF(-1) or something else, without suggested "const" it will adjust the refcount because it is managed in its eye, compiler will generate the ref adjusting code that will crash (may be but not always and that why it passed tests for long time not being detected),
"const" will solve most of these cases, but not all !
The only fix that will be valid is to re-write "TDECCipherModes.EncodeGCM(Source, Dest: PUInt8Array;" change the type from array to simple pointer, this will solve this wide range of errors and wrong doing, internally do what every you want but don not use casting, simple walk the buffer byte by byte.
Also "TBytes(@Source^);" and "TBytes(@Dest^);" has the same undefined behavior invoking wrong casting, crashing when handling Dest i mere chance it could be with Source too.