Add validation of snapshot FileInfo during parsing
Making sure that the file info that we read from the snapshot is still sane.
This commit is contained in:
parent
ae1ed34355
commit
8692292d0c
|
@ -26,6 +26,7 @@ import org.elasticsearch.ElasticsearchParseException;
|
|||
import org.elasticsearch.common.Nullable;
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.ParseFieldMatcher;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.lucene.Lucene;
|
||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
|
@ -298,7 +299,14 @@ public class BlobStoreIndexShardSnapshot {
|
|||
}
|
||||
}
|
||||
}
|
||||
// TODO: Verify???
|
||||
// Verify that file information is complete
|
||||
if (name == null || Strings.validFileName(name) == false) {
|
||||
throw new ElasticsearchParseException("missing or invalid file name [" + name + "]");
|
||||
} else if (physicalName == null || Strings.validFileName(physicalName) == false) {
|
||||
throw new ElasticsearchParseException("missing or invalid physical file name [" + physicalName + "]");
|
||||
} else if (length < 0) {
|
||||
throw new ElasticsearchParseException("missing or invalid file length");
|
||||
}
|
||||
return new FileInfo(name, new StoreFileMetaData(physicalName, length, checksum, writtenBy, metaHash), partSize);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,14 +20,17 @@ package org.elasticsearch.index.snapshots.blobstore;
|
|||
|
||||
import org.apache.lucene.util.BytesRef;
|
||||
import org.apache.lucene.util.Version;
|
||||
import org.elasticsearch.ElasticsearchParseException;
|
||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.common.xcontent.*;
|
||||
import org.elasticsearch.index.store.StoreFileMetaData;
|
||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
||||
import org.elasticsearch.index.snapshots.blobstore.BlobStoreIndexShardSnapshot.FileInfo.Fields;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.is;
|
||||
|
||||
|
@ -44,8 +47,8 @@ public class FileInfoTest extends ElasticsearchTestCase {
|
|||
for (int i = 0; i < hash.length; i++) {
|
||||
hash.bytes[i] = randomByte();
|
||||
}
|
||||
StoreFileMetaData meta = new StoreFileMetaData("foobar", randomInt(), randomAsciiOfLengthBetween(1, 10), Version.LATEST, hash);
|
||||
ByteSizeValue size = new ByteSizeValue(Math.max(0,Math.abs(randomLong())));
|
||||
StoreFileMetaData meta = new StoreFileMetaData("foobar", Math.abs(randomLong()), randomAsciiOfLengthBetween(1, 10), Version.LATEST, hash);
|
||||
ByteSizeValue size = new ByteSizeValue(Math.abs(randomLong()));
|
||||
BlobStoreIndexShardSnapshot.FileInfo info = new BlobStoreIndexShardSnapshot.FileInfo("_foobar", meta, size);
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON).prettyPrint();
|
||||
BlobStoreIndexShardSnapshot.FileInfo.toXContent(info, builder, ToXContent.EMPTY_PARAMS);
|
||||
|
@ -67,4 +70,71 @@ public class FileInfoTest extends ElasticsearchTestCase {
|
|||
assertThat(parsedInfo.isSame(info.metadata()), is(true));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvalidFieldsInFromXContent() throws IOException {
|
||||
final int iters = scaledRandomIntBetween(1, 10);
|
||||
for (int iter = 0; iter < iters; iter++) {
|
||||
final BytesRef hash = new BytesRef(scaledRandomIntBetween(0, 1024 * 1024));
|
||||
hash.length = hash.bytes.length;
|
||||
for (int i = 0; i < hash.length; i++) {
|
||||
hash.bytes[i] = randomByte();
|
||||
}
|
||||
String name = "foobar";
|
||||
String physicalName = "_foobar";
|
||||
String failure = null;
|
||||
long length = Math.max(0,Math.abs(randomLong()));
|
||||
// random corruption
|
||||
switch (randomIntBetween(0, 3)) {
|
||||
case 0:
|
||||
name = "foo,bar";
|
||||
failure = "missing or invalid file name";
|
||||
break;
|
||||
case 1:
|
||||
physicalName = "_foo,bar";
|
||||
failure = "missing or invalid physical file name";
|
||||
break;
|
||||
case 2:
|
||||
length = -Math.abs(randomLong());
|
||||
failure = "missing or invalid file length";
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
default:
|
||||
fail("shouldn't be here");
|
||||
}
|
||||
|
||||
XContentBuilder builder = XContentFactory.contentBuilder(XContentType.JSON);
|
||||
builder.startObject();
|
||||
builder.field(Fields.NAME, name);
|
||||
builder.field(Fields.PHYSICAL_NAME, physicalName);
|
||||
builder.field(Fields.LENGTH, length);
|
||||
builder.endObject();
|
||||
byte[] xContent = builder.bytes().toBytes();
|
||||
|
||||
if (failure == null) {
|
||||
// No failures should read as usual
|
||||
final BlobStoreIndexShardSnapshot.FileInfo parsedInfo;
|
||||
try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(xContent)) {
|
||||
parser.nextToken();
|
||||
parsedInfo = BlobStoreIndexShardSnapshot.FileInfo.fromXContent(parser);
|
||||
}
|
||||
assertThat(name, equalTo(parsedInfo.name()));
|
||||
assertThat(physicalName, equalTo(parsedInfo.physicalName()));
|
||||
assertThat(length, equalTo(parsedInfo.length()));
|
||||
assertNull(parsedInfo.checksum());
|
||||
assertNull(parsedInfo.metadata().checksum());
|
||||
assertNull(parsedInfo.metadata().writtenBy());
|
||||
} else {
|
||||
try (XContentParser parser = XContentFactory.xContent(XContentType.JSON).createParser(xContent)) {
|
||||
parser.nextToken();
|
||||
BlobStoreIndexShardSnapshot.FileInfo.fromXContent(parser);
|
||||
fail("Should have failed with [" + failure + "]");
|
||||
} catch (ElasticsearchParseException ex) {
|
||||
assertThat(ex.getMessage(), containsString(failure));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue