Skip to content

Commit 4effe22

Browse files
su-amaassam-luo-trendmicro
authored andcommitted
update to latest version: v1.6.4
1 parent 30823f5 commit 4effe22

13 files changed

Lines changed: 107 additions & 36 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# CHANGELOG
22

3+
## 1.6.4 - 2026-08-10
4+
5+
- Support new region ap-southeast-3 (Indonesia)
6+
- Support scan gateway for FSCS and FSVA
7+
- Add an Error Handling section to the README documenting SDK and service error codes and messages
8+
- Fix CVE-2026-46340 and CVE-2026-33871
9+
310
## 1.6.3 - 2026-04-13
411

512
- Support new regions af-south-1

‎README.md‎

Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ Creates a new instance of the `AmaasClient` class, and provisions essential sett
187187

188188
| Parameter | Description |
189189
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
190-
| region | The region you obtained your api key. Value provided must be one of the Vision One regions, e.g. `us-east-1`, `eu-central-1`, `ap-northeast-1`, `ap-southeast-2`, `ap-southeast-1`, `ap-south-1`, `me-central-1`,`eu-west-2`,`ca-central-1`,`af-south-1`, etc. If host is given, region will be ignored. |
190+
| region | The region you obtained your api key. Value provided must be one of the Vision One regions, e.g. `us-east-1`, `eu-central-1`, `ap-northeast-1`, `ap-southeast-2`, `ap-southeast-1`, `ap-south-1`, `me-central-1`,`eu-west-2`,`ca-central-1`,`af-south-1`,`ap-southeast-3`, etc. If host is given, region will be ignored. |
191191
| host | The host ip address of self hosted AMaaS scanner. Ignore if to use Trend AMaaS service |
192192
| apikey | Your own Vision One API Key. |
193193
| timeoutInSecs | Timeout to cancel the connection to server in seconds. Valid value is 0, 1, 2, ... ; default to 300 seconds. |
@@ -205,7 +205,7 @@ Creates a new instance of the `AmaasClient` class, and provisions essential sett
205205

206206
| Parameter | Description |
207207
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
208-
| region | The region you obtained your api key. Value provided must be one of the Vision One regions, e.g. `us-east-1`, `eu-central-1`, `ap-northeast-1`, `ap-southeast-2`, `ap-southeast-1`, `ap-south-1`, `me-central-1`,`eu-west-2`,`ca-central-1`,`af-south-1` ,etc. |
208+
| region | The region you obtained your api key. Value provided must be one of the Vision One regions, e.g. `us-east-1`, `eu-central-1`, `ap-northeast-1`, `ap-southeast-2`, `ap-southeast-1`, `ap-south-1`, `me-central-1`,`eu-west-2`,`ca-central-1`,`af-south-1`,`ap-southeast-3` ,etc. |
209209
| apikey | Your own Vision One API Key. |
210210
| timeoutInSecs | Timeout to cancel the connection to server in seconds. Valid value is 0, 1, 2, ... ; default to 300 seconds. |
211211

@@ -367,7 +367,7 @@ public class AMaasScanResultVerbose {
367367

368368
### `AMaasException`
369369

370-
The AMaasException class is the AMaaS SDK exception class.
370+
The AMaasException class is the AMaaS SDK exception class. Every checked error the SDK raises — whether detected locally or relayed from the gRPC server — is thrown as an `AMaasException` carrying an `AMaasErrorCode`. See [Error Handling](#error-handling) below for the full reference of what callers actually receive.
371371

372372
```java
373373
public final class AMaasException extends Exception {
@@ -381,19 +381,51 @@ public final class AMaasException extends Exception {
381381

382382
---
383383

384-
### `AMaasErrorCode`
384+
## Error Handling
385385

386-
AMaasErrorCode is a enum type containing all the error conditions thrown by the `AMaasException` class. The error conditions are as follows:
386+
Every checked error raised by the SDK is thrown as an `AMaasException`. Call `getErrorCode()` to get the associated `AMaasErrorCode` enum value, and `getMessage()` (inherited from `Exception`) to get the fully-formatted message text.
387387

388-
| Enum Type | Error Message Templates | Description |
389-
| ------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
390-
| MSG_ID_ERR_INVALID_REGION | %s is not a supported region. | The region code provided to the AMaasClient constructor is not a valid region. |
391-
| MSG_ID_ERR_MISSING_AUTH | Must provide an API key to use the client. | The API Key provided to the AMaasClient constructor cannot be empty or `null`. |
392-
| MSG_ID_ERR_KEY_AUTH_FAILED | You are not authenticated. Invalid C1 token or Api Key | The API key is invalid. Please make sure a correct Vision One Api key is used. |
393-
| MSG_ID_ERR_FILE_NOT_FOUND | Failed to open file. No such file or directory %s. | The given file cannot be found. Please make sure the file exists. |
394-
| MSG_ID_ERR_FILE_NO_PERMISSION | Failed to open file. Permission denied to open %s. | There is a file access permission issue. Please make sure the SDK has read permission to the file. |
395-
| MSG_ID_GRPC_ERROR | Received gRPC status code: %d, msg: %s. | gRpc error was reported with the status code. For details, please refer to published [gRPC Status Codes](https://grpc.github.io/grpc/core/md_doc_statuscodes.html) |
396-
| MSG_ID_ERR_UNEXPECTED_INTERRUPT | Unexpected interrupt encountered. | An unexpected interrupt signal was received at the client. |
388+
```java
389+
try {
390+
result = client.scanFile(fileName, tags);
391+
} catch (AMaasException e) {
392+
System.out.println("code: " + e.getErrorCode() + ", message: " + e.getMessage());
393+
}
394+
```
395+
396+
The **Source** column classifies each error:
397+
398+
- **SDK-native** — detected and formatted entirely on the client (bad region, missing key, file I/O, tag validation, TLS setup).
399+
- **SDK-mapped** — triggered by a gRPC response from the service, but the caller-visible message is produced by the SDK.
400+
- **Service** — a message produced by the service and relayed unchanged. **This SDK has no such rows** — it never forwards the service's message text, only the gRPC status code (see below).
401+
402+
For gRPC errors, the SDK only forwards the **numeric status code and the code's own name** (via [`io.grpc.Status.Code`](https://grpc.github.io/grpc/java/io/grpc/Status.Code.html)) — it does **not** forward the service's descriptive message text, except for `UNAUTHENTICATED`, where it substitutes a fixed message of its own. See note 1 below.
403+
404+
| AMaasErrorCode | Message returned to the caller | Cause | Source |
405+
|----------------|---------------------------------|-------|--------|
406+
| `MSG_ID_ERR_INVALID_REGION` | `<region> is not a supported region, region value should be one of <list>` | The `region` passed to the `AMaasClient` constructor is not a recognized Vision One region | SDK-native |
407+
| `MSG_ID_ERR_MISSING_AUTH` | `Must provide an API key to use the client.` | No API key was supplied to the `AMaasClient` constructor | SDK-native |
408+
| `MSG_ID_ERR_LOAD_SSL_CERT` | `Failed to load SSL certificate.` | The client's TLS trust material (default certificate, or the custom `caCertPath`) could not be loaded | SDK-native |
409+
| `MSG_ID_ERR_FILE_NOT_FOUND` | `Failed to open file. No such file or directory <path>.` | The file passed to `scanFile()` / `AMaasFileReader` does not exist, or could not be opened | SDK-native |
410+
| `MSG_ID_ERR_FILE_NO_PERMISSION` | `Failed to open file. Permission denied to open <path>.` | The SDK process does not have read permission on the file | SDK-native |
411+
| `MSG_ID_ERR_MAX_NUMBER_OF_TAGS` | `Exceeded maximum number of tags: 8` | More than 8 tags were passed to `scanFile()` / `scanBuffer()` / `scanRun()` | SDK-native |
412+
| `MSG_ID_ERR_LENGTH_OF_TAG` | `Tag length must be between 1 and 63: <tag>.` | A tag is `null`, empty, or longer than 63 characters | SDK-native |
413+
| `MSG_ID_ERR_UNEXPECTED_INTERRUPT` | `Unexpected interrupt encountered.` | The calling thread was interrupted while waiting for the scan to finish | SDK-native |
414+
| `MSG_ID_ERR_KEY_AUTH_FAILED` | `Authorization key cannot be authenticated.` | The service returned gRPC `UNAUTHENTICATED` (16) — no/invalid API key, or (per the service) the account lacks file-scan permission. The SDK always substitutes this one message for `UNAUTHENTICATED`; the service's more specific reason is not exposed to the caller. | SDK-mapped |
415+
| `MSG_ID_GRPC_ERROR` | `Received gRPC status code: 3, msg: INVALID_ARGUMENT.` | Service reported `INVALID_ARGUMENT` (3) — too many tags, a tag too long or empty, illegal characters in `cloudAccountId`, or a malformed SHA1/SHA256 computed by the SDK | SDK-mapped |
416+
| `MSG_ID_GRPC_ERROR` | `Received gRPC status code: 5, msg: NOT_FOUND.` | Service reported `NOT_FOUND` (5) — customer ID not found | SDK-mapped |
417+
| `MSG_ID_GRPC_ERROR` | `Received gRPC status code: 7, msg: PERMISSION_DENIED.` | Service reported `PERMISSION_DENIED` (7) — the SDK feature is not enabled for the account | SDK-mapped |
418+
| `MSG_ID_GRPC_ERROR` | `Received gRPC status code: 8, msg: RESOURCE_EXHAUSTED.` | Service reported `RESOURCE_EXHAUSTED` (8) — hourly scan quota exceeded, file exceeds the maximum allowed size, or scan resource could not be allocated | SDK-mapped |
419+
| `MSG_ID_GRPC_ERROR` | `Received gRPC status code: 9, msg: FAILED_PRECONDITION.` | Service reported `FAILED_PRECONDITION` (9) — incorrect protocol stage reported by the SDK | SDK-mapped |
420+
| `MSG_ID_GRPC_ERROR` | `Received gRPC status code: 12, msg: UNIMPLEMENTED.` | Service reported `UNIMPLEMENTED` (12) — Predictive Machine Learning (PML) requested but not supported | SDK-mapped |
421+
| `MSG_ID_GRPC_ERROR` | `Received gRPC status code: 13, msg: INTERNAL.` | Service reported `INTERNAL` (13) — metadata retrieval failure, network connection error, generic internal error, missing preamble information, or unclear scan result | SDK-mapped |
422+
423+
**Notes**
424+
425+
1. For `MSG_ID_GRPC_ERROR`, the caller sees only the gRPC status code's number and its symbolic name (e.g. `INTERNAL`), **not** the service's descriptive text. Because several distinct service-side conditions share one gRPC code (the Cause column lists the known ones), they are indistinguishable from the exception message alone. Those service strings are not exposed through the Java SDK.
426+
2. Service-side conditions and their code assignments are owned by the File Security service and may change independently of the SDK; this table reflects the catalog current at the time of writing.
427+
3. Engine findings such as `ATSE_*` codes are **not** errors — they are returned inside the scan result payload (see [Sample JSON Response](#sample-json-response)), not as a gRPC status.
428+
4. `MSG_ID_ERR_UNEXPECTED` is defined on `AMaasErrorCode` but is not currently thrown anywhere in the SDK; it is reserved for future use.
397429

398430
## Thread Safety
399431

‎VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.6.3
1+
1.6.4

‎examples/pom.xml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@
5858
<groupId>io.grpc</groupId>
5959
<artifactId>grpc-netty</artifactId>
6060
<version>1.73.0</version>
61+
<exclusions>
62+
<exclusion>
63+
<groupId>io.netty</groupId>
64+
<artifactId>*</artifactId>
65+
</exclusion>
66+
</exclusions>
67+
</dependency>
68+
<dependency>
69+
<groupId>io.netty</groupId>
70+
<artifactId>netty-all</artifactId>
71+
<version>4.2.15.Final</version>
6172
</dependency>
6273
<dependency>
6374
<groupId>com.trend</groupId>

‎examples/s3stream/S3Stream.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public long getLength() {
9999
* @throws IOException if read fails
100100
*/
101101
@Override
102-
public int readBytes(final int offset, final byte[] buff) throws IOException {
102+
public int readBytes(final long offset, final byte[] buff) throws IOException {
103103
final ByteBuffer byteBuffer = ByteBuffer.wrap(buff);
104104
return readByteRange(offset, byteBuffer);
105105
}

‎pom.xml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.trend</groupId>
88
<artifactId>file-security-java-sdk</artifactId>
9-
<version>1.6.3</version>
9+
<version>1.6.4</version>
1010

1111
<name>file-security-java-sdk</name>
1212
<url>https://github.com/trendmicro/tm-v1-fs-java-sdk</url>
@@ -96,7 +96,7 @@
9696
<dependency>
9797
<groupId>io.netty</groupId>
9898
<artifactId>netty-all</artifactId>
99-
<version>4.2.9.Final</version>
99+
<version>4.2.15.Final</version>
100100
</dependency>
101101
<dependency>
102102
<groupId>io.grpc</groupId>

‎protos/scan.proto‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ message C2S {
2222
Stage stage = 1;
2323
string file_name = 2;
2424
uint64 rs_size = 3;
25-
int32 offset = 4;
25+
int64 offset = 4;
2626
bytes chunk = 5;
2727
bool trendx = 6;
2828
string file_sha1 = 7;
@@ -42,10 +42,10 @@ enum Command {
4242
message S2C {
4343
Stage stage = 1;
4444
Command cmd = 2;
45-
int32 offset = 3;
45+
int64 offset = 3;
4646
int32 length = 4;
4747
string result = 5;
48-
repeated int32 bulk_offset = 6;
48+
repeated int64 bulk_offset = 6;
4949
repeated int32 bulk_length = 7;
5050
string session_id = 8;
5151
}

‎src/main/java/com/trend/cloudone/amaas/AMaasBufferReader.java‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,20 @@ public String getIdentifier() {
3535
return this.identifier;
3636
}
3737

38-
public int readBytes(final int offset, final byte[] buf) throws IOException {
38+
public int readBytes(final long offset, final byte[] buf) throws IOException {
39+
// The in-memory buffer is backed by a Java array, which is indexed by int, so a buffer larger than Integer.MAX_VALUE bytes (~2GiB)
40+
// is not representable here. Casting to int is safe for this implementation; only the on-disk file reader (AMaasFileReader) needs
41+
// the full long range. In normal operation the scan engine never requests an offset beyond the declared buffer length,
42+
// so offset always fits in int.
43+
if (offset < 0 || offset > this.readerBuf.length) {
44+
throw new IOException("offset out of range for buffer reader: " + offset + " (buffer length " + this.readerBuf.length + ")");
45+
}
46+
int intOffset = (int) offset;
3947
int chunkLength = buf.length;
40-
if (chunkLength + offset > this.readerBuf.length) {
41-
chunkLength = this.readerBuf.length - offset;
48+
if (chunkLength + intOffset > this.readerBuf.length) {
49+
chunkLength = this.readerBuf.length - intOffset;
4250
}
43-
System.arraycopy(readerBuf, offset, buf, 0, chunkLength);
51+
System.arraycopy(readerBuf, intOffset, buf, 0, chunkLength);
4452
return chunkLength;
4553
}
4654
}

‎src/main/java/com/trend/cloudone/amaas/AMaasClient.java‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ public void onNext(final ScanOuterClass.S2C s2cMsg) {
422422
return;
423423
}
424424
java.util.List<java.lang.Integer> bulkLength;
425-
java.util.List<java.lang.Integer> bulkOffset;
425+
java.util.List<java.lang.Long> bulkOffset;
426426
if (this.bulk) {
427427
log(Level.FINE, "enter bulk mode");
428428
int bulkCount = s2cMsg.getBulkLengthCount();
@@ -433,17 +433,17 @@ public void onNext(final ScanOuterClass.S2C s2cMsg) {
433433
bulkOffset = s2cMsg.getBulkOffsetList();
434434
} else {
435435
bulkLength = Arrays.asList(new Integer[]{s2cMsg.getLength()});
436-
bulkOffset = Arrays.asList(new Integer[]{s2cMsg.getOffset()});
436+
bulkOffset = Arrays.asList(new Long[]{s2cMsg.getOffset()});
437437
}
438438
for (int i = 0; i < bulkLength.size(); i++) {
439-
log(Level.INFO, "Bulk read length={0} at offset={1}", bulkLength.get(i).intValue(), bulkOffset.get(i).intValue());
439+
log(Level.INFO, "Bulk read length={0} at offset={1}", bulkLength.get(i).intValue(), bulkOffset.get(i).longValue());
440440
byte[] bytes = new byte[bulkLength.get(i).intValue()];
441441
try {
442-
int rtnLength = reader.readBytes(bulkOffset.get(i).intValue(), bytes);
442+
int rtnLength = reader.readBytes(bulkOffset.get(i).longValue(), bytes);
443443
ByteString bytestr = ByteString.copyFrom(bytes);
444444
this.fetchCount++;
445445
this.fetchSize += rtnLength;
446-
ScanOuterClass.C2S request = ScanOuterClass.C2S.newBuilder().setStage(Stage.STAGE_RUN).setChunk(bytestr).setOffset(bulkOffset.get(i).intValue()).build();
446+
ScanOuterClass.C2S request = ScanOuterClass.C2S.newBuilder().setStage(Stage.STAGE_RUN).setChunk(bytestr).setOffset(bulkOffset.get(i).longValue()).build();
447447

448448
while (!callObserver.isReady()) {
449449
try {

‎src/main/java/com/trend/cloudone/amaas/AMaasFileReader.java‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,13 @@ public long getLength() {
7575
return this.fileSize;
7676
}
7777

78-
public int readBytes(final int offset, final byte[] buff) throws IOException {
78+
public int readBytes(final long offset, final byte[] buff) throws IOException {
79+
// RandomAccessFile.seek already rejects a negative offset and reads past EOF return -1, so this check is not
80+
// strictly required for safety. It is kept for fail-fast symmetry with AMaasBufferReader and to surface a
81+
// clearer message if the scan engine ever requests an offset outside the declared file size.
82+
if (offset < 0 || offset > this.fileSize) {
83+
throw new IOException("offset out of range for file reader: " + offset + " (file size " + this.fileSize + ")");
84+
}
7985
this.randomFile.seek(offset);
8086
return this.randomFile.read(buff);
8187
}

0 commit comments

Comments
 (0)