oj-introspect 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8275f7a7bc4675418e94fb048888662e5b9e9292eb0e8a7d3f5bd1cb2c4d6cc
4
- data.tar.gz: b8aa813939f082f384d4300cfe56fb41e660c366b18709a0dc8efe97336baa44
3
+ metadata.gz: 0a72b92485dbfef2a4b2fe110e3209d277c1cb98a356648d5c37d65015906b1b
4
+ data.tar.gz: 9d8047afdd2b9434fd257f05eb3bafef180c57a3b7c8e5a873bdf954dfd2dfab
5
5
  SHA512:
6
- metadata.gz: 965b4a25bd1fa1549dcb20162b0f80a6963d29352a5b2333ddc6590b3b32fa0b25e6627470aa94c327cd103472f62669f47e5c823050d4a5038ba8c6b66b10c8
7
- data.tar.gz: 688d27daf26686b8b5dfd71d926d35e3f91adcdb430d21b388dd077fd05f9e2974b296e8eb520543ab7a2f4e1e5587b2152a3437026e8a3d74591e2a436197e4
6
+ metadata.gz: 42c8c6afb2256ae41a156892379fa8535f3944f457105db6d6f6b1581008dccc2ba76e413eef725428ea70d384b69ae3d6a8657d745a3eedda7997d1da13910a
7
+ data.tar.gz: 12446b7a5f18442a2dd7695823b08ebe331a71d707583342f8b9d7034a0acef529df8368cf490b2928da6ae4d31f673783075b3a24d3f302b6dbe8aab34a8db9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- oj-introspect (0.4.0)
4
+ oj-introspect (0.5.0)
5
5
  oj (>= 3.13.22)
6
6
 
7
7
  GEM
data/bin/benchmark CHANGED
@@ -5,16 +5,21 @@ require "oj/introspect"
5
5
  require "json"
6
6
  require "benchmark/ips"
7
7
 
8
- TEST_JSON = '{ "foo": "bar" }'
8
+ TEST_JSON = File.read("./spec/fixtures/vulnerabilities.json")
9
9
 
10
10
  INTROSPECT_PARSER = Oj::Parser.introspect
11
+ FILTERED_INTROSPECT_PARSER = Oj::Introspect.new(filter: "remediations")
11
12
  USUAL_PARSER = Oj::Parser.usual
12
13
 
13
14
  Benchmark.ips do |b|
14
- b.report("Introspected") do
15
+ b.report("Introspect") do
15
16
  INTROSPECT_PARSER.parse(TEST_JSON)
16
17
  end
17
18
 
19
+ b.report("Filtered introspect") do
20
+ FILTERED_INTROSPECT_PARSER.parse(TEST_JSON)
21
+ end
22
+
18
23
  b.report("Oj usual") do
19
24
  USUAL_PARSER.parse(TEST_JSON)
20
25
  end
@@ -16,16 +16,22 @@ typedef struct _introspect_S {
16
16
  struct _usual usual; // inherit all the attributes from `_usual` struct
17
17
  struct _byte_offsets byte_offsets; // I think it's better to encapsulate common fields under a namespace
18
18
 
19
+ char *filter;
20
+ bool introspect;
21
+
19
22
  void (*delegated_start_func)(struct _ojParser *p);
20
23
  void (*delegated_free_func)(struct _ojParser *p);
24
+ VALUE (*delegated_option_func)(struct _ojParser *p, const char *key, VALUE value);
21
25
  void (*delegated_open_object_func)(struct _ojParser *p);
22
26
  void (*delegated_open_object_key_func)(struct _ojParser *p);
27
+ void (*delegated_open_array_key_func)(struct _ojParser *p);
23
28
  void (*delegated_close_object_func)(struct _ojParser *p);
24
- } *IntrospectDelegate;
29
+ } * IntrospectDelegate;
25
30
 
26
31
  static void dfree(ojParser p) {
27
32
  IntrospectDelegate d = (IntrospectDelegate)p->ctx;
28
33
 
34
+ if(d->filter != NULL) xfree(d->filter);
29
35
  xfree(d->byte_offsets.stack);
30
36
  d->delegated_free_func(p);
31
37
  }
@@ -36,6 +42,31 @@ static void start(ojParser p) {
36
42
  d->delegated_start_func(p);
37
43
  // Reset to zero so the parser and delegate can be reused.
38
44
  d->byte_offsets.current = 0;
45
+
46
+ /*
47
+ * If the `filter` is provided we will start introspecting later
48
+ * once we encounter with the key provided.
49
+ */
50
+ d->introspect = (d->filter == NULL);
51
+ }
52
+
53
+ static void copy_ruby_str(char **target, VALUE source) {
54
+ size_t len = RSTRING_LEN(source);
55
+ *target = ALLOC_N(char, len + 1);
56
+ memcpy(*target, RSTRING_PTR(source), len);
57
+ (*target)[len] = '\0'; // Parantheses are important as it means => (*target + sizeof(char) * len)
58
+ }
59
+
60
+ static VALUE option(ojParser p, const char *key, VALUE value) {
61
+ IntrospectDelegate d = (IntrospectDelegate)p->ctx;
62
+
63
+ if(strcmp(key, "filter=") == 0) {
64
+ copy_ruby_str(&d->filter, value); // We need to copy the value as GC can free it later.
65
+
66
+ return Qtrue;
67
+ }
68
+
69
+ return d->delegated_option_func(p, key, value);
39
70
  }
40
71
 
41
72
  static void ensure_byte_offsets_stack(IntrospectDelegate d) {
@@ -65,16 +96,56 @@ static void open_object_introspected(ojParser p) {
65
96
  d->delegated_open_object_func(p);
66
97
  }
67
98
 
99
+ static char * previously_inserted_key(IntrospectDelegate d) {
100
+ Key key = (d->usual.ktail - 1);
101
+
102
+ return ((size_t)key->len < sizeof(key->buf)) ? key->buf : key->key;
103
+ }
104
+
105
+ static bool should_switch_introspection(IntrospectDelegate d) {
106
+ return strcmp(d->filter, previously_inserted_key(d)) == 0;
107
+ }
108
+
109
+ /*
110
+ * WHEN there is a filter
111
+ * AND
112
+ * WHEN the introspection is disabled
113
+ * AND the last inserted key matches the filter
114
+ * THEN enable introspection
115
+ * OR
116
+ * WHEN the introspection is enabled
117
+ * AND the last inserted key matches the filter
118
+ * THEN disable introspection
119
+ */
120
+ static void switch_introspection(IntrospectDelegate d) {
121
+ if(d->filter == NULL) return;
122
+
123
+ d->introspect = should_switch_introspection(d) != d->introspect; // a XOR b
124
+ }
125
+
68
126
  static void open_object_key_introspected(ojParser p) {
69
127
  push(p);
70
128
 
71
129
  IntrospectDelegate d = (IntrospectDelegate)p->ctx;
72
130
  d->delegated_open_object_key_func(p);
131
+
132
+ if(!d->introspect) switch_introspection(d);
133
+ }
134
+
135
+ static void open_array_key_introspected(ojParser p) {
136
+ IntrospectDelegate d = (IntrospectDelegate)p->ctx;
137
+ d->delegated_open_array_key_func(p);
138
+
139
+ if(!d->introspect) switch_introspection(d);
73
140
  }
74
141
 
75
142
  static void set_introspection_values(ojParser p) {
76
143
  IntrospectDelegate d = (IntrospectDelegate)p->ctx;
77
144
 
145
+ if(!d->introspect) return;
146
+
147
+ switch_introspection(d);
148
+
78
149
  volatile VALUE obj = rb_hash_new();
79
150
  rb_hash_aset(obj, ID2SYM(rb_intern("start_byte")), INT2FIX(pop(p)));
80
151
  rb_hash_aset(obj, ID2SYM(rb_intern("end_byte")), INT2FIX(p->cur));
@@ -100,6 +171,9 @@ static void init_introspect_parser(ojParser p, VALUE ropts) {
100
171
  d->delegated_start_func = p->start;
101
172
  p->start = start;
102
173
 
174
+ d->delegated_option_func = p->option;
175
+ p->option = option;
176
+
103
177
  // We are cheating with the mark, free, and options functions. Since struct
104
178
  // _usual is the first member of struct _introspect the cast to Usual in the
105
179
  // usual.c mark() function should still work just fine.
@@ -117,7 +191,9 @@ static void init_introspect_parser(ojParser p, VALUE ropts) {
117
191
  f->close_object = close_object_introspected;
118
192
 
119
193
  f = &p->funcs[OBJECT_FUN];
194
+ d->delegated_open_array_key_func = f->open_array;
120
195
  d->delegated_open_object_key_func = f->open_object;
196
+ f->open_array = open_array_key_introspected;
121
197
  f->open_object = open_object_key_introspected;
122
198
  f->close_object = close_object_introspected;
123
199
 
@@ -126,6 +202,8 @@ static void init_introspect_parser(ojParser p, VALUE ropts) {
126
202
  d->byte_offsets.stack = ALLOC_N(long, BYTE_OFFSETS_STACK_INC_SIZE);
127
203
  d->byte_offsets.length = BYTE_OFFSETS_STACK_INC_SIZE;
128
204
 
205
+ d->filter = NULL;
206
+
129
207
  // Process options.
130
208
  oj_parser_set_option(p, ropts);
131
209
  }
@@ -1,5 +1,5 @@
1
1
  module Oj
2
2
  class Introspect
3
- VERSION = "0.4.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oj-introspect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mehmet Emin INAC
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-02 00:00:00.000000000 Z
11
+ date: 2022-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oj