ruby-oci8 2.2.12 → 2.2.14
Sign up to get free protection for your applications and to get access to all the features.
- 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
|