psych 3.3.2-java → 4.0.3-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/Rakefile +1 -1
- data/ext/java/org/jruby/ext/psych/PsychEmitter.java +77 -33
- data/ext/java/org/jruby/ext/psych/PsychParser.java +65 -19
- data/lib/psych/class_loader.rb +4 -4
- data/lib/psych/core_ext.rb +1 -1
- data/lib/psych/exception.rb +2 -2
- data/lib/psych/handlers/document_stream.rb +1 -1
- data/lib/psych/handlers/recorder.rb +1 -1
- data/lib/psych/json/stream.rb +2 -2
- data/lib/psych/json/tree_builder.rb +1 -1
- data/lib/psych/nodes/node.rb +2 -2
- data/lib/psych/nodes.rb +7 -7
- data/lib/psych/scalar_scanner.rb +8 -9
- data/lib/psych/syntax_error.rb +1 -1
- data/lib/psych/tree_builder.rb +1 -1
- data/lib/psych/versions.rb +1 -1
- data/lib/psych/visitors/json_tree.rb +1 -1
- data/lib/psych/visitors/to_ruby.rb +3 -3
- data/lib/psych/visitors/yaml_tree.rb +51 -3
- data/lib/psych/visitors.rb +6 -6
- data/lib/psych.jar +0 -0
- data/lib/psych.rb +156 -80
- data/psych.gemspec +2 -0
- 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: 54430f72d4e60d345913cc82f31d7e4a6281996cb69213fd3ca26c3da5ee26c4
|
4
|
+
data.tar.gz: 02a5c1a3bd34089470506b97df067d4360f228c7d297610a41fc1109fa6f583e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0ca2e2c4fa3dd2aa52d00519116dca3ad5d8a99bb1d20724c741409e2e362b64e0e23ccada1b8b11e60b93e3fef90dfa2e3f285d2d5e2dfe7ff73138761aeaf6
|
7
|
+
data.tar.gz: a06a46f5c8d486194609c742b2fd105f9e1129db3665aa3eb73ffc88b259720b188c2b7fa7e9923461e20c9fcc662f2bbe462ab6a6021ca7f22920d597deca67
|
data/Rakefile
CHANGED
@@ -33,7 +33,7 @@ end
|
|
33
33
|
|
34
34
|
task :sync_tool do
|
35
35
|
require 'fileutils'
|
36
|
-
FileUtils.cp "../ruby/tool/lib/
|
36
|
+
FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
|
37
37
|
FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
|
38
38
|
FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
|
39
39
|
end
|
@@ -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/lib/psych/class_loader.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
2
|
+
require_relative 'omap'
|
3
|
+
require_relative 'set'
|
4
4
|
|
5
5
|
module Psych
|
6
6
|
class ClassLoader # :nodoc:
|
@@ -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/core_ext.rb
CHANGED
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/json/stream.rb
CHANGED
data/lib/psych/nodes/node.rb
CHANGED
data/lib/psych/nodes.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
2
|
+
require_relative 'nodes/node'
|
3
|
+
require_relative 'nodes/stream'
|
4
|
+
require_relative 'nodes/document'
|
5
|
+
require_relative 'nodes/sequence'
|
6
|
+
require_relative 'nodes/scalar'
|
7
|
+
require_relative 'nodes/mapping'
|
8
|
+
require_relative 'nodes/alias'
|
9
9
|
|
10
10
|
module Psych
|
11
11
|
###
|
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/syntax_error.rb
CHANGED
data/lib/psych/tree_builder.rb
CHANGED
data/lib/psych/versions.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require_relative '../scalar_scanner'
|
3
|
+
require_relative '../class_loader'
|
4
|
+
require_relative '../exception'
|
5
5
|
|
6
6
|
unless defined?(Regexp::NOENCODING)
|
7
7
|
Regexp::NOENCODING = 32
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
2
|
+
require_relative '../tree_builder'
|
3
|
+
require_relative '../scalar_scanner'
|
4
|
+
require_relative '../class_loader'
|
5
5
|
|
6
6
|
module Psych
|
7
7
|
module Visitors
|
@@ -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:]][^"]*$/
|
@@ -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/visitors.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
2
|
+
require_relative 'visitors/visitor'
|
3
|
+
require_relative 'visitors/to_ruby'
|
4
|
+
require_relative 'visitors/emitter'
|
5
|
+
require_relative 'visitors/yaml_tree'
|
6
|
+
require_relative 'visitors/json_tree'
|
7
|
+
require_relative 'visitors/depth_first'
|
data/lib/psych.jar
CHANGED
Binary file
|
data/lib/psych.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
2
|
+
require_relative 'psych/versions'
|
3
3
|
case RUBY_ENGINE
|
4
4
|
when 'jruby'
|
5
|
-
|
5
|
+
require_relative 'psych_jars'
|
6
6
|
if JRuby::Util.respond_to?(:load_ext)
|
7
7
|
JRuby::Util.load_ext('org.jruby.ext.psych.PsychLibrary')
|
8
8
|
else
|
@@ -12,28 +12,28 @@ when 'jruby'
|
|
12
12
|
else
|
13
13
|
require 'psych.so'
|
14
14
|
end
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
15
|
+
require_relative 'psych/nodes'
|
16
|
+
require_relative 'psych/streaming'
|
17
|
+
require_relative 'psych/visitors'
|
18
|
+
require_relative 'psych/handler'
|
19
|
+
require_relative 'psych/tree_builder'
|
20
|
+
require_relative 'psych/parser'
|
21
|
+
require_relative 'psych/omap'
|
22
|
+
require_relative 'psych/set'
|
23
|
+
require_relative 'psych/coder'
|
24
|
+
require_relative 'psych/core_ext'
|
25
|
+
require_relative 'psych/stream'
|
26
|
+
require_relative 'psych/json/tree_builder'
|
27
|
+
require_relative 'psych/json/stream'
|
28
|
+
require_relative 'psych/handlers/document_stream'
|
29
|
+
require_relative 'psych/class_loader'
|
30
30
|
|
31
31
|
###
|
32
32
|
# = Overview
|
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,21 +259,16 @@ 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.unsafe_load yaml,
|
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)
|
@@ -290,7 +282,8 @@ module Psych
|
|
290
282
|
# * TrueClass
|
291
283
|
# * FalseClass
|
292
284
|
# * NilClass
|
293
|
-
# *
|
285
|
+
# * Integer
|
286
|
+
# * Float
|
294
287
|
# * String
|
295
288
|
# * Array
|
296
289
|
# * Hash
|
@@ -327,27 +320,7 @@ module Psych
|
|
327
320
|
# Psych.safe_load("---\n foo: bar") # => {"foo"=>"bar"}
|
328
321
|
# Psych.safe_load("---\n foo: bar", symbolize_names: true) # => {:foo=>"bar"}
|
329
322
|
#
|
330
|
-
def self.safe_load yaml,
|
331
|
-
if legacy_permitted_classes != NOT_GIVEN
|
332
|
-
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
|
333
|
-
permitted_classes = legacy_permitted_classes
|
334
|
-
end
|
335
|
-
|
336
|
-
if legacy_permitted_symbols != NOT_GIVEN
|
337
|
-
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
|
338
|
-
permitted_symbols = legacy_permitted_symbols
|
339
|
-
end
|
340
|
-
|
341
|
-
if legacy_aliases != NOT_GIVEN
|
342
|
-
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
|
343
|
-
aliases = legacy_aliases
|
344
|
-
end
|
345
|
-
|
346
|
-
if legacy_filename != NOT_GIVEN
|
347
|
-
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
|
348
|
-
filename = legacy_filename
|
349
|
-
end
|
350
|
-
|
323
|
+
def self.safe_load yaml, permitted_classes: [], permitted_symbols: [], aliases: false, filename: nil, fallback: nil, symbolize_names: false, freeze: false
|
351
324
|
result = parse(yaml, filename: filename)
|
352
325
|
return fallback unless result
|
353
326
|
|
@@ -363,6 +336,46 @@ module Psych
|
|
363
336
|
result
|
364
337
|
end
|
365
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
|
+
|
366
379
|
###
|
367
380
|
# Parse a YAML string in +yaml+. Returns the Psych::Nodes::Document.
|
368
381
|
# +filename+ is used in the exception message if a Psych::SyntaxError is
|
@@ -382,22 +395,12 @@ module Psych
|
|
382
395
|
# end
|
383
396
|
#
|
384
397
|
# See Psych::Nodes for more information about YAML AST.
|
385
|
-
def self.parse yaml,
|
386
|
-
if legacy_filename != NOT_GIVEN
|
387
|
-
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
|
388
|
-
filename = legacy_filename
|
389
|
-
end
|
390
|
-
|
398
|
+
def self.parse yaml, filename: nil
|
391
399
|
parse_stream(yaml, filename: filename) do |node|
|
392
400
|
return node
|
393
401
|
end
|
394
402
|
|
395
|
-
|
396
|
-
warn_with_uplevel 'Passing the `fallback` keyword argument of Psych.parse is deprecated.', uplevel: 1 if $VERBOSE
|
397
|
-
fallback
|
398
|
-
else
|
399
|
-
false
|
400
|
-
end
|
403
|
+
false
|
401
404
|
end
|
402
405
|
|
403
406
|
###
|
@@ -446,12 +449,7 @@ module Psych
|
|
446
449
|
# Raises a TypeError when NilClass is passed.
|
447
450
|
#
|
448
451
|
# See Psych::Nodes for more information about YAML AST.
|
449
|
-
def self.parse_stream yaml,
|
450
|
-
if legacy_filename != NOT_GIVEN
|
451
|
-
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
|
452
|
-
filename = legacy_filename
|
453
|
-
end
|
454
|
-
|
452
|
+
def self.parse_stream yaml, filename: nil, &block
|
455
453
|
if block_given?
|
456
454
|
parser = Psych::Parser.new(Handlers::DocumentStream.new(&block))
|
457
455
|
parser.parse yaml, filename
|
@@ -515,6 +513,79 @@ module Psych
|
|
515
513
|
visitor.tree.yaml io, options
|
516
514
|
end
|
517
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
|
+
|
518
589
|
###
|
519
590
|
# Dump a list of objects as separate documents to a document stream.
|
520
591
|
#
|
@@ -552,12 +623,7 @@ module Psych
|
|
552
623
|
# end
|
553
624
|
# list # => ['foo', 'bar']
|
554
625
|
#
|
555
|
-
def self.load_stream yaml,
|
556
|
-
if legacy_filename != NOT_GIVEN
|
557
|
-
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
|
558
|
-
filename = legacy_filename
|
559
|
-
end
|
560
|
-
|
626
|
+
def self.load_stream yaml, filename: nil, fallback: [], **kwargs
|
561
627
|
result = if block_given?
|
562
628
|
parse_stream(yaml, filename: filename) do |node|
|
563
629
|
yield node.to_ruby(**kwargs)
|
@@ -583,7 +649,6 @@ module Psych
|
|
583
649
|
self.unsafe_load f, filename: filename, **kwargs
|
584
650
|
}
|
585
651
|
end
|
586
|
-
class << self; alias :load_file :unsafe_load_file; end
|
587
652
|
|
588
653
|
###
|
589
654
|
# Safely loads the document contained in +filename+. Returns the yaml contained in
|
@@ -596,6 +661,17 @@ module Psych
|
|
596
661
|
}
|
597
662
|
end
|
598
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
|
+
|
599
675
|
# :stopdoc:
|
600
676
|
def self.add_domain_type domain, type_tag, &block
|
601
677
|
key = ['tag', domain, type_tag].join ':'
|
data/psych.gemspec
CHANGED
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.3
|
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-12-20 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.1.6
|
142
142
|
signing_key:
|
143
143
|
specification_version: 4
|
144
144
|
summary: Psych is a YAML parser and emitter
|