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.
- checksums.yaml +4 -4
- data/NEWS +26 -0
- data/docs/hanging-after-inactivity.md +1 -1
- data/ext/oci8/extconf.rb +1 -0
- data/ext/oci8/oci8.c +2 -2
- data/ext/oci8/oci8.h +6 -5
- data/ext/oci8/oci8lib.c +14 -22
- data/ext/oci8/oraconf.rb +4 -0
- data/ext/oci8/oradate.c +0 -11
- data/ext/oci8/plthook.h +7 -1
- data/ext/oci8/plthook_elf.c +422 -197
- data/ext/oci8/plthook_osx.c +725 -91
- data/ext/oci8/plthook_win32.c +39 -25
- data/lib/oci8/oracle_version.rb +9 -1
- data/lib/oci8/version.rb +1 -1
- data/lib/oci8.rb +2 -0
- data/test/test_metadata.rb +1 -0
- data/test/test_oranumber.rb +3 -1
- data/test/test_package_type.rb +10 -4
- metadata +3 -3
data/ext/oci8/plthook_win32.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/* -*- indent-tabs-mode: nil -*-
|
2
2
|
*
|
3
|
-
* plthook_win32.c --
|
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(
|
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
|
-
|
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
|
-
|
148
|
-
ordinal_name_buflen +=
|
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
|
-
|
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
|
-
|
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 =
|
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
|
-
|
242
|
-
|
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
|
-
|
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
|
-
|
258
|
-
|
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)
|
data/lib/oci8/oracle_version.rb
CHANGED
@@ -127,7 +127,15 @@ class OCI8
|
|
127
127
|
#
|
128
128
|
# @return [String]
|
129
129
|
def to_s
|
130
|
-
|
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
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)
|
data/test/test_metadata.rb
CHANGED
@@ -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
|
data/test/test_oranumber.rb
CHANGED
@@ -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
|
-
|
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
|
data/test/test_package_type.rb
CHANGED
@@ -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 =>
|
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 =>
|
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 =>
|
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 =>
|
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.
|
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:
|
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.
|
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
|