Skip to content

Commit

Permalink
fix: replace '+' to '%2B' to handle page strs encode (apache#1437)
Browse files Browse the repository at this point in the history
  • Loading branch information
imbajin authored May 20, 2021
1 parent acb7eb1 commit 0fbe4d1
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public class PageState {

public static final byte[] EMPTY_BYTES = new byte[0];
public static final PageState EMPTY = new PageState(EMPTY_BYTES, 0, 0);
public static final char SPACE = ' ';
public static final char PLUS = '+';

private final byte[] position;
private final int offset;
Expand Down Expand Up @@ -73,6 +75,12 @@ private byte[] toBytes() {

public static PageState fromString(String page) {
E.checkNotNull(page, "page");
/*
* URLDecoder will auto decode '+' to space in url due to the request
* of HTML4, so we choose to replace the space to '+' after getting it
* More details refer to #1437
*/
page = page.replace(SPACE, PLUS);
return fromBytes(toBytes(page));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
Expand Down Expand Up @@ -54,6 +55,7 @@
import com.baidu.hugegraph.backend.id.SnowflakeIdGenerator;
import com.baidu.hugegraph.backend.id.SplicingIdGenerator;
import com.baidu.hugegraph.backend.page.PageInfo;
import com.baidu.hugegraph.backend.page.PageState;
import com.baidu.hugegraph.backend.query.Condition;
import com.baidu.hugegraph.backend.query.ConditionQuery;
import com.baidu.hugegraph.backend.query.Query;
Expand Down Expand Up @@ -6667,6 +6669,35 @@ public void testQueryByPageWithInvalidPage() {
});
}

@Test
public void testQueryByPageWithSpecialBase64Chars() {
Assume.assumeTrue("Not support paging",
storeFeatures().supportsQueryByPage());
final String pageWith3Base64Chars = "AAAAADsyABwAEAqI546LS6WW57unBgA" +
"EAAAAAPB////+8H////4alhxAZS8va6" +
"opcAKpklipAAQAAAAAAAAAAQ==";

final String pageWithSpace = "AAAAADsyABwAEAqI546LS6WW57unBgAEAAAAAP" +
"B//// 8H////4alhxAZS8va6opcAKpklipAAQA" +
"AAAAAAAAAQ==";

HugeGraph graph = graph();
init100Books();

// Contains valid character '+' and '/' and '='
GraphTraversal<Vertex, Vertex> traversal;
traversal = graph.traversal().V()
.has("~page", pageWith3Base64Chars).limit(10);
Assert.assertNotNull(traversal);
CloseableIterator.closeIterator(traversal);

// Contains invalid base64 character ' ', will be replaced to '+'
traversal = graph.traversal().V()
.has("~page", pageWithSpace).limit(10);
Assert.assertNotNull(traversal);
CloseableIterator.closeIterator(traversal);
}

@Test
public void testQueryByPageWithInvalidLimit() {
Assume.assumeTrue("Not support paging",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import com.baidu.hugegraph.unit.core.DirectionsTest;
import com.baidu.hugegraph.unit.core.ExceptionTest;
import com.baidu.hugegraph.unit.core.LocksTableTest;
import com.baidu.hugegraph.unit.core.PageStateTest;
import com.baidu.hugegraph.unit.core.QueryTest;
import com.baidu.hugegraph.unit.core.RangeTest;
import com.baidu.hugegraph.unit.core.RolePermissionTest;
Expand Down Expand Up @@ -101,6 +102,7 @@
ExceptionTest.class,
BackendStoreSystemInfoTest.class,
TraversalUtilTest.class,
PageStateTest.class,

/* serializer */
BytesBufferTest.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* Copyright 2017 HugeGraph Authors
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to You 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.
*/

package com.baidu.hugegraph.unit.core;

import java.util.Arrays;

import org.junit.Test;

import com.baidu.hugegraph.backend.BackendException;
import com.baidu.hugegraph.backend.page.PageState;
import com.baidu.hugegraph.testutil.Assert;

public class PageStateTest {

private String pageWith3Base64Chars = "AAAAADsyABwAEAqI546LS6WW57unBgA" +
"EAAAAAPB////+8H////4alhxAZS8va6" +
"opcAKpklipAAQAAAAAAAAAAQ==";

private String pageWithSpace = "AAAAADsyABwAEAqI546LS6WW57unBgAEAAAAAP" +
"B//// 8H////4alhxAZS8va6opcAKpklipAAQA" +
"AAAAAAAAAQ==";

@Test
public void testOriginalStringPageToBytes() {
byte[] validPage = PageState.toBytes(pageWith3Base64Chars);
Assert.assertNotNull(validPage);

Assert.assertThrows(BackendException.class, () -> {
PageState.toBytes(pageWithSpace);
}, e -> {
Assert.assertContains("Invalid page:", e.toString());
});
}

@Test
public void testDecodePageWithSpecialBase64Chars() {
// Assert decode '+' and '/' and '=' and space successfully
Assert.assertNotNull(PageState.fromString(pageWith3Base64Chars));

byte[] decodePlus = PageState.fromString(pageWith3Base64Chars)
.position();
byte[] decodeSpace = PageState.fromString(pageWithSpace).position();

Assert.assertTrue(Arrays.equals(decodePlus, decodeSpace));
}

@Test
public void testDecodePageWithInvalidStringPage() {
final String invalidPageWithBase64Chars = "dGVzdCBiYXNlNjQ=";

Assert.assertThrows(BackendException.class, () -> {
PageState.fromString(invalidPageWithBase64Chars);
}, e -> {
Assert.assertContains("Invalid page: '0x", e.toString());
});

final String invalidBase64Chars = "!abc~";
Assert.assertThrows(BackendException.class, () -> {
PageState.fromString(invalidBase64Chars);
}, e -> {
Assert.assertContains("Invalid page:", e.toString());
});
}

@Test
public void testEmptyPageState() {
Assert.assertEquals(0, PageState.EMPTY.offset());
Assert.assertNull(PageState.EMPTY.toString());

Assert.assertEquals(PageState.EMPTY,
PageState.fromBytes(PageState.EMPTY_BYTES));
}
}

0 comments on commit 0fbe4d1

Please sign in to comment.