psych 3.3.1-java → 4.0.2-java
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/Gemfile +1 -1
- data/Rakefile +9 -2
- data/ext/java/org/jruby/ext/psych/PsychEmitter.java +77 -33
- data/ext/java/org/jruby/ext/psych/PsychParser.java +65 -19
- data/ext/psych/yaml/loader.c +1 -1
- data/ext/psych/yaml/scanner.c +2 -2
- data/ext/psych/yaml/yaml.h +3 -3
- data/ext/psych/yaml/yaml_private.h +1 -1
- data/lib/psych/class_loader.rb +2 -2
- data/lib/psych/exception.rb +2 -2
- data/lib/psych/handler.rb +1 -1
- data/lib/psych/nodes/scalar.rb +1 -1
- data/lib/psych/scalar_scanner.rb +8 -9
- data/lib/psych/versions.rb +2 -2
- data/lib/psych/visitors/to_ruby.rb +1 -1
- data/lib/psych/visitors/yaml_tree.rb +50 -2
- data/lib/psych.jar +0 -0
- data/lib/psych.rb +142 -64
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ce72ed68be903a82b40d36da89dd265af0a701a3ee4052ede7256d195019a9b
|
4
|
+
data.tar.gz: c29db93b6a1debdeb09c7b01d6c9840a338a00b8d20cc9ad8937884966749081
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 495ed773d0916df91ff7ae075d50a1472b524fac88c516e199362b95e5d2c6df9673b921e62c1815c94903109162cccf7012ab57aae5e6c83529ab57801248ff
|
7
|
+
data.tar.gz: a7d3b990ee0fcf4137b05230a2af106b633b7e7d5e6b09343e2c83d7c4161dcbb969a7f4a9c1d534cbb79eab2259e30d0bb76c502c77e1fb4e62d646663eadf5
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -3,8 +3,8 @@ Bundler::GemHelper.install_tasks
|
|
3
3
|
|
4
4
|
require "rake/testtask"
|
5
5
|
Rake::TestTask.new(:test) do |t|
|
6
|
-
t.libs << "test"
|
7
|
-
t.
|
6
|
+
t.libs << "test/lib" << "test"
|
7
|
+
t.ruby_opts << "-rhelper"
|
8
8
|
t.test_files = FileList['test/**/test_*.rb']
|
9
9
|
t.verbose = true
|
10
10
|
t.warning = true
|
@@ -31,4 +31,11 @@ else
|
|
31
31
|
Rake::ExtensionTask.new("psych")
|
32
32
|
end
|
33
33
|
|
34
|
+
task :sync_tool do
|
35
|
+
require 'fileutils'
|
36
|
+
FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
|
37
|
+
FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
|
38
|
+
FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
|
39
|
+
end
|
40
|
+
|
34
41
|
task :default => [:compile, :test]
|
@@ -29,13 +29,16 @@ package org.jruby.ext.psych;
|
|
29
29
|
|
30
30
|
import java.io.IOException;
|
31
31
|
import java.io.OutputStreamWriter;
|
32
|
+
import java.io.Writer;
|
32
33
|
import java.nio.charset.Charset;
|
33
34
|
import java.util.HashMap;
|
34
35
|
import java.util.Map;
|
35
36
|
|
36
37
|
import org.jcodings.Encoding;
|
38
|
+
import org.jcodings.specific.UTF8Encoding;
|
37
39
|
import org.jruby.Ruby;
|
38
40
|
import org.jruby.RubyArray;
|
41
|
+
import org.jruby.RubyBoolean;
|
39
42
|
import org.jruby.RubyClass;
|
40
43
|
import org.jruby.RubyFixnum;
|
41
44
|
import org.jruby.RubyModule;
|
@@ -46,6 +49,8 @@ import org.jruby.runtime.ObjectAllocator;
|
|
46
49
|
import org.jruby.runtime.ThreadContext;
|
47
50
|
import org.jruby.runtime.builtin.IRubyObject;
|
48
51
|
import org.jruby.util.IOOutputStream;
|
52
|
+
import org.jruby.util.TypeConverter;
|
53
|
+
import org.jruby.util.io.EncodingUtils;
|
49
54
|
import org.yaml.snakeyaml.DumperOptions;
|
50
55
|
import org.yaml.snakeyaml.emitter.Emitter;
|
51
56
|
import org.yaml.snakeyaml.emitter.EmitterException;
|
@@ -110,9 +115,7 @@ public class PsychEmitter extends RubyObject {
|
|
110
115
|
|
111
116
|
@JRubyMethod
|
112
117
|
public IRubyObject start_stream(ThreadContext context, IRubyObject encoding) {
|
113
|
-
|
114
|
-
throw context.runtime.newTypeError(encoding, context.runtime.getFixnum());
|
115
|
-
}
|
118
|
+
TypeConverter.checkType(context, encoding, context.runtime.getFixnum());
|
116
119
|
|
117
120
|
initEmitter(context, encoding);
|
118
121
|
|
@@ -136,6 +139,8 @@ public class PsychEmitter extends RubyObject {
|
|
136
139
|
boolean implicitBool = implicit.isTrue();
|
137
140
|
Map<String, String> tagsMap = null;
|
138
141
|
|
142
|
+
TypeConverter.checkType(context, _version, context.runtime.getArray());
|
143
|
+
|
139
144
|
RubyArray versionAry = _version.convertToArray();
|
140
145
|
if (versionAry.size() == 2) {
|
141
146
|
int versionInt0 = (int)versionAry.eltInternal(0).convertToInteger().getLongValue();
|
@@ -153,19 +158,23 @@ public class PsychEmitter extends RubyObject {
|
|
153
158
|
}
|
154
159
|
}
|
155
160
|
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
161
|
+
if (!tags.isNil()) {
|
162
|
+
TypeConverter.checkType(context, tags, context.runtime.getArray());
|
163
|
+
|
164
|
+
RubyArray tagsAry = tags.convertToArray();
|
165
|
+
if (tagsAry.size() > 0) {
|
166
|
+
tagsMap = new HashMap<>(tagsAry.size());
|
167
|
+
for (int i = 0; i < tagsAry.size(); i++) {
|
168
|
+
RubyArray tagsTuple = tagsAry.eltInternal(i).convertToArray();
|
169
|
+
if (tagsTuple.size() != 2) {
|
170
|
+
throw context.runtime.newRuntimeError("tags tuple must be of length 2");
|
171
|
+
}
|
172
|
+
IRubyObject key = tagsTuple.eltInternal(0);
|
173
|
+
IRubyObject value = tagsTuple.eltInternal(1);
|
174
|
+
tagsMap.put(
|
175
|
+
key.asJavaString(),
|
176
|
+
value.asJavaString());
|
163
177
|
}
|
164
|
-
IRubyObject key = tagsTuple.eltInternal(0);
|
165
|
-
IRubyObject value = tagsTuple.eltInternal(1);
|
166
|
-
tagsMap.put(
|
167
|
-
key.asJavaString(),
|
168
|
-
value.asJavaString());
|
169
178
|
}
|
170
179
|
}
|
171
180
|
|
@@ -189,21 +198,29 @@ public class PsychEmitter extends RubyObject {
|
|
189
198
|
IRubyObject plain = args[3];
|
190
199
|
IRubyObject quoted = args[4];
|
191
200
|
IRubyObject style = args[5];
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
201
|
+
|
202
|
+
RubyClass stringClass = context.runtime.getString();
|
203
|
+
|
204
|
+
TypeConverter.checkType(context, value, stringClass);
|
205
|
+
|
206
|
+
RubyString valueStr = (RubyString) value;
|
207
|
+
|
208
|
+
valueStr = EncodingUtils.strConvEnc(context, valueStr, valueStr.getEncoding(), UTF8Encoding.INSTANCE);
|
209
|
+
|
210
|
+
RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
|
211
|
+
RubyString tagStr = exportToUTF8(context, tag, stringClass);
|
196
212
|
|
197
213
|
ScalarEvent event = new ScalarEvent(
|
198
|
-
|
199
|
-
|
200
|
-
new ImplicitTuple(plain.isTrue(),
|
201
|
-
|
202
|
-
value.asJavaString(),
|
214
|
+
anchorStr == null ? null : anchorStr.asJavaString(),
|
215
|
+
tagStr == null ? null : tagStr.asJavaString(),
|
216
|
+
new ImplicitTuple(plain.isTrue(), quoted.isTrue()),
|
217
|
+
valueStr.asJavaString(),
|
203
218
|
NULL_MARK,
|
204
219
|
NULL_MARK,
|
205
220
|
SCALAR_STYLES[style.convertToInteger().getIntValue()]);
|
221
|
+
|
206
222
|
emit(context, event);
|
223
|
+
|
207
224
|
return this;
|
208
225
|
}
|
209
226
|
|
@@ -214,11 +231,14 @@ public class PsychEmitter extends RubyObject {
|
|
214
231
|
IRubyObject implicit = args[2];
|
215
232
|
IRubyObject style = args[3];
|
216
233
|
|
217
|
-
|
234
|
+
RubyClass stringClass = context.runtime.getString();
|
235
|
+
|
236
|
+
RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
|
237
|
+
RubyString tagStr = exportToUTF8(context, tag, stringClass);
|
218
238
|
|
219
239
|
SequenceStartEvent event = new SequenceStartEvent(
|
220
|
-
|
221
|
-
|
240
|
+
anchorStr == null ? null : anchorStr.asJavaString(),
|
241
|
+
tagStr == null ? null : tagStr.asJavaString(),
|
222
242
|
implicit.isTrue(),
|
223
243
|
NULL_MARK,
|
224
244
|
NULL_MARK,
|
@@ -241,16 +261,21 @@ public class PsychEmitter extends RubyObject {
|
|
241
261
|
IRubyObject implicit = args[2];
|
242
262
|
IRubyObject style = args[3];
|
243
263
|
|
244
|
-
|
264
|
+
RubyClass stringClass = context.runtime.getString();
|
265
|
+
|
266
|
+
RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
|
267
|
+
RubyString tagStr = exportToUTF8(context, tag, stringClass);
|
245
268
|
|
246
269
|
MappingStartEvent event = new MappingStartEvent(
|
247
|
-
|
248
|
-
|
270
|
+
anchorStr == null ? null : anchorStr.asJavaString(),
|
271
|
+
tagStr == null ? null : tagStr.asJavaString(),
|
249
272
|
implicit.isTrue(),
|
250
273
|
NULL_MARK,
|
251
274
|
NULL_MARK,
|
252
275
|
FLOW_STYLES[style.convertToInteger().getIntValue()]);
|
276
|
+
|
253
277
|
emit(context, event);
|
278
|
+
|
254
279
|
return this;
|
255
280
|
}
|
256
281
|
|
@@ -263,7 +288,11 @@ public class PsychEmitter extends RubyObject {
|
|
263
288
|
|
264
289
|
@JRubyMethod
|
265
290
|
public IRubyObject alias(ThreadContext context, IRubyObject anchor) {
|
266
|
-
|
291
|
+
RubyClass stringClass = context.runtime.getString();
|
292
|
+
|
293
|
+
RubyString anchorStr = exportToUTF8(context, anchor, stringClass);
|
294
|
+
|
295
|
+
AliasEvent event = new AliasEvent(anchorStr.asJavaString(), NULL_MARK, NULL_MARK);
|
267
296
|
emit(context, event);
|
268
297
|
return this;
|
269
298
|
}
|
@@ -278,7 +307,7 @@ public class PsychEmitter extends RubyObject {
|
|
278
307
|
@JRubyMethod
|
279
308
|
public IRubyObject canonical(ThreadContext context) {
|
280
309
|
// TODO: unclear if this affects a running emitter
|
281
|
-
return
|
310
|
+
return RubyBoolean.newBoolean(context, options.isCanonical());
|
282
311
|
}
|
283
312
|
|
284
313
|
@JRubyMethod(name = "indentation=")
|
@@ -312,6 +341,9 @@ public class PsychEmitter extends RubyObject {
|
|
312
341
|
if (emitter == null) throw context.runtime.newRuntimeError("uninitialized emitter");
|
313
342
|
|
314
343
|
emitter.emit(event);
|
344
|
+
|
345
|
+
// flush writer after each emit
|
346
|
+
writer.flush();
|
315
347
|
} catch (IOException ioe) {
|
316
348
|
throw context.runtime.newIOErrorFromException(ioe);
|
317
349
|
} catch (EmitterException ee) {
|
@@ -325,10 +357,22 @@ public class PsychEmitter extends RubyObject {
|
|
325
357
|
Encoding encoding = PsychLibrary.YAMLEncoding.values()[(int)_encoding.convertToInteger().getLongValue()].encoding;
|
326
358
|
Charset charset = context.runtime.getEncodingService().charsetForEncoding(encoding);
|
327
359
|
|
328
|
-
|
360
|
+
writer = new OutputStreamWriter(new IOOutputStream(io, encoding), charset);
|
361
|
+
emitter = new Emitter(writer, options);
|
362
|
+
}
|
363
|
+
|
364
|
+
private RubyString exportToUTF8(ThreadContext context, IRubyObject tag, RubyClass stringClass) {
|
365
|
+
RubyString tagStr = null;
|
366
|
+
if (!tag.isNil()) {
|
367
|
+
TypeConverter.checkType(context, tag, stringClass);
|
368
|
+
tagStr = (RubyString) tag;
|
369
|
+
tagStr = EncodingUtils.strConvEnc(context, tagStr, tagStr.getEncoding(), UTF8Encoding.INSTANCE);
|
370
|
+
}
|
371
|
+
return tagStr;
|
329
372
|
}
|
330
373
|
|
331
374
|
Emitter emitter;
|
375
|
+
Writer writer;
|
332
376
|
DumperOptions options = new DumperOptions();
|
333
377
|
IRubyObject io;
|
334
378
|
|
@@ -30,6 +30,9 @@ package org.jruby.ext.psych;
|
|
30
30
|
import java.io.ByteArrayInputStream;
|
31
31
|
import java.io.InputStreamReader;
|
32
32
|
import java.nio.charset.Charset;
|
33
|
+
import java.nio.charset.CharsetDecoder;
|
34
|
+
import java.nio.charset.CodingErrorAction;
|
35
|
+
import java.nio.charset.MalformedInputException;
|
33
36
|
import java.util.Map;
|
34
37
|
|
35
38
|
import org.jcodings.Encoding;
|
@@ -61,6 +64,7 @@ import org.jruby.util.log.LoggerFactory;
|
|
61
64
|
import org.yaml.snakeyaml.DumperOptions;
|
62
65
|
import org.yaml.snakeyaml.error.Mark;
|
63
66
|
import org.yaml.snakeyaml.error.MarkedYAMLException;
|
67
|
+
import org.yaml.snakeyaml.error.YAMLException;
|
64
68
|
import org.yaml.snakeyaml.events.AliasEvent;
|
65
69
|
import org.yaml.snakeyaml.events.DocumentEndEvent;
|
66
70
|
import org.yaml.snakeyaml.events.DocumentStartEvent;
|
@@ -75,6 +79,8 @@ import org.yaml.snakeyaml.parser.ParserImpl;
|
|
75
79
|
import org.yaml.snakeyaml.reader.ReaderException;
|
76
80
|
import org.yaml.snakeyaml.reader.StreamReader;
|
77
81
|
import org.yaml.snakeyaml.scanner.ScannerException;
|
82
|
+
|
83
|
+
import static org.jruby.runtime.Helpers.arrayOf;
|
78
84
|
import static org.jruby.runtime.Helpers.invoke;
|
79
85
|
import org.jruby.util.ByteList;
|
80
86
|
|
@@ -89,8 +95,7 @@ public class PsychParser extends RubyObject {
|
|
89
95
|
}
|
90
96
|
}, psych);
|
91
97
|
|
92
|
-
|
93
|
-
runtime.newString("psych/syntax_error"), Block.NULL_BLOCK);
|
98
|
+
runtime.getLoadService().require("psych/syntax_error");
|
94
99
|
psychParser.defineConstant("ANY", runtime.newFixnum(YAML_ANY_ENCODING.ordinal()));
|
95
100
|
psychParser.defineConstant("UTF8", runtime.newFixnum(YAML_UTF8_ENCODING.ordinal()));
|
96
101
|
psychParser.defineConstant("UTF16LE", runtime.newFixnum(YAML_UTF16LE_ENCODING.ordinal()));
|
@@ -110,13 +115,15 @@ public class PsychParser extends RubyObject {
|
|
110
115
|
return parse(context, yaml, runtime.getNil());
|
111
116
|
}
|
112
117
|
|
113
|
-
private IRubyObject stringOrNilFor(
|
114
|
-
if (value == null) return
|
118
|
+
private IRubyObject stringOrNilFor(ThreadContext context, String value, boolean tainted) {
|
119
|
+
if (value == null) return context.nil;
|
115
120
|
|
116
|
-
return stringFor(
|
121
|
+
return stringFor(context, value, tainted);
|
117
122
|
}
|
118
123
|
|
119
|
-
private RubyString stringFor(
|
124
|
+
private RubyString stringFor(ThreadContext context, String value, boolean tainted) {
|
125
|
+
Ruby runtime = context.runtime;
|
126
|
+
|
120
127
|
Encoding encoding = runtime.getDefaultInternalEncoding();
|
121
128
|
if (encoding == null) {
|
122
129
|
encoding = UTF8Encoding.INSTANCE;
|
@@ -136,8 +143,6 @@ public class PsychParser extends RubyObject {
|
|
136
143
|
}
|
137
144
|
|
138
145
|
private StreamReader readerFor(ThreadContext context, IRubyObject yaml) {
|
139
|
-
Ruby runtime = context.runtime;
|
140
|
-
|
141
146
|
if (yaml instanceof RubyString) {
|
142
147
|
ByteList byteList = ((RubyString)yaml).getByteList();
|
143
148
|
Encoding enc = byteList.getEncoding();
|
@@ -175,8 +180,14 @@ public class PsychParser extends RubyObject {
|
|
175
180
|
// If we can't get it from the IO or it doesn't have a charset, fall back on UTF-8
|
176
181
|
charset = UTF8Encoding.INSTANCE.getCharset();
|
177
182
|
}
|
178
|
-
|
183
|
+
CharsetDecoder decoder = charset.newDecoder();
|
184
|
+
decoder.onMalformedInput(CodingErrorAction.REPORT);
|
185
|
+
decoder.onMalformedInput(CodingErrorAction.REPORT);
|
186
|
+
|
187
|
+
return new StreamReader(new InputStreamReader(new IOInputStream(yaml), decoder));
|
179
188
|
} else {
|
189
|
+
Ruby runtime = context.runtime;
|
190
|
+
|
180
191
|
throw runtime.newTypeError(yaml, runtime.getIO());
|
181
192
|
}
|
182
193
|
}
|
@@ -214,7 +225,7 @@ public class PsychParser extends RubyObject {
|
|
214
225
|
|
215
226
|
invoke(context, handler, "end_document", notExplicit);
|
216
227
|
} else if (event.is(ID.Alias)) {
|
217
|
-
IRubyObject alias = stringOrNilFor(
|
228
|
+
IRubyObject alias = stringOrNilFor(context, ((AliasEvent)event).getAnchor(), tainted);
|
218
229
|
|
219
230
|
invoke(context, handler, "alias", alias);
|
220
231
|
} else if (event.is(ID.Scalar)) {
|
@@ -249,6 +260,16 @@ public class PsychParser extends RubyObject {
|
|
249
260
|
parser = null;
|
250
261
|
raiseParserException(context, yaml, re, path);
|
251
262
|
|
263
|
+
} catch (YAMLException ye) {
|
264
|
+
Throwable cause = ye.getCause();
|
265
|
+
|
266
|
+
if (cause instanceof MalformedInputException) {
|
267
|
+
// failure due to improperly encoded input
|
268
|
+
raiseParserException(context, yaml, (MalformedInputException) cause, path);
|
269
|
+
}
|
270
|
+
|
271
|
+
throw ye;
|
272
|
+
|
252
273
|
} catch (Throwable t) {
|
253
274
|
Helpers.throwException(t);
|
254
275
|
return this;
|
@@ -268,8 +289,8 @@ public class PsychParser extends RubyObject {
|
|
268
289
|
RubyArray tags = RubyArray.newArray(runtime);
|
269
290
|
if (tagsMap != null && tagsMap.size() > 0) {
|
270
291
|
for (Map.Entry<String, String> tag : tagsMap.entrySet()) {
|
271
|
-
IRubyObject key = stringFor(
|
272
|
-
IRubyObject value = stringFor(
|
292
|
+
IRubyObject key = stringFor(context, tag.getKey(), tainted);
|
293
|
+
IRubyObject value = stringFor(context, tag.getValue(), tainted);
|
273
294
|
|
274
295
|
tags.append(RubyArray.newArray(runtime, key, value));
|
275
296
|
}
|
@@ -281,8 +302,8 @@ public class PsychParser extends RubyObject {
|
|
281
302
|
|
282
303
|
private void handleMappingStart(ThreadContext context, MappingStartEvent mse, boolean tainted, IRubyObject handler) {
|
283
304
|
Ruby runtime = context.runtime;
|
284
|
-
IRubyObject anchor = stringOrNilFor(
|
285
|
-
IRubyObject tag = stringOrNilFor(
|
305
|
+
IRubyObject anchor = stringOrNilFor(context, mse.getAnchor(), tainted);
|
306
|
+
IRubyObject tag = stringOrNilFor(context, mse.getTag(), tainted);
|
286
307
|
IRubyObject implicit = runtime.newBoolean(mse.getImplicit());
|
287
308
|
IRubyObject style = runtime.newFixnum(translateFlowStyle(mse.getFlowStyle()));
|
288
309
|
|
@@ -292,12 +313,12 @@ public class PsychParser extends RubyObject {
|
|
292
313
|
private void handleScalar(ThreadContext context, ScalarEvent se, boolean tainted, IRubyObject handler) {
|
293
314
|
Ruby runtime = context.runtime;
|
294
315
|
|
295
|
-
IRubyObject anchor = stringOrNilFor(
|
296
|
-
IRubyObject tag = stringOrNilFor(
|
316
|
+
IRubyObject anchor = stringOrNilFor(context, se.getAnchor(), tainted);
|
317
|
+
IRubyObject tag = stringOrNilFor(context, se.getTag(), tainted);
|
297
318
|
IRubyObject plain_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInPlainScalar());
|
298
319
|
IRubyObject quoted_implicit = runtime.newBoolean(se.getImplicit().canOmitTagInNonPlainScalar());
|
299
320
|
IRubyObject style = runtime.newFixnum(translateStyle(se.getScalarStyle()));
|
300
|
-
IRubyObject val = stringFor(
|
321
|
+
IRubyObject val = stringFor(context, se.getValue(), tainted);
|
301
322
|
|
302
323
|
invoke(context, handler, "scalar", val, anchor, tag, plain_implicit,
|
303
324
|
quoted_implicit, style);
|
@@ -305,8 +326,8 @@ public class PsychParser extends RubyObject {
|
|
305
326
|
|
306
327
|
private void handleSequenceStart(ThreadContext context, SequenceStartEvent sse, boolean tainted, IRubyObject handler) {
|
307
328
|
Ruby runtime = context.runtime;
|
308
|
-
IRubyObject anchor = stringOrNilFor(
|
309
|
-
IRubyObject tag = stringOrNilFor(
|
329
|
+
IRubyObject anchor = stringOrNilFor(context, sse.getAnchor(), tainted);
|
330
|
+
IRubyObject tag = stringOrNilFor(context, sse.getTag(), tainted);
|
310
331
|
IRubyObject implicit = runtime.newBoolean(sse.getImplicit());
|
311
332
|
IRubyObject style = runtime.newFixnum(translateFlowStyle(sse.getFlowStyle()));
|
312
333
|
|
@@ -360,6 +381,31 @@ public class PsychParser extends RubyObject {
|
|
360
381
|
RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
|
361
382
|
}
|
362
383
|
|
384
|
+
private static void raiseParserException(ThreadContext context, IRubyObject yaml, MalformedInputException mie, IRubyObject rbPath) {
|
385
|
+
Ruby runtime;
|
386
|
+
Mark mark;
|
387
|
+
RubyClass se;
|
388
|
+
IRubyObject exception;
|
389
|
+
|
390
|
+
runtime = context.runtime;
|
391
|
+
se = (RubyClass)runtime.getModule("Psych").getConstant("SyntaxError");
|
392
|
+
|
393
|
+
mie.getInputLength();
|
394
|
+
|
395
|
+
exception = se.newInstance(context,
|
396
|
+
arrayOf(
|
397
|
+
rbPath,
|
398
|
+
runtime.newFixnum(-1),
|
399
|
+
runtime.newFixnum(-1),
|
400
|
+
runtime.newFixnum(mie.getInputLength()),
|
401
|
+
runtime.getNil(),
|
402
|
+
runtime.getNil()
|
403
|
+
),
|
404
|
+
Block.NULL_BLOCK);
|
405
|
+
|
406
|
+
RubyKernel.raise(context, runtime.getKernel(), new IRubyObject[] { exception }, Block.NULL_BLOCK);
|
407
|
+
}
|
408
|
+
|
363
409
|
private static int translateStyle(DumperOptions.ScalarStyle style) {
|
364
410
|
if (style == null) return 0; // any
|
365
411
|
|
data/ext/psych/yaml/loader.c
CHANGED
data/ext/psych/yaml/scanner.c
CHANGED
@@ -273,7 +273,7 @@
|
|
273
273
|
* The tokens BLOCK-SEQUENCE-START and BLOCK-MAPPING-START denote indentation
|
274
274
|
* increase that precedes a block collection (cf. the INDENT token in Python).
|
275
275
|
* The token BLOCK-END denote indentation decrease that ends a block collection
|
276
|
-
* (cf. the DEDENT token in Python). However YAML has some syntax
|
276
|
+
* (cf. the DEDENT token in Python). However YAML has some syntax peculiarities
|
277
277
|
* that makes detections of these tokens more complex.
|
278
278
|
*
|
279
279
|
* The tokens BLOCK-ENTRY, KEY, and VALUE are used to represent the indicators
|
@@ -3287,7 +3287,7 @@ yaml_parser_scan_flow_scalar(yaml_parser_t *parser, yaml_token_t *token,
|
|
3287
3287
|
|
3288
3288
|
/* Check if we are at the end of the scalar. */
|
3289
3289
|
|
3290
|
-
/* Fix for crash
|
3290
|
+
/* Fix for crash uninitialized value crash
|
3291
3291
|
* Credit for the bug and input is to OSS Fuzz
|
3292
3292
|
* Credit for the fix to Alex Gaynor
|
3293
3293
|
*/
|
data/ext/psych/yaml/yaml.h
CHANGED
@@ -1095,7 +1095,7 @@ typedef struct yaml_parser_s {
|
|
1095
1095
|
yaml_error_type_t error;
|
1096
1096
|
/** Error description. */
|
1097
1097
|
const char *problem;
|
1098
|
-
/** The byte about which the problem
|
1098
|
+
/** The byte about which the problem occurred. */
|
1099
1099
|
size_t problem_offset;
|
1100
1100
|
/** The problematic value (@c -1 is none). */
|
1101
1101
|
int problem_value;
|
@@ -1335,7 +1335,7 @@ yaml_parser_delete(yaml_parser_t *parser);
|
|
1335
1335
|
* Set a string input.
|
1336
1336
|
*
|
1337
1337
|
* Note that the @a input pointer must be valid while the @a parser object
|
1338
|
-
* exists. The application is responsible for
|
1338
|
+
* exists. The application is responsible for destroying @a input after
|
1339
1339
|
* destroying the @a parser.
|
1340
1340
|
*
|
1341
1341
|
* @param[in,out] parser A parser object.
|
@@ -1950,7 +1950,7 @@ yaml_emitter_close(yaml_emitter_t *emitter);
|
|
1950
1950
|
/**
|
1951
1951
|
* Emit a YAML document.
|
1952
1952
|
*
|
1953
|
-
* The
|
1953
|
+
* The document object may be generated using the yaml_parser_load() function
|
1954
1954
|
* or the yaml_document_initialize() function. The emitter takes the
|
1955
1955
|
* responsibility for the document object and destroys its content after
|
1956
1956
|
* it is emitted. The document object is destroyed even if the function fails.
|
data/lib/psych/class_loader.rb
CHANGED
@@ -86,7 +86,7 @@ module Psych
|
|
86
86
|
if @symbols.include? sym
|
87
87
|
super
|
88
88
|
else
|
89
|
-
raise DisallowedClass, 'Symbol'
|
89
|
+
raise DisallowedClass.new('load', 'Symbol')
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
@@ -96,7 +96,7 @@ module Psych
|
|
96
96
|
if @classes.include? klassname
|
97
97
|
super
|
98
98
|
else
|
99
|
-
raise DisallowedClass, klassname
|
99
|
+
raise DisallowedClass.new('load', klassname)
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
data/lib/psych/exception.rb
CHANGED
@@ -7,8 +7,8 @@ module Psych
|
|
7
7
|
end
|
8
8
|
|
9
9
|
class DisallowedClass < Exception
|
10
|
-
def initialize klass_name
|
11
|
-
super "Tried to
|
10
|
+
def initialize action, klass_name
|
11
|
+
super "Tried to #{action} unspecified class: #{klass_name}"
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
data/lib/psych/handler.rb
CHANGED
@@ -119,7 +119,7 @@ module Psych
|
|
119
119
|
# +tag+ is an associated tag or nil
|
120
120
|
# +plain+ is a boolean value
|
121
121
|
# +quoted+ is a boolean value
|
122
|
-
# +style+ is an integer
|
122
|
+
# +style+ is an integer indicating the string style
|
123
123
|
#
|
124
124
|
# See the constants in Psych::Nodes::Scalar for the possible values of
|
125
125
|
# +style+
|
data/lib/psych/nodes/scalar.rb
CHANGED
data/lib/psych/scalar_scanner.rb
CHANGED
@@ -9,15 +9,14 @@ module Psych
|
|
9
9
|
TIME = /^-?\d{4}-\d{1,2}-\d{1,2}(?:[Tt]|\s+)\d{1,2}:\d\d:\d\d(?:\.\d*)?(?:\s*(?:Z|[-+]\d{1,2}:?(?:\d\d)?))?$/
|
10
10
|
|
11
11
|
# Taken from http://yaml.org/type/float.html
|
12
|
-
|
13
|
-
|
14
|
-
|\.(nan|NaN|NAN)(?# not a number))$/x
|
12
|
+
# Base 60, [-+]inf and NaN are handled separately
|
13
|
+
FLOAT = /^(?:[-+]?([0-9][0-9_,]*)?\.[0-9]*([eE][-+][0-9]+)?(?# base 10))$/x
|
15
14
|
|
16
15
|
# Taken from http://yaml.org/type/int.html
|
17
|
-
INTEGER = /^(?:[-+]?0b[0-1_,]+
|
18
|
-
|[-+]?0[0-7_,]+
|
19
|
-
|[-+]?(?:0|[1-9][0-
|
20
|
-
|[-+]?0x[0-9a-fA-F_,]+
|
16
|
+
INTEGER = /^(?:[-+]?0b[0-1_,]+ (?# base 2)
|
17
|
+
|[-+]?0[0-7_,]+ (?# base 8)
|
18
|
+
|[-+]?(?:0|[1-9](?:[0-9]|,[0-9]|_[0-9])*) (?# base 10)
|
19
|
+
|[-+]?0x[0-9a-fA-F_,]+ (?# base 16))$/x
|
21
20
|
|
22
21
|
attr_reader :class_loader
|
23
22
|
|
@@ -34,7 +33,7 @@ module Psych
|
|
34
33
|
|
35
34
|
# Check for a String type, being careful not to get caught by hash keys, hex values, and
|
36
35
|
# special floats (e.g., -.inf).
|
37
|
-
if string.match?(
|
36
|
+
if string.match?(%r{^[^\d.:-]?[[:alpha:]_\s!@#$%\^&*(){}<>|/\\~;=]+}) || string.match?(/\n/)
|
38
37
|
return string if string.length > 5
|
39
38
|
|
40
39
|
if string.match?(/^[^ytonf~]/i)
|
@@ -61,7 +60,7 @@ module Psych
|
|
61
60
|
rescue ArgumentError
|
62
61
|
string
|
63
62
|
end
|
64
|
-
elsif string.match?(
|
63
|
+
elsif string.match?(/^\+?\.inf$/i)
|
65
64
|
Float::INFINITY
|
66
65
|
elsif string.match?(/^-\.inf$/i)
|
67
66
|
-Float::INFINITY
|
data/lib/psych/versions.rb
CHANGED
@@ -272,6 +272,8 @@ module Psych
|
|
272
272
|
tag = 'tag:yaml.org,2002:str'
|
273
273
|
plain = false
|
274
274
|
quote = false
|
275
|
+
elsif o == 'y' || o == 'n'
|
276
|
+
style = Nodes::Scalar::DOUBLE_QUOTED
|
275
277
|
elsif @line_width && o.length > @line_width
|
276
278
|
style = Nodes::Scalar::FOLDED
|
277
279
|
elsif o =~ /^[^[:word:]][^"]*$/
|
@@ -509,9 +511,9 @@ module Psych
|
|
509
511
|
def emit_coder c, o
|
510
512
|
case c.type
|
511
513
|
when :scalar
|
512
|
-
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false,
|
514
|
+
@emitter.scalar c.scalar, nil, c.tag, c.tag.nil?, false, c.style
|
513
515
|
when :seq
|
514
|
-
@emitter.start_sequence nil, c.tag, c.tag.nil?,
|
516
|
+
@emitter.start_sequence nil, c.tag, c.tag.nil?, c.style
|
515
517
|
c.seq.each do |thing|
|
516
518
|
accept thing
|
517
519
|
end
|
@@ -535,5 +537,51 @@ module Psych
|
|
535
537
|
end
|
536
538
|
end
|
537
539
|
end
|
540
|
+
|
541
|
+
class RestrictedYAMLTree < YAMLTree
|
542
|
+
DEFAULT_PERMITTED_CLASSES = {
|
543
|
+
TrueClass => true,
|
544
|
+
FalseClass => true,
|
545
|
+
NilClass => true,
|
546
|
+
Integer => true,
|
547
|
+
Float => true,
|
548
|
+
String => true,
|
549
|
+
Array => true,
|
550
|
+
Hash => true,
|
551
|
+
}.compare_by_identity.freeze
|
552
|
+
|
553
|
+
def initialize emitter, ss, options
|
554
|
+
super
|
555
|
+
@permitted_classes = DEFAULT_PERMITTED_CLASSES.dup
|
556
|
+
Array(options[:permitted_classes]).each do |klass|
|
557
|
+
@permitted_classes[klass] = true
|
558
|
+
end
|
559
|
+
@permitted_symbols = {}.compare_by_identity
|
560
|
+
Array(options[:permitted_symbols]).each do |symbol|
|
561
|
+
@permitted_symbols[symbol] = true
|
562
|
+
end
|
563
|
+
@aliases = options.fetch(:aliases, false)
|
564
|
+
end
|
565
|
+
|
566
|
+
def accept target
|
567
|
+
if !@aliases && @st.key?(target)
|
568
|
+
raise BadAlias, "Tried to dump an aliased object"
|
569
|
+
end
|
570
|
+
|
571
|
+
unless @permitted_classes[target.class]
|
572
|
+
raise DisallowedClass.new('dump', target.class.name || target.class.inspect)
|
573
|
+
end
|
574
|
+
|
575
|
+
super
|
576
|
+
end
|
577
|
+
|
578
|
+
def visit_Symbol sym
|
579
|
+
unless @permitted_symbols[sym]
|
580
|
+
raise DisallowedClass.new('dump', "Symbol(#{sym.inspect})")
|
581
|
+
end
|
582
|
+
|
583
|
+
super
|
584
|
+
end
|
585
|
+
end
|
538
586
|
end
|
539
587
|
end
|
data/lib/psych.jar
CHANGED
Binary file
|
data/lib/psych.rb
CHANGED
@@ -33,7 +33,7 @@ require 'psych/class_loader'
|
|
33
33
|
#
|
34
34
|
# Psych is a YAML parser and emitter.
|
35
35
|
# Psych leverages libyaml [Home page: https://pyyaml.org/wiki/LibYAML]
|
36
|
-
# or [
|
36
|
+
# or [git repo: https://github.com/yaml/libyaml] for its YAML parsing
|
37
37
|
# and emitting capabilities. In addition to wrapping libyaml, Psych also
|
38
38
|
# knows how to serialize and de-serialize most Ruby objects to and from
|
39
39
|
# the YAML format.
|
@@ -234,9 +234,6 @@ require 'psych/class_loader'
|
|
234
234
|
module Psych
|
235
235
|
# The version of libyaml Psych is using
|
236
236
|
LIBYAML_VERSION = Psych.libyaml_version.join('.').freeze
|
237
|
-
# Deprecation guard
|
238
|
-
NOT_GIVEN = Object.new.freeze
|
239
|
-
private_constant :NOT_GIVEN
|
240
237
|
|
241
238
|
###
|
242
239
|
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
@@ -249,11 +246,11 @@ module Psych
|
|
249
246
|
#
|
250
247
|
# Example:
|
251
248
|
#
|
252
|
-
# Psych.
|
253
|
-
# Psych.
|
249
|
+
# Psych.unsafe_load("--- a") # => 'a'
|
250
|
+
# Psych.unsafe_load("---\n - a\n - b") # => ['a', 'b']
|
254
251
|
#
|
255
252
|
# begin
|
256
|
-
# Psych.
|
253
|
+
# Psych.unsafe_load("--- `", filename: "file.txt")
|
257
254
|
# rescue Psych::SyntaxError => ex
|
258
255
|
# ex.file # => 'file.txt'
|
259
256
|
# ex.message # => "(file.txt): found character that cannot start any token"
|
@@ -262,25 +259,21 @@ module Psych
|
|
262
259
|
# When the optional +symbolize_names+ keyword argument is set to a
|
263
260
|
# true value, returns symbols for keys in Hash objects (default: strings).
|
264
261
|
#
|
265
|
-
# Psych.
|
266
|
-
# Psych.
|
262
|
+
# Psych.unsafe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
263
|
+
# Psych.unsafe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
267
264
|
#
|
268
265
|
# Raises a TypeError when `yaml` parameter is NilClass
|
269
266
|
#
|
270
267
|
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
271
268
|
# YAML documents that are supplied via user input. Instead, please use the
|
272
|
-
# safe_load method.
|
269
|
+
# load method or the safe_load method.
|
273
270
|
#
|
274
|
-
def self.
|
275
|
-
if legacy_filename != NOT_GIVEN
|
276
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load is deprecated. Use keyword argument like Psych.load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
277
|
-
filename = legacy_filename
|
278
|
-
end
|
279
|
-
|
271
|
+
def self.unsafe_load yaml, filename: nil, fallback: false, symbolize_names: false, freeze: false
|
280
272
|
result = parse(yaml, filename: filename)
|
281
273
|
return fallback unless result
|
282
274
|
result.to_ruby(symbolize_names: symbolize_names, freeze: freeze)
|
283
275
|
end
|
276
|
+
class << self; alias :load :unsafe_load; end
|
284
277
|
|
285
278
|
###
|
286
279
|
# Safely load the yaml string in +yaml+. By default, only the following
|
@@ -289,7 +282,8 @@ module Psych
|
|
289
282
|
# * TrueClass
|
290
283
|
# * FalseClass
|
291
284
|
# * NilClass
|
292
|
-
# *
|
285
|
+
# * Integer
|
286
|
+
# * Float
|
293
287
|
# * String
|
294
288
|
# * Array
|
295
289
|
# * Hash
|
@@ -326,27 +320,7 @@ module Psych
|
|
326
320
|
# Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
327
321
|
# Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
328
322
|
#
|
329
|
-
def self.safe_load yaml,
|
330
|
-
if legacy_permitted_classes != NOT_GIVEN
|
331
|
-
warn_with_uplevel 'Passing permitted_classes with the 2nd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_classes: ...) instead.', uplevel: 1 if $VERBOSE
|
332
|
-
permitted_classes = legacy_permitted_classes
|
333
|
-
end
|
334
|
-
|
335
|
-
if legacy_permitted_symbols != NOT_GIVEN
|
336
|
-
warn_with_uplevel 'Passing permitted_symbols with the 3rd argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, permitted_symbols: ...) instead.', uplevel: 1 if $VERBOSE
|
337
|
-
permitted_symbols = legacy_permitted_symbols
|
338
|
-
end
|
339
|
-
|
340
|
-
if legacy_aliases != NOT_GIVEN
|
341
|
-
warn_with_uplevel 'Passing aliases with the 4th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, aliases: ...) instead.', uplevel: 1 if $VERBOSE
|
342
|
-
aliases = legacy_aliases
|
343
|
-
end
|
344
|
-
|
345
|
-
if legacy_filename != NOT_GIVEN
|
346
|
-
warn_with_uplevel 'Passing filename with the 5th argument of Psych.safe_load is deprecated. Use keyword argument like Psych.safe_load(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
347
|
-
filename = legacy_filename
|
348
|
-
end
|
349
|
-
|
323
|
+
def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false
|
350
324
|
result = parse(yaml, filename: filename)
|
351
325
|
return fallback unless result
|
352
326
|
|
@@ -362,6 +336,46 @@ module Psych
|
|
362
336
|
result
|
363
337
|
end
|
364
338
|
|
339
|
+
###
|
340
|
+
# Load +yaml+ in to a Ruby data structure. If multiple documents are
|
341
|
+
# provided, the object contained in the first document will be returned.
|
342
|
+
# +filename+ will be used in the exception message if any exception
|
343
|
+
# is raised while parsing. If +yaml+ is empty, it returns
|
344
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
345
|
+
#
|
346
|
+
# Raises a Psych::SyntaxError when a YAML syntax error is detected.
|
347
|
+
#
|
348
|
+
# Example:
|
349
|
+
#
|
350
|
+
# Psych.load("--- a") # => 'a'
|
351
|
+
# Psych.load("---\n - a\n - b") # => ['a', 'b']
|
352
|
+
#
|
353
|
+
# begin
|
354
|
+
# Psych.load("--- `", filename: "file.txt")
|
355
|
+
# rescue Psych::SyntaxError => ex
|
356
|
+
# ex.file # => 'file.txt'
|
357
|
+
# ex.message # => "(file.txt): found character that cannot start any token"
|
358
|
+
# end
|
359
|
+
#
|
360
|
+
# When the optional +symbolize_names+ keyword argument is set to a
|
361
|
+
# true value, returns symbols for keys in Hash objects (default: strings).
|
362
|
+
#
|
363
|
+
# Psych.load("---\n foo: bar") # => {"foo"=>"bar"}
|
364
|
+
# Psych.load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
365
|
+
#
|
366
|
+
# Raises a TypeError when `yaml` parameter is NilClass. This method is
|
367
|
+
# similar to `safe_load` except that `Symbol` objects are allowed by default.
|
368
|
+
#
|
369
|
+
def self.load yaml, permitted_classes: [Symbol], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false
|
370
|
+
safe_load yaml, permitted_classes: permitted_classes,
|
371
|
+
permitted_symbols: permitted_symbols,
|
372
|
+
aliases: aliases,
|
373
|
+
filename: filename,
|
374
|
+
fallback: fallback,
|
375
|
+
symbolize_names: symbolize_names,
|
376
|
+
freeze: freeze
|
377
|
+
end
|
378
|
+
|
365
379
|
###
|
366
380
|
# Parse a YAML string in +yaml+. Returns the Psych::Nodes::Document.
|
367
381
|
# +filename+ is used in the exception message if a Psych::SyntaxError is
|
@@ -381,22 +395,12 @@ module Psych
|
|
381
395
|
# end
|
382
396
|
#
|
383
397
|
# See Psych::Nodes for more information about YAML AST.
|
384
|
-
def self.parse yaml,
|
385
|
-
if legacy_filename != NOT_GIVEN
|
386
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse is deprecated. Use keyword argument like Psych.parse(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
387
|
-
filename = legacy_filename
|
388
|
-
end
|
389
|
-
|
398
|
+
def self.parse yaml, filename: nil
|
390
399
|
parse_stream(yaml, filename: filename) do |node|
|
391
400
|
return node
|
392
401
|
end
|
393
402
|
|
394
|
-
|
395
|
-
warn_with_uplevel 'Passing the `fallback` keyword argument of Psych.parse is deprecated.', uplevel: 1 if $VERBOSE
|
396
|
-
fallback
|
397
|
-
else
|
398
|
-
false
|
399
|
-
end
|
403
|
+
false
|
400
404
|
end
|
401
405
|
|
402
406
|
###
|
@@ -445,12 +449,7 @@ module Psych
|
|
445
449
|
# Raises a TypeError when NilClass is passed.
|
446
450
|
#
|
447
451
|
# See Psych::Nodes for more information about YAML AST.
|
448
|
-
def self.parse_stream yaml,
|
449
|
-
if legacy_filename != NOT_GIVEN
|
450
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.parse_stream is deprecated. Use keyword argument like Psych.parse_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
451
|
-
filename = legacy_filename
|
452
|
-
end
|
453
|
-
|
452
|
+
def self.parse_stream yaml, filename: nil, &block
|
454
453
|
if block_given?
|
455
454
|
parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
|
456
455
|
parser.parse yaml, filename
|
@@ -514,6 +513,79 @@ module Psych
|
|
514
513
|
visitor.tree.yaml io, options
|
515
514
|
end
|
516
515
|
|
516
|
+
###
|
517
|
+
# call-seq:
|
518
|
+
# Psych.safe_dump(o) -> string of yaml
|
519
|
+
# Psych.safe_dump(o, options) -> string of yaml
|
520
|
+
# Psych.safe_dump(o, io) -> io object passed in
|
521
|
+
# Psych.safe_dump(o, io, options) -> io object passed in
|
522
|
+
#
|
523
|
+
# Safely dump Ruby object +o+ to a YAML string. Optional +options+ may be passed in
|
524
|
+
# to control the output format. If an IO object is passed in, the YAML will
|
525
|
+
# be dumped to that IO object. By default, only the following
|
526
|
+
# classes are allowed to be serialized:
|
527
|
+
#
|
528
|
+
# * TrueClass
|
529
|
+
# * FalseClass
|
530
|
+
# * NilClass
|
531
|
+
# * Integer
|
532
|
+
# * Float
|
533
|
+
# * String
|
534
|
+
# * Array
|
535
|
+
# * Hash
|
536
|
+
#
|
537
|
+
# Arbitrary classes can be allowed by adding those classes to the +permitted_classes+
|
538
|
+
# keyword argument. They are additive. For example, to allow Date serialization:
|
539
|
+
#
|
540
|
+
# Psych.safe_dump(yaml, permitted_classes: [Date])
|
541
|
+
#
|
542
|
+
# Now the Date class can be dumped in addition to the classes listed above.
|
543
|
+
#
|
544
|
+
# A Psych::DisallowedClass exception will be raised if the object contains a
|
545
|
+
# class that isn't in the +permitted_classes+ list.
|
546
|
+
#
|
547
|
+
# Currently supported options are:
|
548
|
+
#
|
549
|
+
# [<tt>:indentation</tt>] Number of space characters used to indent.
|
550
|
+
# Acceptable value should be in <tt>0..9</tt> range,
|
551
|
+
# otherwise option is ignored.
|
552
|
+
#
|
553
|
+
# Default: <tt>2</tt>.
|
554
|
+
# [<tt>:line_width</tt>] Max character to wrap line at.
|
555
|
+
#
|
556
|
+
# Default: <tt>0</tt> (meaning "wrap at 81").
|
557
|
+
# [<tt>:canonical</tt>] Write "canonical" YAML form (very verbose, yet
|
558
|
+
# strictly formal).
|
559
|
+
#
|
560
|
+
# Default: <tt>false</tt>.
|
561
|
+
# [<tt>:header</tt>] Write <tt>%YAML [version]</tt> at the beginning of document.
|
562
|
+
#
|
563
|
+
# Default: <tt>false</tt>.
|
564
|
+
#
|
565
|
+
# Example:
|
566
|
+
#
|
567
|
+
# # Dump an array, get back a YAML string
|
568
|
+
# Psych.safe_dump(['a', 'b']) # => "---\n- a\n- b\n"
|
569
|
+
#
|
570
|
+
# # Dump an array to an IO object
|
571
|
+
# Psych.safe_dump(['a', 'b'], StringIO.new) # => #<StringIO:0x000001009d0890>
|
572
|
+
#
|
573
|
+
# # Dump an array with indentation set
|
574
|
+
# Psych.safe_dump(['a', ['b']], indentation: 3) # => "---\n- a\n- - b\n"
|
575
|
+
#
|
576
|
+
# # Dump an array to an IO with indentation set
|
577
|
+
# Psych.safe_dump(['a', ['b']], StringIO.new, indentation: 3)
|
578
|
+
def self.safe_dump o, io = nil, options = {}
|
579
|
+
if Hash === io
|
580
|
+
options = io
|
581
|
+
io = nil
|
582
|
+
end
|
583
|
+
|
584
|
+
visitor = Psych::Visitors::RestrictedYAMLTree.create options
|
585
|
+
visitor << o
|
586
|
+
visitor.tree.yaml io, options
|
587
|
+
end
|
588
|
+
|
517
589
|
###
|
518
590
|
# Dump a list of objects as separate documents to a document stream.
|
519
591
|
#
|
@@ -551,12 +623,7 @@ module Psych
|
|
551
623
|
# end
|
552
624
|
# list # => ['foo', 'bar']
|
553
625
|
#
|
554
|
-
def self.load_stream yaml,
|
555
|
-
if legacy_filename != NOT_GIVEN
|
556
|
-
warn_with_uplevel 'Passing filename with the 2nd argument of Psych.load_stream is deprecated. Use keyword argument like Psych.load_stream(yaml, filename: ...) instead.', uplevel: 1 if $VERBOSE
|
557
|
-
filename = legacy_filename
|
558
|
-
end
|
559
|
-
|
626
|
+
def self.load_stream yaml, filename: nil, fallback: [], **kwargs
|
560
627
|
result = if block_given?
|
561
628
|
parse_stream(yaml, filename: filename) do |node|
|
562
629
|
yield node.to_ruby(**kwargs)
|
@@ -577,9 +644,9 @@ module Psych
|
|
577
644
|
# NOTE: This method *should not* be used to parse untrusted documents, such as
|
578
645
|
# YAML documents that are supplied via user input. Instead, please use the
|
579
646
|
# safe_load_file method.
|
580
|
-
def self.
|
647
|
+
def self.unsafe_load_file filename, **kwargs
|
581
648
|
File.open(filename, 'r:bom|utf-8') { |f|
|
582
|
-
self.
|
649
|
+
self.unsafe_load f, filename: filename, **kwargs
|
583
650
|
}
|
584
651
|
end
|
585
652
|
|
@@ -594,6 +661,17 @@ module Psych
|
|
594
661
|
}
|
595
662
|
end
|
596
663
|
|
664
|
+
###
|
665
|
+
# Loads the document contained in +filename+. Returns the yaml contained in
|
666
|
+
# +filename+ as a Ruby object, or if the file is empty, it returns
|
667
|
+
# the specified +fallback+ return value, which defaults to +false+.
|
668
|
+
# See load for options.
|
669
|
+
def self.load_file filename, **kwargs
|
670
|
+
File.open(filename, 'r:bom|utf-8') { |f|
|
671
|
+
self.load f, filename: filename, **kwargs
|
672
|
+
}
|
673
|
+
end
|
674
|
+
|
597
675
|
# :stopdoc:
|
598
676
|
def self.add_domain_type domain, type_tag, &block
|
599
677
|
key = ['tag', domain, type_tag].join ':'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: psych
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.2
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Aaron Patterson
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-10-21 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -19,8 +19,8 @@ dependencies:
|
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 0.1.7
|
21
21
|
name: jar-dependencies
|
22
|
-
type: :runtime
|
23
22
|
prerelease: false
|
23
|
+
type: :runtime
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
@@ -138,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
138
138
|
version: '0'
|
139
139
|
requirements:
|
140
140
|
- jar org.yaml:snakeyaml, 1.28
|
141
|
-
rubygems_version: 3.
|
141
|
+
rubygems_version: 3.2.29
|
142
142
|
signing_key:
|
143
143
|
specification_version: 4
|
144
144
|
summary: Psych is a YAML parser and emitter
|