libddwaf 1.14.0.0.0 → 1.18.0.0.0
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/.github/actions/docker-build-ruby/Dockerfile +5 -0
- data/.github/actions/docker-build-ruby/Dockerfile.alpine +7 -0
- data/.github/actions/docker-build-ruby/Dockerfile.jruby +6 -0
- data/.github/actions/docker-build-ruby/action.yml +57 -0
- data/.github/workflows/lint.yml +13 -12
- data/.github/workflows/package.yml +93 -174
- data/.github/workflows/test.yml +86 -190
- data/.gitignore +4 -1
- data/.steepignore +4 -0
- data/CHANGELOG.md +5 -1
- data/lib/datadog/appsec/waf/context.rb +122 -0
- data/lib/datadog/appsec/waf/converter.rb +172 -0
- data/lib/datadog/appsec/waf/handle.rb +108 -0
- data/lib/datadog/appsec/waf/lib_ddwaf.rb +307 -0
- data/lib/datadog/appsec/waf/result.rb +33 -0
- data/lib/datadog/appsec/waf/version.rb +2 -2
- data/lib/datadog/appsec/waf.rb +17 -670
- data/sig/datadog/appsec/waf/context.rbs +39 -0
- data/sig/datadog/appsec/waf/converter.rbs +11 -0
- data/sig/datadog/appsec/waf/handle.rbs +42 -0
- data/sig/datadog/appsec/waf/lib_ddwaf.rbs +156 -0
- data/sig/datadog/appsec/waf/result.rbs +33 -0
- data/sig/datadog/appsec/waf.rbs +1 -201
- metadata +22 -8
- data/vendor/rbs/ffi/0/ffi.rbs +0 -62
data/.github/workflows/test.yml
CHANGED
@@ -3,220 +3,116 @@ on:
|
|
3
3
|
- push
|
4
4
|
|
5
5
|
jobs:
|
6
|
-
test-linux:
|
6
|
+
test-cruby-linux:
|
7
7
|
strategy:
|
8
8
|
fail-fast: false
|
9
9
|
matrix:
|
10
|
+
os: [ubuntu-24.04]
|
11
|
+
ruby: ["2.5", "2.6", "2.7", "3.0", "3.1", "3.2", "3.3"]
|
12
|
+
arch: [amd64, arm64]
|
13
|
+
libc: [gnu, musl]
|
10
14
|
include:
|
11
|
-
-
|
12
|
-
cpu: x86_64
|
15
|
+
- arch: amd64
|
13
16
|
platform: x86_64-linux
|
14
|
-
|
15
|
-
qemu: amd64
|
16
|
-
libc: gnu
|
17
|
-
- os: ubuntu-20.04
|
18
|
-
cpu: aarch64
|
17
|
+
- arch: arm64
|
19
18
|
platform: aarch64-linux
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
qemu: arm64
|
58
|
-
libc: gnu
|
59
|
-
- os: ubuntu-20.04
|
60
|
-
cpu: x86_64
|
61
|
-
platform: x86_64-linux
|
62
|
-
image: ruby:2.5
|
63
|
-
qemu: amd64
|
64
|
-
libc: gnu
|
65
|
-
- os: ubuntu-20.04
|
66
|
-
cpu: x86_64
|
67
|
-
platform: x86_64-linux
|
68
|
-
image: ruby:2.4
|
69
|
-
qemu: amd64
|
70
|
-
libc: gnu
|
71
|
-
- os: ubuntu-20.04
|
72
|
-
cpu: x86_64
|
73
|
-
platform: x86_64-linux
|
74
|
-
image: ruby:2.3
|
75
|
-
qemu: amd64
|
76
|
-
libc: gnu
|
77
|
-
- os: ubuntu-20.04
|
78
|
-
cpu: x86_64
|
79
|
-
platform: x86_64-linux
|
80
|
-
image: ruby:2.2
|
81
|
-
qemu: amd64
|
82
|
-
libc: gnu
|
83
|
-
- os: ubuntu-20.04
|
84
|
-
cpu: x86_64
|
85
|
-
platform: x86_64-linux
|
86
|
-
image: ruby:2.1
|
87
|
-
qemu: amd64
|
88
|
-
libc: gnu
|
89
|
-
- os: ubuntu-20.04
|
90
|
-
cpu: x86_64
|
91
|
-
platform: x86_64-linux
|
92
|
-
image: ruby:3.1-alpine
|
93
|
-
qemu: amd64
|
94
|
-
libc: musl
|
95
|
-
- os: ubuntu-20.04
|
96
|
-
cpu: aarch64
|
97
|
-
platform: aarch64-linux
|
98
|
-
image: ruby:3.1-alpine
|
99
|
-
qemu: arm64
|
100
|
-
libc: musl
|
101
|
-
- os: ubuntu-20.04
|
102
|
-
cpu: x86_64
|
103
|
-
platform: x86_64-linux
|
104
|
-
image: ruby:3.0-alpine
|
105
|
-
qemu: amd64
|
106
|
-
libc: musl
|
107
|
-
- os: ubuntu-20.04
|
108
|
-
cpu: aarch64
|
109
|
-
platform: aarch64-linux
|
110
|
-
image: ruby:3.0-alpine
|
111
|
-
qemu: arm64
|
112
|
-
libc: musl
|
113
|
-
- os: ubuntu-20.04
|
114
|
-
cpu: x86_64
|
115
|
-
platform: x86_64-linux
|
116
|
-
image: ruby:2.7-alpine
|
117
|
-
qemu: amd64
|
118
|
-
libc: musl
|
119
|
-
- os: ubuntu-20.04
|
120
|
-
cpu: aarch64
|
121
|
-
platform: aarch64-linux
|
122
|
-
image: ruby:2.7-alpine
|
123
|
-
qemu: arm64
|
124
|
-
libc: musl
|
125
|
-
- os: ubuntu-20.04
|
126
|
-
cpu: x86_64
|
19
|
+
|
20
|
+
name: Test (Ruby ${{ matrix.ruby }}, ${{ matrix.arch }}, ${{ matrix.libc }})
|
21
|
+
runs-on: ${{ matrix.os }}
|
22
|
+
|
23
|
+
steps:
|
24
|
+
- name: Checkout
|
25
|
+
uses: actions/checkout@v4
|
26
|
+
|
27
|
+
- name: Build docker image
|
28
|
+
id: build-image
|
29
|
+
uses: ./.github/actions/docker-build-ruby
|
30
|
+
with:
|
31
|
+
ruby-version: ${{ matrix.ruby }}
|
32
|
+
arch: ${{ matrix.arch }}
|
33
|
+
libc: ${{ matrix.libc }}
|
34
|
+
|
35
|
+
- name: Bundle install
|
36
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle install
|
37
|
+
|
38
|
+
- name: Fetch binary library
|
39
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle exec rake fetch[${{ matrix.platform }}]
|
40
|
+
|
41
|
+
- name: Extract binary library
|
42
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle exec rake extract[${{ matrix.platform }}]
|
43
|
+
|
44
|
+
- name: Run specs
|
45
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle exec rake spec
|
46
|
+
|
47
|
+
test-jruby-linux:
|
48
|
+
strategy:
|
49
|
+
fail-fast: false
|
50
|
+
matrix:
|
51
|
+
os: [ubuntu-24.04]
|
52
|
+
jruby: ["9.3", "9.4"]
|
53
|
+
arch: [amd64, arm64]
|
54
|
+
include:
|
55
|
+
- arch: amd64
|
127
56
|
platform: x86_64-linux
|
128
|
-
|
129
|
-
qemu: amd64
|
130
|
-
libc: musl
|
131
|
-
- os: ubuntu-20.04
|
132
|
-
cpu: aarch64
|
57
|
+
- arch: arm64
|
133
58
|
platform: aarch64-linux
|
134
|
-
|
135
|
-
|
136
|
-
libc: musl
|
137
|
-
# TODO: jruby images have no sudo so apt-get can't get a lock
|
138
|
-
# - os: ubuntu-20.04
|
139
|
-
# cpu: x86_64
|
140
|
-
# platform: x86_64-linux-gnu
|
141
|
-
# image: jruby:9.3.0.0
|
142
|
-
# qemu: amd64
|
143
|
-
# libc: gnu
|
144
|
-
# - os: ubuntu-20.04
|
145
|
-
# cpu: x86_64
|
146
|
-
# platform: x86_64-linux-gnu
|
147
|
-
# image: jruby:9.2.8.0
|
148
|
-
# qemu: amd64
|
149
|
-
# libc: gnu
|
150
|
-
# - os: ubuntu-20.04
|
151
|
-
# cpu: x86_64
|
152
|
-
# platform: aarch64-linux-gnu
|
153
|
-
# image: jruby:9.3.4.0
|
154
|
-
# qemu: arm64
|
155
|
-
# libc: gnu
|
156
|
-
name: Test (${{ matrix.image }}, ${{ matrix.cpu }})
|
59
|
+
|
60
|
+
name: Test (Jruby ${{ matrix.jruby }}, ${{ matrix.arch }})
|
157
61
|
runs-on: ${{ matrix.os }}
|
62
|
+
|
158
63
|
steps:
|
159
|
-
- name: Enable ${{ matrix.qemu }} platform
|
160
|
-
id: qemu
|
161
|
-
if: ${{ matrix.cpu != 'amd64' }}
|
162
|
-
run: |
|
163
|
-
docker run --privileged --rm tonistiigi/binfmt:latest --install ${{ matrix.qemu }} | tee platforms.json
|
164
|
-
echo "::set-output name=platforms::$(cat platforms.json)"
|
165
|
-
- name: Start container
|
166
|
-
id: container
|
167
|
-
run: |
|
168
|
-
echo ${{ matrix.image }} > container_image
|
169
|
-
docker run --rm -d -v "${PWD}":"${PWD}" -w "${PWD}" --platform linux/${{ matrix.qemu }} ${{ matrix.image }} /bin/sleep 64d | tee container_id
|
170
|
-
docker exec -w "${PWD}" $(cat container_id) uname -a
|
171
|
-
echo "::set-output name=id::$(cat container_id)"
|
172
|
-
- name: Install Alpine system dependencies
|
173
|
-
if: ${{ matrix.libc == 'musl' }}
|
174
|
-
run: docker exec -w "${PWD}" ${{ steps.container.outputs.id }} apk add --no-cache build-base git
|
175
|
-
- name: Install JRuby system dependencies
|
176
|
-
if: ${{ startsWith(matrix.image, 'jruby') }}
|
177
|
-
run: |
|
178
|
-
docker exec -w "${PWD}" ${{ steps.container.outputs.id }} sudo apt-get update
|
179
|
-
docker exec -w "${PWD}" ${{ steps.container.outputs.id }} sudo apt-get install -y build-essential git
|
180
64
|
- name: Checkout
|
181
|
-
uses: actions/checkout@
|
182
|
-
|
183
|
-
|
184
|
-
|
65
|
+
uses: actions/checkout@v4
|
66
|
+
|
67
|
+
- name: Build docker image
|
68
|
+
id: build-image
|
69
|
+
uses: ./.github/actions/docker-build-ruby
|
70
|
+
with:
|
71
|
+
ruby-version: ${{ matrix.jruby }}
|
72
|
+
jruby: true
|
73
|
+
arch: ${{ matrix.arch }}
|
74
|
+
libc: gnu
|
75
|
+
|
76
|
+
- name: Bundle install
|
77
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle install
|
78
|
+
|
185
79
|
- name: Fetch binary library
|
186
|
-
run:
|
187
|
-
|
80
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle exec rake fetch[${{ matrix.platform }}]
|
81
|
+
|
188
82
|
- name: Extract binary library
|
189
|
-
run:
|
190
|
-
|
83
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle exec rake extract[${{ matrix.platform }}]
|
84
|
+
|
191
85
|
- name: Run specs
|
192
|
-
run:
|
193
|
-
|
86
|
+
run: ${{ steps.build-image.outputs.run-cmd }} bundle exec rake spec
|
87
|
+
|
194
88
|
test-darwin:
|
195
89
|
strategy:
|
196
90
|
fail-fast: false
|
197
91
|
matrix:
|
92
|
+
os: [macos-15, macos-15-large]
|
198
93
|
include:
|
199
|
-
- os: macos-
|
200
|
-
|
94
|
+
- os: macos-15
|
95
|
+
platform: arm64-darwin
|
96
|
+
- os: macos-15-large
|
201
97
|
platform: x86_64-darwin
|
202
|
-
|
203
|
-
|
204
|
-
# platform: arm64-darwin
|
205
|
-
name: Test (${{ matrix.os }} ${{ matrix.cpu }})
|
98
|
+
|
99
|
+
name: Test (${{ matrix.os }})
|
206
100
|
runs-on: ${{ matrix.os }}
|
101
|
+
env:
|
102
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
103
|
+
|
207
104
|
steps:
|
208
105
|
- name: Checkout
|
209
|
-
uses: actions/checkout@
|
106
|
+
uses: actions/checkout@v4
|
107
|
+
|
210
108
|
- name: Bundle
|
211
|
-
run:
|
212
|
-
|
109
|
+
run: bundle install
|
110
|
+
|
213
111
|
- name: Fetch binary library
|
214
|
-
run:
|
215
|
-
|
112
|
+
run: bundle exec rake fetch[${{ matrix.platform }}]
|
113
|
+
|
216
114
|
- name: Extract binary library
|
217
|
-
run:
|
218
|
-
bundle exec rake extract[${{ matrix.platform }}]
|
219
|
-
- name: Run specs
|
220
|
-
run: |
|
221
|
-
bundle exec rake spec
|
115
|
+
run: bundle exec rake extract[${{ matrix.platform }}]
|
222
116
|
|
117
|
+
- name: Run specs
|
118
|
+
run: bundle exec rake spec
|
data/.gitignore
CHANGED
data/.steepignore
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
ffi/library.rbs:36:45 "Type `::FFI::DataConverter` is generic but used as a non generic type"
|
2
|
+
ffi/struct.rbs:5:15 "Type application of `::FFI::Type::Mapped` doesn't satisfy the constraints"
|
3
|
+
ffi/struct.rbs:23:29 "Type application of `::FFI::Type::Mapped` doesn't satisfy the constraints"
|
4
|
+
ffi/auto_pointer.rbs:15:65 "Type application of `::FFI::AutoPointer::Releaser::_Proc` doesn't satisfy the constraints"
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# 2024-10-29 v.1.15.0.0.0
|
2
|
+
- Update to libddwaf 1.15.0
|
3
|
+
- Changed `Datadog::AppSec::WAF::Context#run` interface to accommodate ephemeral data ([Breaking change](https://github.com/DataDog/libddwaf/blob/master/CHANGELOG.md#v1150-unstable))
|
4
|
+
|
1
5
|
# 2023-09-11 v.1.14.0.0.0
|
2
6
|
- Update to libddwaf 1.14.0
|
3
7
|
- Add support for `Float` and `Nil` scalar values when converting from ruby to WAF Object and vice versa.
|
@@ -6,7 +10,7 @@
|
|
6
10
|
# 2023-08-29 v.1.11.0.0.0
|
7
11
|
|
8
12
|
- Update to libddwaf 1.11.0
|
9
|
-
- Changed `Datadog::AppSec::WAF::Handle#ruleset_info` to `Datadog::AppSec::WAF::Handle#diagnostics
|
13
|
+
- Changed `Datadog::AppSec::WAF::Handle#ruleset_info` to `Datadog::AppSec::WAF::Handle#diagnostics`. (Breaking change)
|
10
14
|
The schema of the diagnostics variable can be found [here](https://github.com/DataDog/libddwaf/blob/master/schema/diagnostics.json)
|
11
15
|
- Changed `Datadog::AppSec::WAF::Result#data` to `Datadog::AppSec::WAF::Result#events`. (Breaking change)
|
12
16
|
The schema of the events variable can be found [here](https://github.com/DataDog/libddwaf/blob/master/schema/events.json)
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module WAF
|
6
|
+
# Ruby representation of the ddwaf_context in libddwaf
|
7
|
+
# See https://github.com/DataDog/libddwaf/blob/10e3a1dfc7bc9bb8ab11a09a9f8b6b339eaf3271/BINDING_IMPL_NOTES.md?plain=1#L125-L158
|
8
|
+
class Context
|
9
|
+
RESULT_CODE = {
|
10
|
+
ddwaf_ok: :ok,
|
11
|
+
ddwaf_match: :match,
|
12
|
+
ddwaf_err_internal: :err_internal,
|
13
|
+
ddwaf_err_invalid_object: :err_invalid_object,
|
14
|
+
ddwaf_err_invalid_argument: :err_invalid_argument
|
15
|
+
}.freeze
|
16
|
+
|
17
|
+
attr_reader :context_obj
|
18
|
+
|
19
|
+
def initialize(handle)
|
20
|
+
handle_obj = handle.handle_obj
|
21
|
+
retain(handle)
|
22
|
+
|
23
|
+
@context_obj = LibDDWAF.ddwaf_context_init(handle_obj)
|
24
|
+
raise LibDDWAF::Error, 'Could not create context' if @context_obj.null?
|
25
|
+
|
26
|
+
validate!
|
27
|
+
end
|
28
|
+
|
29
|
+
def finalize
|
30
|
+
invalidate!
|
31
|
+
|
32
|
+
retained.each do |retained_obj|
|
33
|
+
next unless retained_obj.is_a?(LibDDWAF::Object)
|
34
|
+
|
35
|
+
LibDDWAF.ddwaf_object_free(retained_obj)
|
36
|
+
end
|
37
|
+
|
38
|
+
LibDDWAF.ddwaf_context_destroy(context_obj)
|
39
|
+
end
|
40
|
+
|
41
|
+
def run(persistent_data, ephemeral_data, timeout = LibDDWAF::DDWAF_RUN_TIMEOUT)
|
42
|
+
valid!
|
43
|
+
|
44
|
+
persistent_data_obj = Converter.ruby_to_object(
|
45
|
+
persistent_data,
|
46
|
+
max_container_size: LibDDWAF::DDWAF_MAX_CONTAINER_SIZE,
|
47
|
+
max_container_depth: LibDDWAF::DDWAF_MAX_CONTAINER_DEPTH,
|
48
|
+
max_string_length: LibDDWAF::DDWAF_MAX_STRING_LENGTH,
|
49
|
+
coerce: false
|
50
|
+
)
|
51
|
+
if persistent_data_obj.null?
|
52
|
+
raise LibDDWAF::Error, "Could not convert persistent data: #{persistent_data.inspect}"
|
53
|
+
end
|
54
|
+
|
55
|
+
# retain C objects in memory for subsequent calls to run
|
56
|
+
retain(persistent_data_obj)
|
57
|
+
|
58
|
+
ephemeral_data_obj = Converter.ruby_to_object(
|
59
|
+
ephemeral_data,
|
60
|
+
max_container_size: LibDDWAF::DDWAF_MAX_CONTAINER_SIZE,
|
61
|
+
max_container_depth: LibDDWAF::DDWAF_MAX_CONTAINER_DEPTH,
|
62
|
+
max_string_length: LibDDWAF::DDWAF_MAX_STRING_LENGTH,
|
63
|
+
coerce: false
|
64
|
+
)
|
65
|
+
if ephemeral_data_obj.null?
|
66
|
+
raise LibDDWAF::Error, "Could not convert ephemeral data: #{ephemeral_data.inspect}"
|
67
|
+
end
|
68
|
+
|
69
|
+
result_obj = LibDDWAF::Result.new
|
70
|
+
raise LibDDWAF::Error, 'Could not create result object' if result_obj.null?
|
71
|
+
|
72
|
+
code = LibDDWAF.ddwaf_run(@context_obj, persistent_data_obj, ephemeral_data_obj, result_obj, timeout)
|
73
|
+
|
74
|
+
result = Result.new(
|
75
|
+
RESULT_CODE[code],
|
76
|
+
Converter.object_to_ruby(result_obj[:events]),
|
77
|
+
result_obj[:total_runtime],
|
78
|
+
result_obj[:timeout],
|
79
|
+
Converter.object_to_ruby(result_obj[:actions]),
|
80
|
+
Converter.object_to_ruby(result_obj[:derivatives])
|
81
|
+
)
|
82
|
+
|
83
|
+
[RESULT_CODE[code], result]
|
84
|
+
ensure
|
85
|
+
LibDDWAF.ddwaf_result_free(result_obj) if result_obj
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def validate!
|
91
|
+
@valid = true
|
92
|
+
end
|
93
|
+
|
94
|
+
def invalidate!
|
95
|
+
@valid = false
|
96
|
+
end
|
97
|
+
|
98
|
+
def valid?
|
99
|
+
@valid
|
100
|
+
end
|
101
|
+
|
102
|
+
def valid!
|
103
|
+
return if valid?
|
104
|
+
|
105
|
+
raise LibDDWAF::Error, "Attempt to use an invalid instance: #{inspect}"
|
106
|
+
end
|
107
|
+
|
108
|
+
def retained
|
109
|
+
@retained ||= []
|
110
|
+
end
|
111
|
+
|
112
|
+
def retain(object)
|
113
|
+
retained << object
|
114
|
+
end
|
115
|
+
|
116
|
+
def release(object)
|
117
|
+
retained.delete(object)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,172 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Datadog
|
4
|
+
module AppSec
|
5
|
+
module WAF
|
6
|
+
# Module responsible for Ruby-to-C and C-to-Ruby conversions
|
7
|
+
module Converter
|
8
|
+
module_function
|
9
|
+
|
10
|
+
# rubocop:disable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
11
|
+
def ruby_to_object(val, max_container_size: nil, max_container_depth: nil, max_string_length: nil, coerce: true)
|
12
|
+
case val
|
13
|
+
when Array
|
14
|
+
obj = LibDDWAF::Object.new
|
15
|
+
res = LibDDWAF.ddwaf_object_array(obj)
|
16
|
+
if res.null?
|
17
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val}"
|
18
|
+
end
|
19
|
+
|
20
|
+
max_index = max_container_size - 1 if max_container_size
|
21
|
+
val.each.with_index do |e, i| # rubocop:disable Style/MultilineIfModifier
|
22
|
+
member = Converter.ruby_to_object(e,
|
23
|
+
max_container_size: max_container_size,
|
24
|
+
max_container_depth: (max_container_depth - 1 if max_container_depth),
|
25
|
+
max_string_length: max_string_length,
|
26
|
+
coerce: coerce)
|
27
|
+
e_res = LibDDWAF.ddwaf_object_array_add(obj, member)
|
28
|
+
raise LibDDWAF::Error, "Could not add to array object: #{e.inspect}" unless e_res
|
29
|
+
|
30
|
+
break val if max_index && i >= max_index
|
31
|
+
end unless max_container_depth == 0
|
32
|
+
|
33
|
+
obj
|
34
|
+
when Hash
|
35
|
+
obj = LibDDWAF::Object.new
|
36
|
+
res = LibDDWAF.ddwaf_object_map(obj)
|
37
|
+
if res.null?
|
38
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val}"
|
39
|
+
end
|
40
|
+
|
41
|
+
max_index = max_container_size - 1 if max_container_size
|
42
|
+
val.each.with_index do |e, i| # rubocop:disable Style/MultilineIfModifier
|
43
|
+
# for Steep, which doesn't handle |(k, v), i|
|
44
|
+
k, v = e[0], e[1] # rubocop:disable Style/ParallelAssignment
|
45
|
+
|
46
|
+
k = k.to_s[0, max_string_length] if max_string_length
|
47
|
+
member = Converter.ruby_to_object(v,
|
48
|
+
max_container_size: max_container_size,
|
49
|
+
max_container_depth: (max_container_depth - 1 if max_container_depth),
|
50
|
+
max_string_length: max_string_length,
|
51
|
+
coerce: coerce)
|
52
|
+
kv_res = LibDDWAF.ddwaf_object_map_addl(obj, k.to_s, k.to_s.bytesize, member)
|
53
|
+
unless kv_res
|
54
|
+
raise LibDDWAF::Error, "Could not add to map object: #{k.inspect} => #{v.inspect}"
|
55
|
+
end
|
56
|
+
|
57
|
+
break val if max_index && i >= max_index
|
58
|
+
end unless max_container_depth == 0
|
59
|
+
|
60
|
+
obj
|
61
|
+
when String
|
62
|
+
obj = LibDDWAF::Object.new
|
63
|
+
encoded_val = val.to_s.encode('utf-8', invalid: :replace, undef: :replace)
|
64
|
+
val = encoded_val[0, max_string_length] if max_string_length
|
65
|
+
str = val.to_s
|
66
|
+
res = LibDDWAF.ddwaf_object_stringl(obj, str, str.bytesize)
|
67
|
+
if res.null?
|
68
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val.inspect}"
|
69
|
+
end
|
70
|
+
|
71
|
+
obj
|
72
|
+
when Symbol
|
73
|
+
obj = LibDDWAF::Object.new
|
74
|
+
val = val.to_s[0, max_string_length] if max_string_length
|
75
|
+
str = val.to_s
|
76
|
+
res = LibDDWAF.ddwaf_object_stringl(obj, str, str.bytesize)
|
77
|
+
if res.null?
|
78
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val.inspect}"
|
79
|
+
end
|
80
|
+
|
81
|
+
obj
|
82
|
+
when Integer
|
83
|
+
obj = LibDDWAF::Object.new
|
84
|
+
res = if coerce
|
85
|
+
LibDDWAF.ddwaf_object_string(obj, val.to_s)
|
86
|
+
elsif val < 0
|
87
|
+
LibDDWAF.ddwaf_object_signed(obj, val)
|
88
|
+
else
|
89
|
+
LibDDWAF.ddwaf_object_unsigned(obj, val)
|
90
|
+
end
|
91
|
+
if res.null?
|
92
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val.inspect}"
|
93
|
+
end
|
94
|
+
|
95
|
+
obj
|
96
|
+
when Float
|
97
|
+
obj = LibDDWAF::Object.new
|
98
|
+
res = if coerce
|
99
|
+
LibDDWAF.ddwaf_object_string(obj, val.to_s)
|
100
|
+
else
|
101
|
+
LibDDWAF.ddwaf_object_float(obj, val)
|
102
|
+
end
|
103
|
+
if res.null?
|
104
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val.inspect}"
|
105
|
+
end
|
106
|
+
|
107
|
+
obj
|
108
|
+
when TrueClass, FalseClass
|
109
|
+
obj = LibDDWAF::Object.new
|
110
|
+
res = if coerce
|
111
|
+
LibDDWAF.ddwaf_object_string(obj, val.to_s)
|
112
|
+
else
|
113
|
+
LibDDWAF.ddwaf_object_bool(obj, val)
|
114
|
+
end
|
115
|
+
if res.null?
|
116
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val.inspect}"
|
117
|
+
end
|
118
|
+
|
119
|
+
obj
|
120
|
+
when NilClass
|
121
|
+
obj = LibDDWAF::Object.new
|
122
|
+
res = if coerce
|
123
|
+
LibDDWAF.ddwaf_object_string(obj, '')
|
124
|
+
else
|
125
|
+
LibDDWAF.ddwaf_object_null(obj)
|
126
|
+
end
|
127
|
+
if res.null?
|
128
|
+
raise LibDDWAF::Error, "Could not convert into object: #{val.inspect}"
|
129
|
+
end
|
130
|
+
|
131
|
+
obj
|
132
|
+
else
|
133
|
+
Converter.ruby_to_object('')
|
134
|
+
end
|
135
|
+
end
|
136
|
+
# rubocop:enable Metrics/MethodLength,Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity
|
137
|
+
|
138
|
+
def object_to_ruby(obj)
|
139
|
+
case obj[:type]
|
140
|
+
when :ddwaf_obj_invalid, :ddwaf_obj_null
|
141
|
+
nil
|
142
|
+
when :ddwaf_obj_bool
|
143
|
+
obj[:valueUnion][:boolean]
|
144
|
+
when :ddwaf_obj_string
|
145
|
+
obj[:valueUnion][:stringValue].read_bytes(obj[:nbEntries])
|
146
|
+
when :ddwaf_obj_signed
|
147
|
+
obj[:valueUnion][:intValue]
|
148
|
+
when :ddwaf_obj_unsigned
|
149
|
+
obj[:valueUnion][:uintValue]
|
150
|
+
when :ddwaf_obj_float
|
151
|
+
obj[:valueUnion][:f64]
|
152
|
+
when :ddwaf_obj_array
|
153
|
+
(0...obj[:nbEntries]).each.with_object([]) do |i, a|
|
154
|
+
ptr = obj[:valueUnion][:array] + i * LibDDWAF::Object.size
|
155
|
+
e = Converter.object_to_ruby(LibDDWAF::Object.new(ptr))
|
156
|
+
a << e # steep:ignore
|
157
|
+
end
|
158
|
+
when :ddwaf_obj_map
|
159
|
+
(0...obj[:nbEntries]).each.with_object({}) do |i, h|
|
160
|
+
ptr = obj[:valueUnion][:array] + i * Datadog::AppSec::WAF::LibDDWAF::Object.size
|
161
|
+
o = Datadog::AppSec::WAF::LibDDWAF::Object.new(ptr)
|
162
|
+
l = o[:parameterNameLength]
|
163
|
+
k = o[:parameterName].read_bytes(l)
|
164
|
+
v = Converter.object_to_ruby(LibDDWAF::Object.new(ptr))
|
165
|
+
h[k] = v # steep:ignore
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|