youxinren / snakeyaml

Automatically exported from code.google.com/p/snakeyaml
Apache License 2.0
0 stars 0 forks source link

Length of Base64 encoded input string is not a multiple of 4 #99

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I am unable to load a base64 file that has line breaks, however if I removed 
all line breaks it would work. 

Below is the error message and my testcase. I have tried using version 
SnakeYaml 1.5 and 1.6 both failed.

Regards
chungonn

org.yaml.snakeyaml.error.YAMLException: Length of Base64 encoded input string 
is not a multiple of 4.
    at org.yaml.snakeyaml.util.Base64Coder.decode(Base64Coder.java:91)
    at org.yaml.snakeyaml.constructor.SafeConstructor$ConstructYamlBinary.construct(SafeConstructor.java:248)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:184)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping2ndStep(BaseConstructor.java:327)
    at org.yaml.snakeyaml.constructor.SafeConstructor.constructMapping2ndStep(SafeConstructor.java:125)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping(BaseConstructor.java:308)
    at org.yaml.snakeyaml.constructor.SafeConstructor$ConstructYamlMap.construct(SafeConstructor.java:443)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:184)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping2ndStep(BaseConstructor.java:327)
    at org.yaml.snakeyaml.constructor.SafeConstructor.constructMapping2ndStep(SafeConstructor.java:125)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructMapping(BaseConstructor.java:308)
    at org.yaml.snakeyaml.constructor.SafeConstructor$ConstructYamlMap.construct(SafeConstructor.java:443)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:184)
    at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:143)
    at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:129)
    at org.yaml.snakeyaml.Yaml.load(Yaml.java:264)
    at org.yaml.snakeyaml.Yaml.load(Yaml.java:250)
    at models.roster.YamlBase64Test.testYamlBase64Loading(YamlBase64Test.java:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Original issue reported on code.google.com by chungonn@gmail.com on 3 Jan 2011 at 1:48

Attachments:

GoogleCodeExporter commented 9 years ago
Thank you for using SnakeYAML and trying to improve it.

The error happens because you try to use literal scalar where line breaks are 
respected. This is the spec (http://yaml.org/spec/1.1/#id858081):
"Scalar content can be written ... using a literal style (“|”) where all 
line breaks are significant"

You need to use double quoted scalar (http://yaml.org/spec/1.1/#id904245) to 
escape the line breaks.
See the example: 
YAML: 
http://code.google.com/p/snakeyaml/source/browse/src/test/resources/issues/issue
99-base64_double_quoted.yaml

test: 
http://code.google.com/p/snakeyaml/source/browse/src/test/java/org/yaml/snakeyam
l/issues/issue99/YamlBase64Test.java

Complete change: 
http://code.google.com/p/snakeyaml/source/detail?r=ef6beaf29a3a814962a1e85156278
6d9490d2517

Original comment by py4fun@gmail.com on 3 Jan 2011 at 12:20

GoogleCodeExporter commented 9 years ago
Hi,

Thanks for the quick response. I got it working after the following your links. 
Btw, if it is not too much to ask if SnakeYAML can be enhanced to read a double 
quoted scalar without the last '\' character in each line. This would mean that 
we could use direct output generated from an base64 encoding utility

Thank you once again for the help

Original comment by chungonn@gmail.com on 4 Jan 2011 at 6:58

GoogleCodeExporter commented 9 years ago
I am afraid you misunderstood the issue. It is not a bug but a feature of 
SnakeYAML. It works according to the specification. If you wish to enhance the 
way how YAML looks and works you can start a topic in the core YAML list:
http://groups.google.com/group/yaml-core

Original comment by py4fun@gmail.com on 4 Jan 2011 at 8:50

GoogleCodeExporter commented 9 years ago
Yes, I know it is not a bug. It was just an enhancement request. I recall 
somewhere from SnakeYAML document 'binary' section that refer to this link 
http://yaml.org/type/binary.html where it has an example with line-break and 
without the '\' character at the end of each line.

Original comment by chungonn@gmail.com on 4 Jan 2011 at 9:12

GoogleCodeExporter commented 9 years ago
I think I understand now what you wish to achieve. Check 
http://code.google.com/p/snakeyaml/source/browse/src/test/java/org/yaml/snakeyam
l/issues/issue99/YamlBase64Test.java (testRedefineBinaryTag)

The processing of the global !!binary tag is changes to ignore the white 
spaces. You can also define your own local tag as it is done here 
http://yaml.org/type/binary.html (mind the single '!' to indicate the local 
tag). So you can use the direct output generated from an base64 encoding 
utility.

Disadvantages:
1) Redefining standard global tags is not supported by all parsers. I know that 
PyYAML and SnakeYAML support it. If you give your YAML document to another 
party they must migrate to these parsers.
2) Your YAML document will require special treatment. If you give your document 
to the public they cannot simply parse it with standard tools. Of course if you 
control both producer and consumer of the YAML document it should not be a big 
issue

P.S. While writing the example I found how the implementation can be further 
simplified. May be I will manage to implement it in release 1.8

Original comment by py4fun@gmail.com on 4 Jan 2011 at 4:25

GoogleCodeExporter commented 9 years ago
You shall be careful if you use a YAML document in the context of an existing 
framework like Play!. Using custom constructors may break some features. Play! 
is using its own extensions to encode test fixtures. I would recommend to 
contact Play! developers to clarify the issue and stick to the standard way in 
the meantime.

The improvement I wanted to introduce in release 1.8 will not change anything 
here. It would be merely a minor enhancement to simplify constructor code. I am 
not sure it will be done in release 1.8

Original comment by py4fun@gmail.com on 7 Jan 2011 at 9:12

GoogleCodeExporter commented 9 years ago

Original comment by py4fun@gmail.com on 18 Jan 2011 at 9:38