boonproject / boon

Simple opinionated Java for the novice to expert level Java Programmer. Low Ceremony. High Productivity.
http://richardhightower.github.io/site/Boon/Welcome.html
Apache License 2.0
522 stars 102 forks source link

Does not escape single double quote key #344

Closed mathiasxx closed 8 years ago

mathiasxx commented 8 years ago

I'm seeing this with java8 and 0.33 boon:

code:

  public static void main(String[] args) {
    ObjectMapper mapper = JsonFactory.create();
    HashMap<String, Object> data = new HashMap<>();
    data.put("\"", Double.parseDouble("1.2312312"));
    System.out.println(mapper.writeValueAsString(data));
}

output:

{""":1.2312312}
RichardHightower commented 8 years ago

thanks for reporting this.. I will take a look.

RichardHightower commented 8 years ago

I looked it up. We don't json encode keys. We probably should. We do encode values.

/*
 * Copyright 2013-2014 Richard M. Hightower
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *          http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * __________                              _____          __   .__
 * \______   \ ____   ____   ____   /\    /     \ _____  |  | _|__| ____    ____
 *  |    |  _//  _ \ /  _ \ /    \  \/   /  \ /  \\__  \ |  |/ /  |/    \  / ___\
 *  |    |   (  <_> |  <_> )   |  \ /\  /    Y    \/ __ \|    <|  |   |  \/ /_/  >
 *  |______  /\____/ \____/|___|  / \/  \____|__  (____  /__|_ \__|___|  /\___  /
 *         \/                   \/              \/     \/     \/       \//_____/
 *      ____.                     ___________   _____    ______________.___.
 *     |    |____ ___  _______    \_   _____/  /  _  \  /   _____/\__  |   |
 *     |    \__  \\  \/ /\__  \    |    __)_  /  /_\  \ \_____  \  /   |   |
 * /\__|    |/ __ \\   /  / __ \_  |        \/    |    \/        \ \____   |
 * \________(____  /\_/  (____  / /_______  /\____|__  /_______  / / ______|
 *               \/           \/          \/         \/        \/  \/
 */

package io.advantageous.boon.json.serializers.impl;

import io.advantageous.boon.core.reflection.FastStringUtils;
import io.advantageous.boon.json.serializers.JsonSerializerInternal;
import io.advantageous.boon.json.serializers.MapSerializer;
import io.advantageous.boon.primitive.CharBuf;

import java.util.Map;
import java.util.Set;

/**
 * Created by rick on 1/1/14.
 */
public class MapSerializerImpl implements MapSerializer {
    private static final char [] EMPTY_MAP_CHARS = {'{', '}'};
    private final boolean includeNulls;

    public MapSerializerImpl(boolean includeNulls) {
        this.includeNulls = includeNulls;
    }

    private void serializeFieldName ( String name, CharBuf builder ) {
        builder.addJsonFieldName ( FastStringUtils.toCharArray(name) );
    }

    @Override
    public final void serializeMap ( JsonSerializerInternal serializer, Map<Object, Object> map, CharBuf builder ) {

        if ( map.size () == 0 ) {
            builder.addChars ( EMPTY_MAP_CHARS );
            return;
        }

        builder.addChar( '{' );

        final Set<Map.Entry<Object, Object>> entrySet = map.entrySet();
        int index=0;

        if (!includeNulls) {
            for (Map.Entry<Object, Object> entry : entrySet) {
                if (entry.getValue() != null) {
                    serializeFieldName(entry.getKey().toString(), builder);
                    serializer.serializeObject(entry.getValue(), builder);
                    builder.addChar(',');
                    index++;
                }
            }
        }else {
            for (Map.Entry<Object, Object> entry : entrySet) {
                    serializeFieldName(entry.getKey().toString(), builder);
                    serializer.serializeObject(entry.getValue(), builder);
                    builder.addChar(',');
                    index++;

            }
        }
        if (index>0)
        builder.removeLastChar ();
        builder.addChar( '}' );

    }
}

I can make it as an option. It does not come up too much. Value encoding yes. Key encoding no. But it seems like a very valid use case to me.

RichardHightower commented 8 years ago

I fixed it in https://github.com/advantageous/boon/commit/606763f4f869b3e808e1935153fc003ff8da4a8c but now I need to merge it in here.

RichardHightower commented 8 years ago

Fixed.

package org.boon.bugs;

import org.boon.json.*;
import org.junit.Test;

import java.util.HashMap;

import static junit.framework.Assert.assertEquals;
/**
 * Created by rick on 12/14/15.
 */
public class BoonBug344 {

        @Test
        public void test() {
            ObjectMapper mapper = JsonFactory.create(new JsonParserFactory(),
                    new JsonSerializerFactory().setSerializeMapKeys(true).setEncodeStrings(true));
            HashMap<String, Object> data = new HashMap<>();
            data.put("\"hi\"", Double.parseDouble("1.2312312"));

            assertEquals("{\"\\\"hi\\\"\":1.2312312}", mapper.toJson(data));
        }

        @Test
        public void test2() {
            final JsonSerializerFactory jsonSerializerFactory = new JsonSerializerFactory();
            final JsonSerializer jsonSerializer = jsonSerializerFactory.setSerializeMapKeys(true).setEncodeStrings(true).create();

            HashMap<String, Object> data = new HashMap<>();
            data.put("\"hi\"", Double.parseDouble("1.2312312"));

            assertEquals("{\"\\\"hi\\\"\":1.2312312}", jsonSerializer.serialize(data).toString());
        }
}

Please try it and let me know.

RichardHightower commented 8 years ago

fixed it and sent you a linked in request. seems we have the same barber. Thanks for the good bug report with a short code example. It makes fixing much easier when I can write a unit test.

mathiasxx commented 8 years ago

Thanks for the quick attention. It looks like you've git it fixed, but I'll write back here after I jar this up and drop it in my project.

mathiasxx commented 8 years ago

Is there a doc somewhere with build instructions? My optimistic attempts with mvn package and gradle build both ended in failure.

mathiasxx commented 8 years ago

Well, build worked well enough to create "boon.jar". Tried out the new jar and it serializes properly. Thanks!

RichardHightower commented 8 years ago

cool beans. sorry.. I missed your earlier messages. Been under water... coming up for air. Glad you figured it out.