psych 3.3.1-java → 4.0.2-java
Sign up to get free protection for your applications and to get access to all the features.
- 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
|