From 29694ec13b4783e12add14922d42a2292efb42dd Mon Sep 17 00:00:00 2001 From: Mikusch Date: Wed, 27 Sep 2023 16:05:43 +0200 Subject: [PATCH] Add block parameter to various ArrayList functions (#1656) * Add block parameter to FindString * Add block parameter for GetString & GetArray * Fix buffer overflow issues * Fix wrong return * Add size parameter to SetArrayString --- core/logic/smn_adt_array.cpp | 78 ++++++++++++++++++++++++++++++++--- plugins/include/adt_array.inc | 42 ++++++++++++++----- 2 files changed, 104 insertions(+), 16 deletions(-) diff --git a/core/logic/smn_adt_array.cpp b/core/logic/smn_adt_array.cpp index fe91b3172d..fd85743fac 100644 --- a/core/logic/smn_adt_array.cpp +++ b/core/logic/smn_adt_array.cpp @@ -281,7 +281,19 @@ static cell_t GetArrayString(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size()); } - cell_t *blk = array->at(idx); + // the blocknumber is not guaranteed to always be passed + size_t blocknumber = 0; + if (params[0] >= 5) + { + blocknumber = (size_t)params[5]; + } + + if (blocknumber >= array->blocksize()) + { + return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize()); + } + + cell_t *blk = &array->base()[idx * array->blocksize() + blocknumber]; size_t numWritten = 0; pContext->StringToLocalUTF8(params[3], params[4], (char *)blk, &numWritten); @@ -307,7 +319,19 @@ static cell_t GetArrayArray(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size()); } - cell_t *blk = array->at(idx); + // the blocknumber is not guaranteed to always be passed + size_t blocknumber = 0; + if (params[0] >= 5) + { + blocknumber = (size_t)params[5]; + } + + if (blocknumber >= array->blocksize()) + { + return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize()); + } + + cell_t *blk = &array->base()[idx * array->blocksize() + blocknumber]; size_t indexes = array->blocksize(); if (params[4] != -1 && (size_t)params[4] <= array->blocksize()) { @@ -379,12 +403,30 @@ static cell_t SetArrayString(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size()); } - cell_t *blk = array->at(idx); + // the blocknumber is not guaranteed to always be passed + size_t blocknumber = 0; + if (params[0] >= 5) + { + blocknumber = (size_t)params[5]; + } + + if (blocknumber >= array->blocksize()) + { + return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize()); + } + + cell_t *blk = &array->base()[idx * array->blocksize() + blocknumber]; char *str; pContext->LocalToString(params[3], &str); - return strncopy((char *)blk, str, array->blocksize() * sizeof(cell_t)); + size_t maxlength = array->blocksize() * sizeof(cell_t); + if (params[0] >= 4 && params[4] != -1 && (size_t)params[4] <= array->blocksize()) + { + maxlength = (size_t)params[4]; + } + + return strncopy((char*)blk, str, maxlength); } static cell_t SetArrayArray(IPluginContext *pContext, const cell_t *params) @@ -405,7 +447,19 @@ static cell_t SetArrayArray(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid index %d (count: %d)", idx, array->size()); } - cell_t *blk = array->at(idx); + // the blocknumber is not guaranteed to always be passed + size_t blocknumber = 0; + if (params[0] >= 5) + { + blocknumber = (size_t)params[5]; + } + + if (blocknumber >= array->blocksize()) + { + return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize()); + } + + cell_t *blk = &array->base()[idx * array->blocksize() + blocknumber]; size_t indexes = array->blocksize(); if (params[4] != -1 && (size_t)params[4] <= array->blocksize()) { @@ -533,12 +587,24 @@ static cell_t FindStringInArray(IPluginContext *pContext, const cell_t *params) return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err); } + // the blocknumber is not guaranteed to always be passed + size_t blocknumber = 0; + if (params[0] >= 3) + { + blocknumber = (size_t)params[3]; + } + + if (blocknumber >= array->blocksize()) + { + return pContext->ThrowNativeError("Invalid block %d (blocksize: %d)", blocknumber, array->blocksize()); + } + char *str; pContext->LocalToString(params[2], &str); for (unsigned int i = 0; i < array->size(); i++) { - const char *array_str = (const char *)array->at(i); + const char *array_str = (const char *)&array->base()[i * array->blocksize() + blocknumber]; if (strcmp(str, array_str) == 0) { return (cell_t) i; diff --git a/plugins/include/adt_array.inc b/plugins/include/adt_array.inc index 911b66702c..6f60ef119f 100644 --- a/plugins/include/adt_array.inc +++ b/plugins/include/adt_array.inc @@ -129,9 +129,11 @@ methodmap ArrayList < Handle { // @param index Index in the array. // @param buffer Buffer to copy to. // @param maxlength Maximum size of the buffer. + // @param block Optionally specify which block to read from + // (useful if the blocksize > 0). // @return Number of characters copied. // @error Invalid index. - public native int GetString(int index, char[] buffer, int maxlength); + public native int GetString(int index, char[] buffer, int maxlength, int block=0); // Retrieves an array of cells from an array. // @@ -139,9 +141,11 @@ methodmap ArrayList < Handle { // @param buffer Buffer to store the array in. // @param size If not set, assumes the buffer size is equal to the // blocksize. Otherwise, the size passed is used. + // @param block Optionally specify which block to read from + // (useful if the blocksize > 0). // @return Number of cells copied. // @error Invalid index. - public native int GetArray(int index, any[] buffer, int size=-1); + public native int GetArray(int index, any[] buffer, int size=-1, int block=0); // Sets a cell value in an array. // @@ -157,9 +161,13 @@ methodmap ArrayList < Handle { // // @param index Index in the array. // @param value String value to set. + // @param size If not set, assumes the buffer size is equal to the + // blocksize. Otherwise, the size passed is used. + // @param block Optionally specify which block to write to + // (useful if the blocksize > 0). // @return Number of characters copied. // @error Invalid index. - public native int SetString(int index, const char[] value); + public native int SetString(int index, const char[] value, int size=-1, int block=0); // Sets an array of cells in an array. // @@ -167,9 +175,11 @@ methodmap ArrayList < Handle { // @param values Array to copy. // @param size If not set, assumes the buffer size is equal to the // blocksize. Otherwise, the size passed is used. + // @param block Optionally specify which block to write to + // (useful if the blocksize > 0). // @return Number of cells copied. // @error Invalid index. - public native int SetArray(int index, const any[] values, int size=-1); + public native int SetArray(int index, const any[] values, int size=-1, int block=0); // Shifts an array up. All array contents after and including the given // index are shifted up by one, and the given index is then "free." @@ -198,8 +208,9 @@ methodmap ArrayList < Handle { // the string cannot be located, -1 will be returned. // // @param item String to search for + // @param block Optionally which block to search in // @return Array index, or -1 on failure - public native int FindString(const char[] item); + public native int FindString(const char[] item, int block=0); // Returns the index for the first occurrence of the provided value. If the // value cannot be located, -1 will be returned. @@ -349,10 +360,12 @@ native any GetArrayCell(Handle array, int index, int block=0, bool asChar=false) * @param index Index in the array. * @param buffer Buffer to copy to. * @param maxlength Maximum size of the buffer. + * @param block Optionally specify which block to read from + * (useful if the blocksize > 0). * @return Number of characters copied. * @error Invalid Handle or invalid index. */ -native int GetArrayString(Handle array, int index, char[] buffer, int maxlength); +native int GetArrayString(Handle array, int index, char[] buffer, int maxlength, int block=0); /** * Retrieves an array of cells from an array. @@ -362,10 +375,12 @@ native int GetArrayString(Handle array, int index, char[] buffer, int maxlength) * @param buffer Buffer to store the array in. * @param size If not set, assumes the buffer size is equal to the * blocksize. Otherwise, the size passed is used. + * @param block Optionally specify which block to read from + * (useful if the blocksize > 0). * @return Number of cells copied. * @error Invalid Handle or invalid index. */ -native int GetArrayArray(Handle array, int index, any[] buffer, int size=-1); +native int GetArrayArray(Handle array, int index, any[] buffer, int size=-1, int block=0); /** * Sets a cell value in an array. @@ -386,10 +401,14 @@ native void SetArrayCell(Handle array, int index, any value, int block=0, bool a * @param array Array Handle. * @param index Index in the array. * @param value String value to set. + * @param size If not set, assumes the buffer size is equal to the + * blocksize. Otherwise, the size passed is used. + * @param block Optionally specify which block to write to + * (useful if the blocksize > 0). * @return Number of characters copied. * @error Invalid Handle or invalid index. */ -native int SetArrayString(Handle array, int index, const char[] value); +native int SetArrayString(Handle array, int index, const char[] value, int size=-1, int block=0); /** * Sets an array of cells in an array. @@ -399,10 +418,12 @@ native int SetArrayString(Handle array, int index, const char[] value); * @param values Array to copy. * @param size If not set, assumes the buffer size is equal to the * blocksize. Otherwise, the size passed is used. + * @param block Optionally specify which block to write to + * (useful if the blocksize > 0). * @return Number of cells copied. * @error Invalid Handle or invalid index. */ -native int SetArrayArray(Handle array, int index, const any[] values, int size=-1); +native int SetArrayArray(Handle array, int index, const any[] values, int size=-1, int block=0); /** * Shifts an array up. All array contents after and including the given @@ -442,10 +463,11 @@ native void SwapArrayItems(Handle array, int index1, int index2); * * @param array Array Handle. * @param item String to search for + * @param block Optionally which block to search in * @return Array index, or -1 on failure * @error Invalid Handle */ -native int FindStringInArray(Handle array, const char[] item); +native int FindStringInArray(Handle array, const char[] item, int block=0); /** * Returns the index for the first occurrence of the provided value. If the value