From 5f63e6ff1dc8388cb533742ba0735a8d063aef44 Mon Sep 17 00:00:00 2001 From: KJ Tsanaktsidis Date: Fri, 1 Apr 2022 13:28:20 +1100 Subject: [PATCH] Use the correct function to delete udatpg objects The skeleton generator is currently using udat_close to delete objects created with udatpg_open; it should be using udatpg_close instead. The C-side implementation of udat_close calls straight into the C++ delete operator: U_CAPI void U_EXPORT2 udat_close(UDateFormat* format) { delete (DateFormat*)format; } The destructor on the DateFormat class is virtual, so i'm frankly astonished this isn't just chasing and calling a pointer to nowhere. I guess we got "lucky" and DateFormat and DateTimePatternGenerator have a similar enough layout by chance that this works. However it's entirely at the whim of the compiler as to whether this keeps working or not, so we should fix it and call the correct cleanup function. --- lib/ffi-icu/lib.rb | 1 + lib/ffi-icu/time_formatting.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/ffi-icu/lib.rb b/lib/ffi-icu/lib.rb index e9c581f..532c573 100644 --- a/lib/ffi-icu/lib.rb +++ b/lib/ffi-icu/lib.rb @@ -438,6 +438,7 @@ module ICU attach_function :udat_applyPattern, "udat_applyPattern#{suffix}", [:pointer, :bool , :pointer, :int32_t ], :void # skeleton pattern attach_function :udatpg_open, "udatpg_open#{suffix}", [:string, :pointer], :pointer + attach_function :udatpg_close, "udatpg_close#{suffix}", [:pointer], :void attach_function :udatpg_getBestPattern, "udatpg_getBestPattern#{suffix}", [:pointer, :pointer, :int32_t, :pointer, :int32_t, :pointer], :int32_t # tz attach_function :ucal_setDefaultTimeZone, "ucal_setDefaultTimeZone#{suffix}", [:pointer, :pointer], :int32_t diff --git a/lib/ffi-icu/time_formatting.rb b/lib/ffi-icu/time_formatting.rb index b78e129..fb50226 100644 --- a/lib/ffi-icu/time_formatting.rb +++ b/lib/ffi-icu/time_formatting.rb @@ -198,7 +198,7 @@ module ICU pattern_ptr = UCharPointer.new(needed_length) udatpg_ptr = Lib.check_error { |error| Lib.udatpg_open(locale, error) } - generator = FFI::AutoPointer.new(udatpg_ptr, Lib.method(:udat_close)) + generator = FFI::AutoPointer.new(udatpg_ptr, Lib.method(:udatpg_close)) retried = false