Skip to content

Commit dc345fe

Browse files
Merge 0a31804 into 4e29063
2 parents 4e29063 + 0a31804 commit dc345fe

File tree

6 files changed

+64
-53
lines changed

6 files changed

+64
-53
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

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

1011
### Features
1112

sentry/api/sentry.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4365,6 +4365,7 @@ public final class io/sentry/util/ExceptionUtils {
43654365
public final class io/sentry/util/FileUtils {
43664366
public fun <init> ()V
43674367
public static fun deleteRecursively (Ljava/io/File;)Z
4368+
public static fun readBytesFromFile (Ljava/lang/String;J)[B
43684369
public static fun readText (Ljava/io/File;)Ljava/lang/String;
43694370
}
43704371

sentry/src/main/java/io/sentry/SentryEnvelopeItem.java

Lines changed: 1 addition & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.sentry;
22

3+
import static io.sentry.util.FileUtils.readBytesFromFile;
34
import static io.sentry.vendor.Base64.NO_PADDING;
45
import static io.sentry.vendor.Base64.NO_WRAP;
56

@@ -9,13 +10,11 @@
910
import io.sentry.util.JsonSerializationUtils;
1011
import io.sentry.util.Objects;
1112
import io.sentry.vendor.Base64;
12-
import java.io.BufferedInputStream;
1313
import java.io.BufferedReader;
1414
import java.io.BufferedWriter;
1515
import java.io.ByteArrayInputStream;
1616
import java.io.ByteArrayOutputStream;
1717
import java.io.File;
18-
import java.io.FileInputStream;
1918
import java.io.IOException;
2019
import java.io.InputStreamReader;
2120
import java.io.OutputStreamWriter;
@@ -304,48 +303,6 @@ private static void ensureAttachmentSizeLimit(
304303
return new SentryEnvelopeItem(itemHeader, () -> cachedItem.getBytes());
305304
}
306305

307-
private static byte[] readBytesFromFile(String pathname, long maxFileLength)
308-
throws SentryEnvelopeException {
309-
try {
310-
File file = new File(pathname);
311-
312-
if (!file.isFile()) {
313-
throw new SentryEnvelopeException(
314-
String.format(
315-
"Reading the item %s failed, because the file located at the path is not a file.",
316-
pathname));
317-
}
318-
319-
if (!file.canRead()) {
320-
throw new SentryEnvelopeException(
321-
String.format("Reading the item %s failed, because can't read the file.", pathname));
322-
}
323-
324-
if (file.length() > maxFileLength) {
325-
throw new SentryEnvelopeException(
326-
String.format(
327-
"Dropping item, because its size located at '%s' with %d bytes is bigger "
328-
+ "than the maximum allowed size of %d bytes.",
329-
pathname, file.length(), maxFileLength));
330-
}
331-
332-
try (FileInputStream fileInputStream = new FileInputStream(pathname);
333-
BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
334-
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
335-
byte[] bytes = new byte[1024];
336-
int length;
337-
int offset = 0;
338-
while ((length = inputStream.read(bytes)) != -1) {
339-
outputStream.write(bytes, offset, length);
340-
}
341-
return outputStream.toByteArray();
342-
}
343-
} catch (IOException | SecurityException exception) {
344-
throw new SentryEnvelopeException(
345-
String.format("Reading the item %s failed.\n%s", pathname, exception.getMessage()));
346-
}
347-
}
348-
349306
public static @NotNull SentryEnvelopeItem fromClientReport(
350307
final @NotNull ISerializer serializer, final @NotNull ClientReport clientReport)
351308
throws IOException {

sentry/src/main/java/io/sentry/util/FileUtils.java

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
package io.sentry.util;
22

3+
import java.io.BufferedInputStream;
34
import java.io.BufferedReader;
5+
import java.io.ByteArrayOutputStream;
46
import java.io.File;
7+
import java.io.FileInputStream;
58
import java.io.FileReader;
69
import java.io.IOException;
710
import org.jetbrains.annotations.ApiStatus;
@@ -60,4 +63,52 @@ public static boolean deleteRecursively(@Nullable File file) {
6063
}
6164
return contentBuilder.toString();
6265
}
66+
67+
/**
68+
* Reads the content of a path into a byte array. If the path is does not exists, it's not a file,
69+
* can't be read or is larger than max size allowed IOException is thrown. Do not use with large
70+
* files, as the byte array is kept in memory!
71+
*
72+
* @param pathname file to read
73+
* @return a byte array containing all the content of the file
74+
* @throws IOException In case of error reading the file
75+
*/
76+
public static byte[] readBytesFromFile(String pathname, long maxFileLength)
77+
throws IOException, SecurityException {
78+
File file = new File(pathname);
79+
80+
if (!file.exists()) {
81+
throw new IOException(String.format("File '%s' doesn't exists", file.getName()));
82+
}
83+
84+
if (!file.isFile()) {
85+
throw new IOException(
86+
String.format("Reading path %s failed, because it's not a file.", pathname));
87+
}
88+
89+
if (!file.canRead()) {
90+
throw new IOException(
91+
String.format("Reading the item %s failed, because can't read the file.", pathname));
92+
}
93+
94+
if (file.length() > maxFileLength) {
95+
throw new IOException(
96+
String.format(
97+
"Reading file failed, because size located at '%s' with %d bytes is bigger "
98+
+ "than the maximum allowed size of %d bytes.",
99+
pathname, file.length(), maxFileLength));
100+
}
101+
102+
try (FileInputStream fileInputStream = new FileInputStream(pathname);
103+
BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
104+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
105+
byte[] bytes = new byte[1024];
106+
int length;
107+
int offset = 0;
108+
while ((length = inputStream.read(bytes)) != -1) {
109+
outputStream.write(bytes, offset, length);
110+
}
111+
return outputStream.toByteArray();
112+
}
113+
}
63114
}

sentry/src/test/java/io/sentry/JsonSerializerTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ class JsonSerializerTest {
10371037
.log(
10381038
eq(SentryLevel.ERROR),
10391039
eq("Failed to create envelope item. Dropping it."),
1040-
any<SentryEnvelopeException>()
1040+
any<IOException>()
10411041
)
10421042
}
10431043

sentry/src/test/java/io/sentry/SentryEnvelopeItemTest.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import org.mockito.kotlin.whenever
1313
import java.io.BufferedWriter
1414
import java.io.ByteArrayOutputStream
1515
import java.io.File
16+
import java.io.IOException
1617
import java.io.OutputStreamWriter
1718
import java.nio.charset.Charset
1819
import kotlin.test.AfterTest
@@ -120,7 +121,7 @@ class SentryEnvelopeItemTest {
120121

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

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

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

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

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

166-
assertFailsWith<SentryEnvelopeException>("Reading the attachment ${attachment.pathname} failed.") {
167+
assertFailsWith<SecurityException>("Reading the attachment ${attachment.pathname} failed.") {
167168
item.data
168169
}
169170

@@ -244,12 +245,12 @@ class SentryEnvelopeItemTest {
244245
file.writeBytes(fixture.bytesTooBig)
245246
val attachment = Attachment(file.path)
246247

247-
val exception = assertFailsWith<SentryEnvelopeException> {
248+
val exception = assertFailsWith<IOException> {
248249
SentryEnvelopeItem.fromAttachment(fixture.serializer, fixture.options.logger, attachment, fixture.maxAttachmentSize).data
249250
}
250251

251252
assertEquals(
252-
"Dropping item, because its size located at " +
253+
"Reading file failed, because size located at " +
253254
"'${fixture.pathname}' with ${file.length()} bytes is bigger than the maximum " +
254255
"allowed size of ${fixture.maxAttachmentSize} bytes.",
255256
exception.message
@@ -317,7 +318,7 @@ class SentryEnvelopeItemTest {
317318
}
318319
file.writeBytes(fixture.bytes)
319320
file.setReadable(false)
320-
assertFailsWith<SentryEnvelopeException>("Dropping profiling trace data, because the file ${file.path} doesn't exists") {
321+
assertFailsWith<IOException>("Dropping profiling trace data, because the file ${file.path} doesn't exists") {
321322
SentryEnvelopeItem.fromProfilingTrace(profilingTraceData, fixture.maxAttachmentSize, mock()).data
322323
}
323324
}
@@ -344,12 +345,12 @@ class SentryEnvelopeItemTest {
344345
whenever(it.traceFile).thenReturn(file)
345346
}
346347

347-
val exception = assertFailsWith<SentryEnvelopeException> {
348+
val exception = assertFailsWith<IOException> {
348349
SentryEnvelopeItem.fromProfilingTrace(profilingTraceData, fixture.maxAttachmentSize, mock()).data
349350
}
350351

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

0 commit comments

Comments
 (0)