Skip to content

Commit

Permalink
Merge 0a31804 into 4e29063
Browse files Browse the repository at this point in the history
  • Loading branch information
krystofwoldrich authored Nov 15, 2023
2 parents 4e29063 + 0a31804 commit dc345fe
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 53 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

- (Internal) Extract Android Profiler and Measurements for Hybrid SDKs ([#3016](https://github.com/getsentry/sentry-java/pull/3016))
- Ensure DSN uses http/https protocol ([#3044](https://github.com/getsentry/sentry-java/pull/3044))
- (Internal) Add `readBytesFromFile` for use in Hybrid SDKs ([#3052](https://github.com/getsentry/sentry-java/pull/3052))

### Features

Expand Down
1 change: 1 addition & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -4365,6 +4365,7 @@ public final class io/sentry/util/ExceptionUtils {
public final class io/sentry/util/FileUtils {
public fun <init> ()V
public static fun deleteRecursively (Ljava/io/File;)Z
public static fun readBytesFromFile (Ljava/lang/String;J)[B
public static fun readText (Ljava/io/File;)Ljava/lang/String;
}

Expand Down
45 changes: 1 addition & 44 deletions sentry/src/main/java/io/sentry/SentryEnvelopeItem.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.sentry;

import static io.sentry.util.FileUtils.readBytesFromFile;
import static io.sentry.vendor.Base64.NO_PADDING;
import static io.sentry.vendor.Base64.NO_WRAP;

Expand All @@ -9,13 +10,11 @@
import io.sentry.util.JsonSerializationUtils;
import io.sentry.util.Objects;
import io.sentry.vendor.Base64;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
Expand Down Expand Up @@ -304,48 +303,6 @@ private static void ensureAttachmentSizeLimit(
return new SentryEnvelopeItem(itemHeader, () -> cachedItem.getBytes());
}

private static byte[] readBytesFromFile(String pathname, long maxFileLength)
throws SentryEnvelopeException {
try {
File file = new File(pathname);

if (!file.isFile()) {
throw new SentryEnvelopeException(
String.format(
"Reading the item %s failed, because the file located at the path is not a file.",
pathname));
}

if (!file.canRead()) {
throw new SentryEnvelopeException(
String.format("Reading the item %s failed, because can't read the file.", pathname));
}

if (file.length() > maxFileLength) {
throw new SentryEnvelopeException(
String.format(
"Dropping item, because its size located at '%s' with %d bytes is bigger "
+ "than the maximum allowed size of %d bytes.",
pathname, file.length(), maxFileLength));
}

try (FileInputStream fileInputStream = new FileInputStream(pathname);
BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] bytes = new byte[1024];
int length;
int offset = 0;
while ((length = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, offset, length);
}
return outputStream.toByteArray();
}
} catch (IOException | SecurityException exception) {
throw new SentryEnvelopeException(
String.format("Reading the item %s failed.\n%s", pathname, exception.getMessage()));
}
}

public static @NotNull SentryEnvelopeItem fromClientReport(
final @NotNull ISerializer serializer, final @NotNull ClientReport clientReport)
throws IOException {
Expand Down
51 changes: 51 additions & 0 deletions sentry/src/main/java/io/sentry/util/FileUtils.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package io.sentry.util;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import org.jetbrains.annotations.ApiStatus;
Expand Down Expand Up @@ -60,4 +63,52 @@ public static boolean deleteRecursively(@Nullable File file) {
}
return contentBuilder.toString();
}

/**
* Reads the content of a path into a byte array. If the path is does not exists, it's not a file,
* can't be read or is larger than max size allowed IOException is thrown. Do not use with large
* files, as the byte array is kept in memory!
*
* @param pathname file to read
* @return a byte array containing all the content of the file
* @throws IOException In case of error reading the file
*/
public static byte[] readBytesFromFile(String pathname, long maxFileLength)
throws IOException, SecurityException {
File file = new File(pathname);

if (!file.exists()) {
throw new IOException(String.format("File '%s' doesn't exists", file.getName()));
}

if (!file.isFile()) {
throw new IOException(
String.format("Reading path %s failed, because it's not a file.", pathname));
}

if (!file.canRead()) {
throw new IOException(
String.format("Reading the item %s failed, because can't read the file.", pathname));
}

if (file.length() > maxFileLength) {
throw new IOException(
String.format(
"Reading file failed, because size located at '%s' with %d bytes is bigger "
+ "than the maximum allowed size of %d bytes.",
pathname, file.length(), maxFileLength));
}

try (FileInputStream fileInputStream = new FileInputStream(pathname);
BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
byte[] bytes = new byte[1024];
int length;
int offset = 0;
while ((length = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, offset, length);
}
return outputStream.toByteArray();
}
}
}
2 changes: 1 addition & 1 deletion sentry/src/test/java/io/sentry/JsonSerializerTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ class JsonSerializerTest {
.log(
eq(SentryLevel.ERROR),
eq("Failed to create envelope item. Dropping it."),
any<SentryEnvelopeException>()
any<IOException>()
)
}

Expand Down
17 changes: 9 additions & 8 deletions sentry/src/test/java/io/sentry/SentryEnvelopeItemTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.mockito.kotlin.whenever
import java.io.BufferedWriter
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.IOException
import java.io.OutputStreamWriter
import java.nio.charset.Charset
import kotlin.test.AfterTest
Expand Down Expand Up @@ -120,7 +121,7 @@ class SentryEnvelopeItemTest {

val item = SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize)

assertFailsWith<SentryEnvelopeException>(
assertFailsWith<IOException>(
"Reading the attachment ${attachment.pathname} failed, because the file located at " +
"the path is not a file."
) {
Expand All @@ -140,7 +141,7 @@ class SentryEnvelopeItemTest {

val item = SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize)

assertFailsWith<SentryEnvelopeException>(
assertFailsWith<IOException>(
"Reading the attachment ${attachment.pathname} failed, " +
"because can't read the file."
) {
Expand All @@ -163,7 +164,7 @@ class SentryEnvelopeItemTest {

val item = SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize)

assertFailsWith<SentryEnvelopeException>("Reading the attachment ${attachment.pathname} failed.") {
assertFailsWith<SecurityException>("Reading the attachment ${attachment.pathname} failed.") {
item.data
}

Expand Down Expand Up @@ -244,12 +245,12 @@ class SentryEnvelopeItemTest {
file.writeBytes(fixture.bytesTooBig)
val attachment = Attachment(file.path)

val exception = assertFailsWith<SentryEnvelopeException> {
val exception = assertFailsWith<IOException> {
SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize).data
}

assertEquals(
"Dropping item, because its size located at " +
"Reading file failed, because size located at " +
"'${fixture.pathname}' with ${file.length()} bytes is bigger than the maximum " +
"allowed size of ${fixture.maxAttachmentSize} bytes.",
exception.message
Expand Down Expand Up @@ -317,7 +318,7 @@ class SentryEnvelopeItemTest {
}
file.writeBytes(fixture.bytes)
file.setReadable(false)
assertFailsWith<SentryEnvelopeException>("Dropping profiling trace data, because the file ${file.path} doesn't exists") {
assertFailsWith<IOException>("Dropping profiling trace data, because the file ${file.path} doesn't exists") {
SentryEnvelopeItem.fromProfilingTrace(profilingTraceData, fixture.maxAttachmentSize, mock()).data
}
}
Expand All @@ -344,12 +345,12 @@ class SentryEnvelopeItemTest {
whenever(it.traceFile).thenReturn(file)
}

val exception = assertFailsWith<SentryEnvelopeException> {
val exception = assertFailsWith<IOException> {
SentryEnvelopeItem.fromProfilingTrace(profilingTraceData, fixture.maxAttachmentSize, mock()).data
}

assertEquals(
"Dropping item, because its size located at " +
"Reading file failed, because size located at " +
"'${fixture.pathname}' with ${file.length()} bytes is bigger than the maximum " +
"allowed size of ${fixture.maxAttachmentSize} bytes.",
exception.message
Expand Down

0 comments on commit dc345fe

Please sign in to comment.