libddwaf 1.24.1.0.1-arm64-darwin → 1.24.1.1.0-arm64-darwin

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b2777036186023f0cb57302c5e7803cb118c2d4b482eab098abcf247e6739289
4
- data.tar.gz: 25fe4e393d11e3efe3403fbea34b2cba9ea9dd4d365d175467c93260e566056c
3
+ metadata.gz: 20a320cedc5fb4c6d94dc099b6a7bafc64affb79eb93cf1dce2780e86c3ee469
4
+ data.tar.gz: e8930d8fbd01f9bccb5bec8e5083c1dd9cd46af38e293b847e0fb4783fc9bd34
5
5
  SHA512:
6
- metadata.gz: a0e4cd4c6de88eb36b69ab03554749950fe59e3e2c5b66484165766fba32b5a85dbc8c828bf321e842ba03f199e0a78cd06c5dd42c78b66cef25dc309886c230
7
- data.tar.gz: ca30f1b14e0e31edea04af6f9a309f533c1fe7258f682f6f676ea0f77af185fe6b01743f56cc108e4b7aa263972ff1067dfe54015c3e3a5cd6e4c2c645241ac3
6
+ metadata.gz: 3fd4185e435715d19d2ed3580286e3837a7560de3324ef9c253605a060ab84959879dbd92c1572d476668a48e796243480e1b803577bce77661dd6886769fabe
7
+ data.tar.gz: 471a5a438ecb9dcab06a0f6a68271e8429fc67436c1f89112e4ac5a795e3ec300d33e851022323ce12b27a80c0492f28cdb0cb1ac4c17010bc4ffc1f3ec01b9d
data/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
- # Unreleased v1.23.0.0.0
1
+ # Unreleased
2
+
3
+ # 2025-08-15 v1.24.1.1.0
4
+
5
+ ## Added
6
+
7
+ - Add `LibDDWAF::Object#input_truncated?` method that returns true if the input object was truncated during conversion to libddwaf object
8
+
9
+ ## Changed
10
+
11
+ - Change `Handle#known_addresses` to cache the result
12
+
13
+ # 2025-05-20 v1.24.1.0.0
2
14
 
3
15
  ## Added
4
16
 
data/README.md ADDED
@@ -0,0 +1,124 @@
1
+ # libddwaf Ruby bindings
2
+
3
+ ``libddwaf-rb`` is library exposing the libddwaf C++ library to Ruby, packaging it in a multiplatform gem.
4
+
5
+ For the libddwaf implementation, see this repository:
6
+ - [``libddwaf``: libddwaf](https://github.com/DataDog/libddwaf.git)
7
+
8
+
9
+
10
+ ## Rake tasks
11
+
12
+ ### Outline
13
+
14
+ A typical workflow is as follows:
15
+
16
+ ```
17
+ rake fetch # fetch prebuilt libddwaf binaries tarball in vendor/libddwaf
18
+ rake extract # extract downloaded tarball in vendor/libddwaf
19
+ rake spec # run rspec
20
+ rake binary # build the gem
21
+ ```
22
+
23
+ Note that each depends on the previous one, but `fetch` and `extract` are lazy, which proves useful to produce manual builds.
24
+
25
+ ### Platform selection
26
+
27
+ By default the above will automatically use the local Ruby platform.
28
+
29
+ Since libddwaf binary builds are available upstream, it's possible to build gems for any platform on any other platform. To that end `fetch`, `extract`, and `binary` can take an argument to specify the Ruby platform for which these operations should apply:
30
+
31
+ ```
32
+ rake fetch[x86_64-linux-musl]
33
+ rake extract[x86_64-linux-musl]
34
+ rake binary[x86_64-linux-musl]
35
+ ```
36
+
37
+ Of course you can't force the platform for `rspec` since that requires running code; see the Docker section below for ways to achieve that.
38
+
39
+ Note that zsh gives special meaning to brackets, therefore you may need to quote the argument:
40
+
41
+ ```
42
+ rake 'fetch[x86_64-linux-musl]'
43
+ ```
44
+
45
+ Available platforms are:
46
+
47
+ ```
48
+ x86_64-linux-musl # Alpine build: targets musl-based Linux
49
+ x86_64-linux-gnu # Debian build: targets glibc-based Linux
50
+ x86_64-linux # Portable build: targets multiple linux libc
51
+ x86_64-darwin # Darwin build: targets macOS
52
+ aarch64-linux-musl # Same as above, for ARMv8
53
+ aarch64-linux-gnu # Same as above, for ARMv8
54
+ aarch64-linux # Same as above, for ARMv8
55
+ arm64-darwin # Same as above, for Apple Silicon
56
+ java # JRuby build, universal
57
+ ```
58
+
59
+ Note: since it is not (yet) possible to package gems for the `java` Ruby platform any other way than `java`, it has to package all the native architectures.
60
+
61
+ In addition, options can be specified for the portable build:
62
+
63
+ ```
64
+ rake binary[x86_64-linux:gnu+musl] # Combined build: combine musl and glibc builds, selecting one at runtime
65
+ rake binary[x86_64-linux:llvm] # Hybrid build: linked to llvm static libs and built against a musl sysroot
66
+ ```
67
+
68
+ See upstream libddwaf for details about the [hybrid portable build](https://github.com/DataDog/libddwaf/blob/master/docker/libddwaf/README.md).
69
+
70
+ ## Testing with Docker
71
+
72
+ Unless using Docker for Mac, remember to enable foreign CPU emulation via QEMU:
73
+
74
+ ```
75
+ # aarch64 on x86_64 hardware
76
+ docker run --privileged --rm tonistiigi/binfmt --install arm64
77
+ # x86_64 on aarch64 hardware
78
+ docker run --privileged --rm tonistiigi/binfmt --install amd64
79
+ ```
80
+
81
+ Then you can substitute e.g `--platform linux/x86_64` with `--platform linux/aarch64` below.
82
+
83
+ ### GNU (Debian)
84
+
85
+ ```
86
+ # this is too old for aarch64
87
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.1 sh -c 'rm -fv Gemfile.lock && gem install bundler -v "~> 1.17" && bundle install && bundle exec rake spec'
88
+ # these are fine for aarch64
89
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.2 sh -c 'rm -fv Gemfile.lock && gem install bundler -v "~> 1.17" && bundle install && bundle exec rake spec'
90
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.3 sh -c 'rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
91
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.4 sh -c 'rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
92
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.5 sh -c 'rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
93
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.6 sh -c 'rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
94
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.7 sh -c 'rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
95
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:3.0 sh -c 'rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
96
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:3.1 sh -c 'rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
97
+ ```
98
+
99
+ ### musl (Alpine)
100
+
101
+ ```
102
+ # these are too old for aarch64
103
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.1-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler -v "~> 1.17" && bundle install && bundle exec rake spec'
104
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.2-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler -v "~> 1.17" && bundle install && bundle exec rake spec'
105
+ # these are fine for aarch64
106
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.3-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
107
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.4-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
108
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.5-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
109
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.6-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
110
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:2.7-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
111
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:3.0-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
112
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:3.1-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
113
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" ruby:3.1-alpine sh -c 'apk update && apk add build-base git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
114
+ ```
115
+
116
+ ### JRuby
117
+
118
+ ```
119
+ # these are too old for aarch64
120
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" jruby:9.2.8.0 sh -c 'apt-get update && apt-get install -y build-essential git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
121
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" jruby:9.3.0.0 sh -c 'apt-get update && apt-get install -y build-essential git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
122
+ # this is fine for aarch64
123
+ docker run --rm -it --platform linux/x86_64 -v "${PWD}":"${PWD}" -w "${PWD}" jruby:9.3.4.0 sh -c 'apt-get update && apt-get install -y build-essential git && rm -fv Gemfile.lock && gem install bundler:2.2.22 && bundle install && bundle exec rake spec'
124
+ ```
@@ -8,7 +8,7 @@ module Datadog
8
8
  module_function
9
9
 
10
10
  # standard:disable Metrics/MethodLength,Metrics/CyclomaticComplexity
11
- def ruby_to_object(val, max_container_size: nil, max_container_depth: nil, max_string_length: nil, coerce: true)
11
+ def ruby_to_object(val, max_container_size: nil, max_container_depth: nil, max_string_length: nil, top_obj: nil, coerce: true)
12
12
  case val
13
13
  when Array
14
14
  obj = LibDDWAF::Object.new
@@ -16,19 +16,25 @@ module Datadog
16
16
  raise ConversionError, "Could not convert into object: #{val}" if res.null?
17
17
 
18
18
  max_index = max_container_size - 1 if max_container_size
19
- unless max_container_depth == 0
19
+ if max_container_depth == 0
20
+ top_obj&.mark_as_input_truncated!
21
+ else
20
22
  val.each.with_index do |e, i|
21
23
  member = Converter.ruby_to_object(
22
24
  e,
23
25
  max_container_size: max_container_size,
24
26
  max_container_depth: (max_container_depth - 1 if max_container_depth),
25
27
  max_string_length: max_string_length,
28
+ top_obj: top_obj || obj,
26
29
  coerce: coerce
27
30
  )
28
31
  e_res = LibDDWAF.ddwaf_object_array_add(obj, member)
29
32
  raise ConversionError, "Could not add to array object: #{e.inspect}" unless e_res
30
33
 
31
- break val if max_index && i >= max_index
34
+ if max_index && i >= max_index
35
+ (top_obj || obj).mark_as_input_truncated!
36
+ break val
37
+ end
32
38
  end
33
39
  end
34
40
 
@@ -39,24 +45,33 @@ module Datadog
39
45
  raise ConversionError, "Could not convert into object: #{val}" if res.null?
40
46
 
41
47
  max_index = max_container_size - 1 if max_container_size
42
- unless max_container_depth == 0
48
+ if max_container_depth == 0
49
+ top_obj&.mark_as_input_truncated!
50
+ else
43
51
  val.each.with_index do |e, i|
44
52
  # for Steep, which doesn't handle |(k, v), i|
45
53
  k = e[0]
46
54
  v = e[1]
47
55
 
48
- k = k.to_s[0, max_string_length] if max_string_length
56
+ if max_string_length && k.length > max_string_length
57
+ k = k.to_s[0, max_string_length]
58
+ (top_obj || obj).mark_as_input_truncated!
59
+ end
49
60
  member = Converter.ruby_to_object(
50
61
  v,
51
62
  max_container_size: max_container_size,
52
63
  max_container_depth: (max_container_depth - 1 if max_container_depth),
53
64
  max_string_length: max_string_length,
65
+ top_obj: top_obj || obj,
54
66
  coerce: coerce
55
67
  )
56
68
  kv_res = LibDDWAF.ddwaf_object_map_addl(obj, k.to_s, k.to_s.bytesize, member)
57
69
  raise ConversionError, "Could not add to map object: #{k.inspect} => #{v.inspect}" unless kv_res
58
70
 
59
- break val if max_index && i >= max_index
71
+ if max_index && i >= max_index
72
+ (top_obj || obj).mark_as_input_truncated!
73
+ break val
74
+ end
60
75
  end
61
76
  end
62
77
 
@@ -64,15 +79,21 @@ module Datadog
64
79
  when String
65
80
  obj = LibDDWAF::Object.new
66
81
  encoded_val = val.to_s.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
67
- val = encoded_val[0, max_string_length] if max_string_length
68
- str = val.to_s
82
+ if max_string_length && encoded_val.length > max_string_length
83
+ encoded_val = encoded_val[0, max_string_length]
84
+ (top_obj || obj).mark_as_input_truncated!
85
+ end
86
+ str = encoded_val.to_s
69
87
  res = LibDDWAF.ddwaf_object_stringl(obj, str, str.bytesize)
70
88
  raise ConversionError, "Could not convert into object: #{val.inspect}" if res.null?
71
89
 
72
90
  obj
73
91
  when Symbol
74
92
  obj = LibDDWAF::Object.new
75
- val = val.to_s[0, max_string_length] if max_string_length
93
+ if max_string_length
94
+ val = val.to_s[0, max_string_length]
95
+ (top_obj || obj).mark_as_input_truncated!
96
+ end
76
97
  str = val.to_s
77
98
  res = LibDDWAF.ddwaf_object_stringl(obj, str, str.bytesize)
78
99
  raise ConversionError, "Could not convert into object: #{val.inspect}" if res.null?
@@ -37,6 +37,8 @@ module Datadog
37
37
  #
38
38
  # @return [Array<String>] the list of known addresses
39
39
  def known_addresses
40
+ return @known_addresses if defined?(@known_addresses)
41
+
40
42
  ensure_pointer_presence!
41
43
 
42
44
  count = LibDDWAF::UInt32Ptr.new
@@ -44,8 +46,7 @@ module Datadog
44
46
 
45
47
  return [] if count == 0 # list is null
46
48
 
47
- list.get_array_of_string(0, count[:value])
48
- # TODO: garbage collect the count?
49
+ @known_addresses = list.get_array_of_string(0, count[:value]).compact
49
50
  end
50
51
 
51
52
  private
@@ -37,15 +37,6 @@ module Datadog
37
37
  Gem::Platform.local.os
38
38
  end
39
39
 
40
- def self.local_version
41
- return nil unless local_os == "linux"
42
-
43
- # Old rubygems don't handle non-gnu linux correctly
44
- return ::Regexp.last_match(1) if RUBY_PLATFORM =~ /linux-(.+)$/
45
-
46
- "gnu"
47
- end
48
-
49
40
  def self.local_cpu
50
41
  if RUBY_ENGINE == "jruby"
51
42
  os_arch = java.lang.System.get_property("os.arch")
@@ -66,33 +57,6 @@ module Datadog
66
57
  __dir__ || raise("__dir__ is nil: eval?")
67
58
  end
68
59
 
69
- def self.vendor_dir
70
- File.join(source_dir, "../../../../vendor")
71
- end
72
-
73
- def self.libddwaf_vendor_dir
74
- File.join(vendor_dir, "libddwaf")
75
- end
76
-
77
- def self.shared_lib_triplet(version: local_version)
78
- version ? "#{local_os}-#{version}-#{local_cpu}" : "#{local_os}-#{local_cpu}"
79
- end
80
-
81
- def self.libddwaf_dir
82
- default = File.join(libddwaf_vendor_dir,
83
- "libddwaf-#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{shared_lib_triplet}")
84
- candidates = [
85
- default
86
- ]
87
-
88
- if local_os == "linux"
89
- candidates << File.join(libddwaf_vendor_dir,
90
- "libddwaf-#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{shared_lib_triplet(version: nil)}")
91
- end
92
-
93
- candidates.find { |d| Dir.exist?(d) } || default
94
- end
95
-
96
60
  def self.shared_lib_extname
97
61
  if Gem::Platform.local.os == "darwin"
98
62
  ".dylib"
@@ -104,6 +68,9 @@ module Datadog
104
68
  end
105
69
 
106
70
  def self.shared_lib_path
71
+ variant = "#{Datadog::AppSec::WAF::VERSION::BASE_STRING}-#{local_os}-#{local_cpu}"
72
+ libddwaf_dir = File.join(source_dir, "../../../../vendor/libddwaf/libddwaf-#{variant}")
73
+
107
74
  File.join(libddwaf_dir, "lib", "libddwaf#{shared_lib_extname}")
108
75
  end
109
76
 
@@ -169,6 +136,14 @@ module Datadog
169
136
  :valueUnion, ObjectValueUnion,
170
137
  :nbEntries, :uint64,
171
138
  :type, :ddwaf_obj_type
139
+
140
+ def input_truncated?
141
+ @input_truncated == true
142
+ end
143
+
144
+ def mark_as_input_truncated!
145
+ @input_truncated = true
146
+ end
172
147
  end
173
148
 
174
149
  typedef Object.by_ref, :ddwaf_object
@@ -5,7 +5,7 @@ module Datadog
5
5
  BASE_STRING = "1.24.1"
6
6
  # NOTE: Every change to the `BASE_STRING` should be accompanied
7
7
  # by a reset of the patch version in the `STRING` below.
8
- STRING = "#{BASE_STRING}.0.1"
8
+ STRING = "#{BASE_STRING}.1.0"
9
9
  MINIMUM_RUBY_VERSION = "2.5"
10
10
  end
11
11
  end
data/libddwaf.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require "datadog/appsec/waf/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "libddwaf"
7
+ spec.version = Datadog::AppSec::WAF::VERSION::STRING
8
+ spec.required_ruby_version = [">= #{Datadog::AppSec::WAF::VERSION::MINIMUM_RUBY_VERSION}"]
9
+ spec.required_rubygems_version = ">= 2.0.0"
10
+ spec.authors = ["Datadog, Inc."]
11
+ spec.email = ["dev@datadoghq.com"]
12
+
13
+ spec.summary = "Datadog WAF"
14
+ spec.description = <<-EOS.gsub(/^[\s]+/, "")
15
+ libddwaf packages a WAF implementation in C++, exposed to Ruby
16
+ EOS
17
+
18
+ spec.homepage = "https://github.com/DataDog/libddwaf-rb"
19
+ spec.license = "BSD-3-Clause"
20
+
21
+ if spec.respond_to?(:metadata)
22
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
23
+ else
24
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
25
+ end
26
+
27
+ libddwaf_version = Datadog::AppSec::WAF::VERSION::BASE_STRING
28
+
29
+ spec.files = ["libddwaf.gemspec"]
30
+ spec.files.concat(Dir.glob("lib/**/*.rb"))
31
+ spec.files.concat(Dir.glob("{vendor/rbs,sig}/**/*.rbs"))
32
+ spec.files.concat(Dir.glob("{README,CHANGELOG,LICENSE,NOTICE}*"))
33
+ spec.files.concat(%W[
34
+ vendor/libddwaf/libddwaf-#{libddwaf_version}-darwin-arm64/lib/libddwaf.dylib
35
+ vendor/libddwaf/libddwaf-#{libddwaf_version}-darwin-x86_64/lib/libddwaf.dylib
36
+ vendor/libddwaf/libddwaf-#{libddwaf_version}-linux-aarch64/lib/libddwaf.so
37
+ vendor/libddwaf/libddwaf-#{libddwaf_version}-linux-x86_64/lib/libddwaf.so
38
+ ])
39
+
40
+ spec.require_paths = ["lib"]
41
+
42
+ spec.add_dependency "ffi", "~> 1.0"
43
+ end
@@ -0,0 +1,29 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ class Context
5
+ @context_ptr: ::FFI::Pointer
6
+
7
+ @retained: Array[untyped]
8
+
9
+ RESULT_CODE: ::Hash[::Symbol, ::Symbol]
10
+
11
+ def initialize: (::FFI::Pointer context_ptr) -> void
12
+
13
+ def finalize!: () -> void
14
+
15
+ def run: (WAF::data persistent_data, WAF::data ephemeral_data, ?::Integer timeout) -> Result
16
+
17
+ private
18
+
19
+ def ensure_pointer_presence!: () -> void
20
+
21
+ def retained: () -> Array[untyped]
22
+
23
+ def retain: (top object) -> void
24
+
25
+ def release: (top object) -> void
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,11 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ module Converter
5
+ def self.ruby_to_object: (top val, ?max_container_size: ::Integer?, ?max_container_depth: ::Integer?, ?max_string_length: ::Integer?, ?top_obj: LibDDWAF::Object?, ?coerce: bool?) -> LibDDWAF::Object
6
+
7
+ def self.object_to_ruby: (LibDDWAF::Object obj) -> WAF::data
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ class Error < StandardError
5
+ end
6
+
7
+ class InstanceFinalizedError < Error
8
+ end
9
+
10
+ class ConversionError < Error
11
+ end
12
+
13
+ class LibDDWAFError < Error
14
+ attr_reader diagnostics: WAF::data
15
+
16
+ def initialize: (::String msg, ?diagnostics: WAF::data?) -> void
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,21 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ class Handle
5
+ @handle_ptr: ::FFI::Pointer
6
+
7
+ def initialize: (::FFI::Pointer handle_ptr) -> void
8
+
9
+ def finalize!: () -> void
10
+
11
+ def build_context: () -> Context
12
+
13
+ def known_addresses: () -> known_addresses
14
+
15
+ private
16
+
17
+ def ensure_pointer_presence!: () -> void
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,23 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ class HandleBuilder
5
+ @builder_ptr: ::FFI::Pointer
6
+
7
+ def initialize: (?limits: ::Hash[::Symbol, ::Integer], ?obfuscator: ::Hash[::Symbol, ::String]) -> void
8
+
9
+ def finalize!: () -> void
10
+
11
+ def build_handle: () -> Handle
12
+
13
+ def add_or_update_config: (data config, path: ::String) -> data
14
+
15
+ def remove_config_at_path: (::String path) -> bool
16
+
17
+ private
18
+
19
+ def ensure_pointer_presence!: () -> void
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,161 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ module LibDDWAF
5
+ DEFAULT_MAX_CONTAINER_SIZE: ::Integer
6
+ DEFAULT_MAX_CONTAINER_DEPTH: ::Integer
7
+ DEFAULT_MAX_STRING_LENGTH: ::Integer
8
+
9
+ DDWAF_MAX_CONTAINER_SIZE: ::Integer
10
+ DDWAF_MAX_CONTAINER_DEPTH: ::Integer
11
+ DDWAF_MAX_STRING_LENGTH: ::Integer
12
+
13
+ DDWAF_RUN_TIMEOUT: ::Integer
14
+
15
+ extend ::FFI::Library
16
+
17
+ def self.typedef: [T < ::FFI::Type, N, R, C] (T old, Symbol | ::FFI::DataConverter[N, R, C] add, ?untyped) -> T
18
+ | (Symbol old, Symbol add, ?untyped) -> (::FFI::Type | ::FFI::Enum)
19
+ | [X < ::FFI::DataConverter[N, R, C], N, R, C] (X old, Symbol add, ?untyped) -> ::FFI::Type::Mapped[X, N, R, C]
20
+ | (:enum old, Array[Symbol | Integer] add, ?untyped) -> ::FFI::Enum
21
+ | (:enum old, Symbol | ::FFI::Type add, Array[Symbol | Integer] info) -> ::FFI::Enum
22
+ | (untyped, ::Symbol) -> void
23
+
24
+ def self.callback: (::Symbol name, Array[::FFI::Library::ffi_lib_type] params, ::FFI::Library::ffi_lib_type ret) -> ::FFI::CallbackInfo
25
+
26
+ def self.enum: (*(Symbol | Integer) args) -> ::FFI::Enum
27
+ | (Array[Symbol | Integer] values) -> ::FFI::Enum
28
+
29
+ def self.local_os: () -> ::String
30
+ def self.local_cpu: () -> ::String
31
+ def self.local_version: () -> (::String | nil)
32
+ def self.source_dir: () -> ::String
33
+ def self.vendor_dir: () -> ::String
34
+ def self.libddwaf_vendor_dir: () -> ::String
35
+ def self.shared_lib_triplet: (?version: ::String?) -> ::String
36
+ def self.libddwaf_dir: () -> ::String
37
+ def self.shared_lib_extname: () -> ::String
38
+ def self.shared_lib_path: () -> ::String
39
+
40
+ # version
41
+
42
+ def self.ddwaf_get_version: () -> ::String
43
+
44
+ # ddwaf::object data structure
45
+
46
+ DDWAF_OBJ_TYPE: ::FFI::Enum
47
+
48
+ class UInt32Ptr < ::FFI::Struct[::FFI::AbstractMemory, ::Integer]
49
+ end
50
+
51
+ class UInt64Ptr < ::FFI::Struct[::FFI::AbstractMemory, ::Integer]
52
+ end
53
+
54
+ class SizeTPtr < ::FFI::Struct[::FFI::AbstractMemory, ::Integer]
55
+ end
56
+
57
+ class ObjectValueUnion < ::FFI::Union[::FFI::AbstractMemory, untyped]
58
+ end
59
+
60
+ class Object < ::FFI::Struct[::FFI::AbstractMemory, untyped]
61
+ def input_truncated?: () -> bool
62
+
63
+ def mark_as_input_truncated!: () -> bool
64
+ end
65
+
66
+ # setters
67
+
68
+ def self.ddwaf_object_invalid: (LibDDWAF::Object) -> ::FFI::Pointer
69
+ def self.ddwaf_object_string: (LibDDWAF::Object, ::String) -> ::FFI::Pointer
70
+ def self.ddwaf_object_stringl: (LibDDWAF::Object, ::String, ::Integer) -> ::FFI::Pointer
71
+ def self.ddwaf_object_stringl_nc: (LibDDWAF::Object, ::String, ::Integer) -> ::FFI::Pointer
72
+ def self.ddwaf_object_unsigned: (LibDDWAF::Object, ::Integer) -> ::FFI::Pointer
73
+ def self.ddwaf_object_signed: (LibDDWAF::Object, ::Integer) -> ::FFI::Pointer
74
+ def self.ddwaf_object_string_from_unsigned: (LibDDWAF::Object, ::Integer) -> ::FFI::Pointer
75
+ def self.ddwaf_object_string_from_signed: (LibDDWAF::Object, ::Integer) -> ::FFI::Pointer
76
+ def self.ddwaf_object_bool: (LibDDWAF::Object, bool) -> ::FFI::Pointer
77
+ def self.ddwaf_object_float: (LibDDWAF::Object, ::Float) -> ::FFI::Pointer
78
+ def self.ddwaf_object_null: (LibDDWAF::Object) -> ::FFI::Pointer
79
+
80
+ def self.ddwaf_object_array: (LibDDWAF::Object) -> ::FFI::Pointer
81
+ def self.ddwaf_object_array_add: (LibDDWAF::Object, LibDDWAF::Object) -> bool
82
+
83
+ def self.ddwaf_object_map: (LibDDWAF::Object) -> ::FFI::Pointer
84
+ def self.ddwaf_object_map_add: (LibDDWAF::Object, ::String, LibDDWAF::Object) -> bool
85
+ def self.ddwaf_object_map_addl: (LibDDWAF::Object, ::String, ::Integer, LibDDWAF::Object) -> bool
86
+ def self.ddwaf_object_map_addl_nc: (LibDDWAF::Object, ::String, ::Integer, LibDDWAF::Object) -> bool
87
+
88
+ # getters
89
+
90
+ def self.ddwaf_object_type: (LibDDWAF::Object) -> ::FFI::Enum
91
+ def self.ddwaf_object_size: (LibDDWAF::Object) -> ::Integer
92
+ def self.ddwaf_object_length: (LibDDWAF::Object) -> ::Integer
93
+ def self.ddwaf_object_get_key: (LibDDWAF::Object, SizeTPtr) -> ::String
94
+ def self.ddwaf_object_get_string: (LibDDWAF::Object, SizeTPtr) -> ::String
95
+ def self.ddwaf_object_get_unsigned: (LibDDWAF::Object, SizeTPtr) -> ::Integer
96
+ def self.ddwaf_object_get_signed: (LibDDWAF::Object, SizeTPtr) -> ::Integer
97
+ def self.ddwaf_object_get_index: (LibDDWAF::Object, ::Integer) -> LibDDWAF::Object
98
+ def self.ddwaf_object_get_bool: (LibDDWAF::Object) -> bool
99
+ def self.ddwaf_object_get_float: (LibDDWAF::Object) -> ::Float
100
+
101
+ # freeers
102
+
103
+ def self.ddwaf_object_free: (LibDDWAF::Object) -> void
104
+
105
+ ObjectFree: ::FFI::Function
106
+ ObjectNoFree: ::FFI::Pointer
107
+
108
+ # handle builder
109
+
110
+ def self.ddwaf_builder_init: (HandleBuilderConfig) -> ::FFI::Pointer
111
+ def self.ddwaf_builder_destroy: (::FFI::Pointer) -> void
112
+
113
+ def self.ddwaf_builder_add_or_update_config: (::FFI::Pointer, ::String, ::Integer, LibDDWAF::Object, LibDDWAF::Object) -> bool
114
+ def self.ddwaf_builder_remove_config: (::FFI::Pointer, ::String, ::Integer) -> bool
115
+
116
+ def self.ddwaf_builder_build_instance: (::FFI::Pointer) -> ::FFI::Pointer
117
+
118
+ # main handle
119
+
120
+ class HandleBuilderConfig < ::FFI::Struct[::FFI::AbstractMemory, untyped]
121
+ class Limits < ::FFI::Struct[::FFI::AbstractMemory, ::Integer]
122
+ end
123
+
124
+ class Obfuscator < ::FFI::Struct[::FFI::AbstractMemory, ::FFI::Pointer]
125
+ end
126
+ end
127
+
128
+ def self.ddwaf_destroy: (::FFI::Pointer) -> void
129
+
130
+ def self.ddwaf_known_addresses: (::FFI::Pointer, UInt32Ptr) -> ::FFI::Pointer
131
+ def self.ddwaf_rule_data_ids: (::FFI::Pointer, UInt32Ptr) -> ::FFI::Pointer
132
+
133
+ # updating
134
+
135
+ DDWAF_RET_CODE: ::FFI::Enum
136
+
137
+ # running
138
+
139
+ def self.ddwaf_context_init: (::FFI::Pointer) -> ::FFI::Pointer
140
+ def self.ddwaf_context_destroy: (::FFI::Pointer) -> void
141
+
142
+ class Result < ::FFI::Struct[::FFI::AbstractMemory, untyped]
143
+ end
144
+
145
+ def self.ddwaf_run: (::FFI::Pointer, Object, Object, Result, ::Integer) -> ::Symbol
146
+ def self.ddwaf_result_free: (Result) -> void
147
+
148
+ # logging
149
+
150
+ DDWAF_LOG_LEVEL: ::FFI::Enum
151
+
152
+ type ddwaf_log_level = ::Symbol
153
+
154
+ # TODO: signature is as below but steep 1.1 does not yet support method/proc/block mapping
155
+ # type ddwaf_log_cb = ^(ddwaf_log_level, ::String, ::String, ::Integer, ::FFI::Pointer, ::Integer) -> void
156
+ type ddwaf_log_cb = ::Method | ::Proc
157
+ def self.ddwaf_set_log_cb: (ddwaf_log_cb, ddwaf_log_level) -> bool
158
+ end
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,33 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ class Result
5
+ @status: ::Symbol
6
+
7
+ @events: WAF::data
8
+
9
+ @total_runtime: ::Float
10
+
11
+ @timeout: bool
12
+
13
+ @actions: WAF::data
14
+
15
+ @derivatives: WAF::data
16
+
17
+ attr_reader status: ::Symbol
18
+
19
+ attr_reader events: WAF::data
20
+
21
+ attr_reader total_runtime: ::Float
22
+
23
+ attr_reader timeout: bool
24
+
25
+ attr_reader actions: WAF::data
26
+
27
+ attr_reader derivatives: WAF::data
28
+
29
+ def initialize: (::Symbol status, WAF::data events, ::Float total_runtime, bool timeout, WAF::data actions, WAF::data derivatives) -> void
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,13 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ module VERSION
5
+ BASE_STRING: ::String
6
+
7
+ STRING: ::String
8
+
9
+ MINIMUM_RUBY_VERSION: ::String
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Datadog
2
+ module AppSec
3
+ module WAF
4
+ type data = String | Symbol | Integer | Float | TrueClass | FalseClass | Array[data] | Hash[(String | Symbol | nil), data] | nil
5
+ type known_addresses = ::Array[::String]
6
+ type diagnostics = ::Hash[::String, untyped]
7
+
8
+ def self.version: () -> ::String
9
+
10
+ self.@logger: ::Logger
11
+ self.@log_callback: LibDDWAF::ddwaf_log_cb
12
+
13
+ def self.log_callback: (LibDDWAF::ddwaf_log_level, ::String, ::String, ::Integer, ::FFI::Pointer, ::Integer) -> void
14
+ def self.logger: () -> ::Logger
15
+ def self.logger=: (::Logger logger) -> void
16
+ end
17
+ end
18
+ end
data/sig/libddwaf.rbs ADDED
File without changes
@@ -0,0 +1,7 @@
1
+ class Gem::Platform
2
+ def self.local: () -> Gem::Platform
3
+
4
+ def os: () -> String
5
+ def cpu: () -> String
6
+ def version: () -> String
7
+ end
@@ -0,0 +1,3 @@
1
+ module Kernel
2
+ def java: () -> untyped
3
+ end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libddwaf
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.24.1.0.1
4
+ version: 1.24.1.1.0
5
5
  platform: arm64-darwin
6
6
  authors:
7
7
  - Datadog, Inc.
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2025-07-21 00:00:00.000000000 Z
10
+ date: 2025-08-15 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: ffi
@@ -39,6 +38,7 @@ files:
39
38
  - LICENSE.Apache
40
39
  - LICENSE.BSD3
41
40
  - NOTICE
41
+ - README.md
42
42
  - lib/datadog/appsec/waf.rb
43
43
  - lib/datadog/appsec/waf/context.rb
44
44
  - lib/datadog/appsec/waf/converter.rb
@@ -49,13 +49,25 @@ files:
49
49
  - lib/datadog/appsec/waf/result.rb
50
50
  - lib/datadog/appsec/waf/version.rb
51
51
  - lib/libddwaf.rb
52
+ - libddwaf.gemspec
53
+ - sig/datadog/appsec/waf.rbs
54
+ - sig/datadog/appsec/waf/context.rbs
55
+ - sig/datadog/appsec/waf/converter.rbs
56
+ - sig/datadog/appsec/waf/errors.rbs
57
+ - sig/datadog/appsec/waf/handle.rbs
58
+ - sig/datadog/appsec/waf/handle_builder.rbs
59
+ - sig/datadog/appsec/waf/lib_ddwaf.rbs
60
+ - sig/datadog/appsec/waf/result.rbs
61
+ - sig/datadog/appsec/waf/version.rbs
62
+ - sig/libddwaf.rbs
52
63
  - vendor/libddwaf/libddwaf-1.24.1-darwin-arm64/lib/libddwaf.dylib
64
+ - vendor/rbs/gem/0/gem.rbs
65
+ - vendor/rbs/jruby/0/jruby.rbs
53
66
  homepage: https://github.com/DataDog/libddwaf-rb
54
67
  licenses:
55
68
  - BSD-3-Clause
56
69
  metadata:
57
70
  allowed_push_host: https://rubygems.org
58
- post_install_message:
59
71
  rdoc_options: []
60
72
  require_paths:
61
73
  - lib
@@ -70,8 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
70
82
  - !ruby/object:Gem::Version
71
83
  version: 2.0.0
72
84
  requirements: []
73
- rubygems_version: 3.5.21
74
- signing_key:
85
+ rubygems_version: 3.6.2
75
86
  specification_version: 4
76
87
  summary: Datadog WAF
77
88
  test_files: []