ruby-oci8 2.2.12 → 2.2.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  /* -*- indent-tabs-mode: nil -*-
2
2
  *
3
- * plthook_win32.c -- implemention of plthook for PE format
3
+ * plthook_win32.c -- implementation of plthook for PE format
4
4
  *
5
5
  * URL: https://github.com/kubo/plthook
6
6
  *
@@ -86,7 +86,7 @@ int plthook_open(plthook_t **plthook_out, const char *filename)
86
86
  HMODULE hMod;
87
87
 
88
88
  *plthook_out = NULL;
89
- if (!GetModuleHandleExA(0, filename, &hMod)) {
89
+ if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, filename, &hMod)) {
90
90
  set_errmsg2("Cannot get module %s: ", filename);
91
91
  return PLTHOOK_FILE_NOT_FOUND;
92
92
  }
@@ -107,7 +107,7 @@ int plthook_open_by_address(plthook_t **plthook_out, void *address)
107
107
  HMODULE hMod;
108
108
 
109
109
  *plthook_out = NULL;
110
- if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, address, &hMod)) {
110
+ if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, address, &hMod)) {
111
111
  set_errmsg2("Cannot get module at address %p: ", address);
112
112
  return PLTHOOK_FILE_NOT_FOUND;
113
113
  }
@@ -134,7 +134,8 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
134
134
  for (desc = desc_head; desc->Name != 0; desc++) {
135
135
  IMAGE_THUNK_DATA *name_thunk = (IMAGE_THUNK_DATA*)((char*)hMod + desc->OriginalFirstThunk);
136
136
  IMAGE_THUNK_DATA *addr_thunk = (IMAGE_THUNK_DATA*)((char*)hMod + desc->FirstThunk);
137
- int is_winsock2_dll = (stricmp((char *)hMod + desc->Name, "WS2_32.DLL") == 0);
137
+ const char *module_name = (char *)hMod + desc->Name;
138
+ int is_winsock2_dll = (stricmp(module_name, "WS2_32.DLL") == 0);
138
139
 
139
140
  while (addr_thunk->u1.Function != 0) {
140
141
  if (IMAGE_SNAP_BY_ORDINAL(name_thunk->u1.Ordinal)) {
@@ -144,8 +145,11 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
144
145
  name = winsock2_ordinal2name(ordinal);
145
146
  }
146
147
  if (name == NULL) {
147
- char buf[64];
148
- ordinal_name_buflen += sprintf(buf, "#%d", ordinal) + 1;
148
+ #ifdef __CYGWIN__
149
+ ordinal_name_buflen += snprintf(NULL, 0, "%s:@%d", module_name, ordinal) + 1;
150
+ #else
151
+ ordinal_name_buflen += _scprintf("%s:@%d", module_name, ordinal) + 1;
152
+ #endif
149
153
  }
150
154
  }
151
155
  num_entries++;
@@ -167,7 +171,8 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
167
171
  for (desc = desc_head; desc->Name != 0; desc++) {
168
172
  IMAGE_THUNK_DATA *name_thunk = (IMAGE_THUNK_DATA*)((char*)hMod + desc->OriginalFirstThunk);
169
173
  IMAGE_THUNK_DATA *addr_thunk = (IMAGE_THUNK_DATA*)((char*)hMod + desc->FirstThunk);
170
- int is_winsock2_dll = (stricmp((char *)hMod + desc->Name, "WS2_32.DLL") == 0);
174
+ const char *module_name = (char *)hMod + desc->Name;
175
+ int is_winsock2_dll = (stricmp(module_name, "WS2_32.DLL") == 0);
171
176
 
172
177
  while (addr_thunk->u1.Function != 0) {
173
178
  const char *name = NULL;
@@ -178,12 +183,13 @@ static int plthook_open_real(plthook_t **plthook_out, HMODULE hMod)
178
183
  name = winsock2_ordinal2name(ordinal);
179
184
  }
180
185
  if (name == NULL) {
181
- ordinal_name_buf += sprintf(ordinal_name_buf, "#%d", ordinal) + 1;
186
+ name = ordinal_name_buf;
187
+ ordinal_name_buf += sprintf(ordinal_name_buf, "%s:@%d", module_name, ordinal) + 1;
182
188
  }
183
189
  } else {
184
190
  name = (char*)((PIMAGE_IMPORT_BY_NAME)((char*)hMod + name_thunk->u1.AddressOfData))->Name;
185
191
  }
186
- plthook->entries[idx].mod_name = (char *)hMod + desc->Name;
192
+ plthook->entries[idx].mod_name = module_name;
187
193
  plthook->entries[idx].name = name;
188
194
  plthook->entries[idx].addr = (void**)&addr_thunk->u1.Function;
189
195
  idx++;
@@ -231,41 +237,49 @@ int plthook_replace(plthook_t *plthook, const char *funcname, void *funcaddr, vo
231
237
  const char *name;
232
238
  void **addr;
233
239
  int rv;
240
+ BOOL import_by_ordinal = funcname[0] != '?' && strstr(funcname, ":@") != NULL;
234
241
 
235
242
  if (plthook == NULL) {
236
243
  set_errmsg("invalid argument: The first argument is null.");
237
244
  return PLTHOOK_INVALID_ARGUMENT;
238
245
  }
239
246
  while ((rv = plthook_enum(plthook, &pos, &name, &addr)) == 0) {
247
+ if (import_by_ordinal) {
248
+ if (stricmp(name, funcname) == 0) {
249
+ goto found;
250
+ }
251
+ } else {
252
+ /* import by name */
240
253
  #ifdef _WIN64
241
- if (strcmp(name, funcname) == 0) {
242
- replace_funcaddr(addr, funcaddr, oldfunc);
243
- return 0;
244
- }
245
- #else
246
- /* Function names may be decorated in Windows 32-bit applications. */
247
- if (strncmp(name, funcname, funcnamelen) == 0) {
248
- if (name[funcnamelen] == '\0' || name[funcnamelen] == '@') {
249
- replace_funcaddr(addr, funcaddr, oldfunc);
250
- return 0;
254
+ if (strcmp(name, funcname) == 0) {
255
+ goto found;
251
256
  }
252
- }
253
- if (name[0] == '_' || name[0] == '@') {
254
- name++;
257
+ #else
258
+ /* Function names may be decorated in Windows 32-bit applications. */
255
259
  if (strncmp(name, funcname, funcnamelen) == 0) {
256
260
  if (name[funcnamelen] == '\0' || name[funcnamelen] == '@') {
257
- replace_funcaddr(addr, funcaddr, oldfunc);
258
- return 0;
261
+ goto found;
262
+ }
263
+ }
264
+ if (name[0] == '_' || name[0] == '@') {
265
+ name++;
266
+ if (strncmp(name, funcname, funcnamelen) == 0) {
267
+ if (name[funcnamelen] == '\0' || name[funcnamelen] == '@') {
268
+ goto found;
269
+ }
259
270
  }
260
271
  }
261
- }
262
272
  #endif
273
+ }
263
274
  }
264
275
  if (rv == EOF) {
265
276
  set_errmsg("no such function: %s", funcname);
266
277
  rv = PLTHOOK_FUNCTION_NOT_FOUND;
267
278
  }
268
279
  return rv;
280
+ found:
281
+ replace_funcaddr(addr, funcaddr, oldfunc);
282
+ return 0;
269
283
  }
270
284
 
271
285
  void plthook_close(plthook_t *plthook)
@@ -127,7 +127,15 @@ class OCI8
127
127
  #
128
128
  # @return [String]
129
129
  def to_s
130
- format('%d.%d.%d.%d.%d', @major, @minor, @update, @patch, @port_update)
130
+ version_format =
131
+ if @major >= 23 && @patch != 0 && @port_update != 0
132
+ # The fifth numeral is the release month (01 through 12) since Oracle 23ai
133
+ # See https://docs.oracle.com/en/database/oracle/oracle-database/23/upgrd/oracle-database-release-numbers.html#GUID-1E2F3945-C0EE-4EB2-A933-8D1862D8ECE2__GUID-704EC7BB-4EEA-4A92-96FC-579B216DCA97
134
+ '%d.%d.%d.%d.%02d'
135
+ else
136
+ '%d.%d.%d.%d.%d'
137
+ end
138
+ format(version_format, @major, @minor, @update, @patch, @port_update)
131
139
  end
132
140
 
133
141
  # Returns true if +self+ and +other+ are the same type and have
data/lib/oci8/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  class OCI8
2
- VERSION = "2.2.12"
2
+ VERSION = "2.2.14"
3
3
  end
data/lib/oci8.rb CHANGED
@@ -147,6 +147,8 @@ class OCI8
147
147
  ORAVER_12_1 = OCI8::OracleVersion.new(12, 1)
148
148
  # @private
149
149
  ORAVER_18 = OCI8::OracleVersion.new(18)
150
+ # @private
151
+ ORAVER_23 = OCI8::OracleVersion.new(23)
150
152
 
151
153
  # @private
152
154
  @@oracle_client_version = OCI8::OracleVersion.new(self.oracle_client_vernum)
@@ -1896,6 +1896,7 @@ EOS
1896
1896
  # Get data_size of NCHAR(1) and that of CHAR(1 CHAR).
1897
1897
  # They depend on the database character set and the
1898
1898
  # client character set.
1899
+ drop_table('test_table')
1899
1900
  @conn.exec('CREATE TABLE test_table (nc NCHAR(1), c CHAR(1 CHAR))')
1900
1901
  cursor = @conn.exec("select * from test_table")
1901
1902
  cfrm = cursor.column_metadata[0].data_size # size of NCHAR(1) in bytes
@@ -697,7 +697,9 @@ EOS
697
697
  OraNumber.new(str)
698
698
  flunk("exception expected but none was thrown. test data: " + str)
699
699
  rescue
700
- assert_equal(oraerr.to_s, $!.to_s, "test data: " + str)
700
+ expected_errhead = oraerr.to_s.gsub(/:.*/m, '') # strip chars after ':'
701
+ actual_errhead = $!.to_s.gsub(/:.*/m, '')
702
+ assert_equal(expected_errhead, actual_errhead, "test data: " + str)
701
703
  end
702
704
  end
703
705
  if onum
@@ -47,6 +47,12 @@ class TestPackageType < Minitest::Test
47
47
  end
48
48
 
49
49
  def test_describe_package
50
+ if $oracle_server_version >= OCI8::ORAVER_23
51
+ boolean_type_name = 'BOOLEAN'
52
+ else
53
+ boolean_type_name = 'PL/SQL BOOLEAN'
54
+ end
55
+
50
56
  integer_type_attrs = {
51
57
  :class => OCI8::Metadata::Type,
52
58
  #:typecode => nil,
@@ -127,7 +133,7 @@ class TestPackageType < Minitest::Test
127
133
  #:map_method => nil,
128
134
  #:order_method => nil,
129
135
  :is_invoker_rights? => false,
130
- :name => 'PL/SQL BOOLEAN',
136
+ :name => boolean_type_name,
131
137
  :schema_name => 'SYS',
132
138
  :is_final_type? => true,
133
139
  :is_instantiable_type? => true,
@@ -137,7 +143,7 @@ class TestPackageType < Minitest::Test
137
143
  :package_name => nil,
138
144
  :type_attrs => [],
139
145
  #:type_methods => [],
140
- :inspect => '#<OCI8::Metadata::Type:(0) SYS.PL/SQL BOOLEAN>', # TODO: change to "BOOLEAN"
146
+ :inspect => "#<OCI8::Metadata::Type:(0) SYS.#{boolean_type_name}>",
141
147
  }
142
148
 
143
149
  varchar2_type_attrs = {
@@ -277,7 +283,7 @@ class TestPackageType < Minitest::Test
277
283
  :num_elems => 0,
278
284
  :precision => 0,
279
285
  :scale => 0,
280
- :type_name => 'PL/SQL BOOLEAN',
286
+ :type_name => boolean_type_name,
281
287
  :schema_name => 'SYS',
282
288
  :type_metadata => boolean_type_attrs,
283
289
  :inspect => '#<OCI8::Metadata::Collection: BOOLEAN>',
@@ -444,7 +450,7 @@ class TestPackageType < Minitest::Test
444
450
  :name => 'B',
445
451
  :precision => 0,
446
452
  :scale => 0,
447
- :type_name => 'PL/SQL BOOLEAN',
453
+ :type_name => boolean_type_name,
448
454
  :schema_name => 'SYS',
449
455
  :fsprecision => 0,
450
456
  :lfprecision => 0,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-oci8
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.12
4
+ version: 2.2.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kubo Takehiro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-30 00:00:00.000000000 Z
11
+ date: 2024-08-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: 'ruby-oci8 is a ruby interface for Oracle using OCI8 API. It is available
14
14
  with Oracle 10g or later including Oracle Instant Client.
@@ -152,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
152
152
  - !ruby/object:Gem::Version
153
153
  version: '0'
154
154
  requirements: []
155
- rubygems_version: 3.4.1
155
+ rubygems_version: 3.5.5
156
156
  signing_key:
157
157
  specification_version: 4
158
158
  summary: Ruby interface for Oracle using OCI8 API