diff --git a/src/lexfloatclient-native.ts b/src/lexfloatclient-native.ts index 460ae1b..611612d 100644 --- a/src/lexfloatclient-native.ts +++ b/src/lexfloatclient-native.ts @@ -28,3 +28,10 @@ export function arrayToString(array: Uint8Array): string { return Buffer.from(array).toString('utf8').replace(/\0.*$/g, ''); } } + +export function getCArray(length: number): Uint8Array { + if (process.platform == 'win32') { + return new Uint8Array(length * 2); + } + return new Uint8Array(length); +} diff --git a/src/lexfloatclient.ts b/src/lexfloatclient.ts index ae82a0e..8858d6e 100644 --- a/src/lexfloatclient.ts +++ b/src/lexfloatclient.ts @@ -1,5 +1,5 @@ import { LexFloatClientException } from "./lexfloatclient-exception"; -import { arrayToString, LexFloatClientNative } from "./lexfloatclient-native"; +import { arrayToString, getCArray, LexFloatClientNative } from "./lexfloatclient-native"; import { LexFloatStatusCodes } from "./lexfloatstatus-codes"; /** @@ -193,7 +193,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostProductVersionName(): string { - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetHostProductVersionName(array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -208,7 +208,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostProductVersionDisplayName(): string { - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetHostProductVersionDisplayName(array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -222,7 +222,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetFloatingLicenseMode(): string { - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetFloatingLicenseMode(array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -239,7 +239,7 @@ export class LexFloatClient { */ static GetHostProductVersionFeatureFlag(name: string): HostProductVersionFeatureFlag { const enabled = new Uint32Array(1); - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetHostProductVersionFeatureFlag(name, enabled, array, array.length); switch (status) { case LexFloatStatusCodes.LF_OK: @@ -255,7 +255,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostLicenseEntitlementSetName(): string { - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetHostLicenseEntitlementSetName(array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -269,7 +269,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostLicenseEntitlementSetDisplayName(): string { - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetHostLicenseEntitlementSetDisplayName(array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -283,7 +283,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostFeatureEntitlements(): HostFeatureEntitlement[] { - const array = new Uint8Array(4096); + const array = getCArray(4096); const status = LexFloatClientNative.GetHostFeatureEntitlements(array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -298,7 +298,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostFeatureEntitlement(featureName: string): HostFeatureEntitlement { - const array = new Uint8Array(1024); + const array = getCArray(1024); const status = LexFloatClientNative.GetHostFeatureEntitlement(featureName, array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -315,7 +315,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostProductMetadata(key: string): string { - const array = new Uint8Array(4096); + const array = getCArray(4096); const status = LexFloatClientNative.GetHostProductMetadata(key, array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -332,7 +332,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetHostLicenseMetadata(key: string): string { - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetHostLicenseMetadata(key, array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -385,7 +385,7 @@ export class LexFloatClient { * @throws {LexActivatorException} */ static GetHostConfig(): HostConfig | null { - const array = new Uint8Array(1024); + const array = getCArray(1024); const status = LexFloatClientNative.GetHostConfig(array, array.length) if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -429,7 +429,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetFloatingClientMetadata(key: string): string { - const array = new Uint8Array(4096); + const array = getCArray(4096); const status = LexFloatClientNative.GetFloatingClientMetadata(key, array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); @@ -442,7 +442,7 @@ export class LexFloatClient { * @throws {LexFloatClientException} */ static GetFloatingClientLibraryVersion(): string { - const array = new Uint8Array(256); + const array = getCArray(256); const status = LexFloatClientNative.GetFloatingClientLibraryVersion(array, array.length); if (status != LexFloatStatusCodes.LF_OK) { throw new LexFloatClientException(status); diff --git a/src/native/main.cpp b/src/native/main.cpp index de3ef55..652537f 100644 --- a/src/native/main.cpp +++ b/src/native/main.cpp @@ -34,6 +34,20 @@ STRING toEncodedString(Napi::String input) #endif } +size_t getCharCount(Napi::Env env, size_t byteLength) +{ +#ifdef _WIN32 + if (byteLength % sizeof(CHARTYPE) != 0) { + Napi::TypeError::New(env, "Invalid UTF-16 buffer length").ThrowAsJavaScriptException(); + return 0; + } + return byteLength / sizeof(CHARTYPE); +#else + return byteLength; +#endif +} + + void floatingLicenseCallback(uint32_t status) { auto it = LicenseCallbacks.find(HostProductId); @@ -66,7 +80,10 @@ Napi::Value getHostConfig(const Napi::CallbackInfo &info) return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostConfigInternal(arg0, length)); } @@ -197,7 +214,10 @@ Napi::Value getHostProductVersionName(const Napi::CallbackInfo &info) return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostProductVersionName(arg0, length)); } @@ -216,7 +236,10 @@ Napi::Value getHostProductVersionDisplayName(const Napi::CallbackInfo &info) return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostProductVersionDisplayName(arg0, length)); } @@ -248,7 +271,10 @@ Napi::Value getHostProductVersionFeatureFlag(const Napi::CallbackInfo &info) { uint32_t *arg1 = reinterpret_cast(array1.ArrayBuffer().Data()); Napi::Uint8Array array2 = info[2].As(); CHARTYPE *arg2 = reinterpret_cast(array2.ArrayBuffer().Data()); - size_t length = array2.ElementLength(); + size_t length = getCharCount(env, array2.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } return Napi::Number::New(env, GetHostProductVersionFeatureFlag(arg0.c_str(), arg1, arg2, length)); } @@ -266,7 +292,10 @@ Napi::Value getHostLicenseEntitlementSetName(const Napi::CallbackInfo &info) return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostLicenseEntitlementSetName(arg0, length)); } @@ -285,7 +314,10 @@ Napi::Value getHostLicenseEntitlementSetDisplayName(const Napi::CallbackInfo &in return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostLicenseEntitlementSetDisplayName(arg0, length)); } @@ -304,7 +336,10 @@ Napi::Value getHostFeatureEntitlements(const Napi::CallbackInfo &info) return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostFeatureEntitlementsInternal(arg0, length)); } @@ -329,7 +364,10 @@ Napi::Value getHostFeatureEntitlement(const Napi::CallbackInfo &info) } STRING arg0 = toEncodedString(info[0].As()); Napi::Uint8Array array = info[1].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg1 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostFeatureEntitlementInternal(arg0.c_str(), arg1, length)); } @@ -354,7 +392,10 @@ Napi::Value getHostProductMetadata(const Napi::CallbackInfo &info) } STRING arg0 = toEncodedString(info[0].As()); Napi::Uint8Array array = info[1].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg1 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostProductMetadata(arg0.c_str(), arg1, length)); } @@ -379,7 +420,10 @@ Napi::Value getHostLicenseMetadata(const Napi::CallbackInfo &info) } STRING arg0 = toEncodedString(info[0].As()); Napi::Uint8Array array = info[1].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg1 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetHostLicenseMetadata(arg0.c_str(), arg1, length)); } @@ -484,7 +528,10 @@ Napi::Value getFloatingClientMetadata(const Napi::CallbackInfo &info) } STRING arg0 = toEncodedString(info[0].As()); Napi::Uint8Array array = info[1].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg1 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetFloatingClientMetadata(arg0.c_str(), arg1, length)); } @@ -503,7 +550,10 @@ Napi::Value getFloatingClientLibraryVersion(const Napi::CallbackInfo &info) return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetFloatingClientLibraryVersion(arg0, length)); } @@ -540,7 +590,10 @@ Napi::Value getFloatingLicenseMode(const Napi::CallbackInfo &info) return env.Null(); } Napi::Uint8Array array = info[0].As(); - size_t length = array.ElementLength(); + size_t length = getCharCount(env, array.ByteLength()); + if(env.IsExceptionPending()) { + return env.Null(); + } CHARTYPE *arg0 = reinterpret_cast(array.ArrayBuffer().Data()); return Napi::Number::New(env, GetFloatingLicenseMode(arg0, length)); }