This is an automated email from the ASF dual-hosted git repository.
pandalee pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new dc527314c fix(go): fix type writing and reading logic in slice (#2427)
dc527314c is described below
commit dc527314cd076f9ed579ea36b711c94277917a8f
Author: lzaeh <[email protected]>
AuthorDate: Fri Jul 18 23:34:38 2025 +0800
fix(go): fix type writing and reading logic in slice (#2427)
<!--
**Thanks for contributing to Fory.**
**If this is your first time opening a PR on fory, you can refer to
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).**
Contribution Checklist
- The **Apache Fory (incubating)** community has restrictions on the
naming of pr titles. You can also find instructions in
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).
- Fory has a strong focus on performance. If the PR you submit will have
an impact on performance, please benchmark it first and provide the
benchmark result here.
-->
## What does this PR do?
<!-- Describe the purpose of this PR. -->
This PR investigates and fixes the issue described in #2423.
- In the slice serializer, the type marker should be written and read
using the correct functions, instead of using typeId directly.
Otherwise, struct types may lose type information during serialization.
- A test case from issue #2423 has been added to the language-specific
test suite.
In PR #2339 , the dynamic type ID allocation mechanism was temporarily
removed to improve cross-language compatibility. However, as mentioned
in both that PR and this one, the following problems still remain:
- If the slice in issue #2423 is replaced with an array, the issue still
exists. The original case (a slice) is already fixed in this PR.
- If the slice element type is changed to a concrete map type, the issue
also persists.
- As noted in PR #2339, arrays and slices still have potential problems
that can cause issues in cross-language deserialization.
I'm currently working on fixing the above issues in my spare time.
Apologies for the delay.
## Related issues
close #2423
<!--
Is there any related issue? Please attach here.
- #xxxx0
- #xxxx1
- #xxxx2
-->
## Does this PR introduce any user-facing change?
<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/fory/issues/new/choose) describing the
need to do so and update the document if necessary.
-->
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
<!--
When the PR has an impact on performance (if you don't know whether the
PR will have an impact on performance, you can submit the PR first, and
if it will have impact on performance, the code reviewer will explain
it), be sure to attach a benchmark data here.
-->
---
go/fory/fory_test.go | 29 +++++++++++++++++++++++++++++
go/fory/slice.go | 6 ++----
2 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/go/fory/fory_test.go b/go/fory/fory_test.go
index 78fecbfcc..cf1fdfb73 100644
--- a/go/fory/fory_test.go
+++ b/go/fory/fory_test.go
@@ -627,6 +627,35 @@ func TestSliceEachIndividually(t *testing.T) {
}
}
+// Test Fory's serialization and deserialization of a struct with a slice of
nested structs.
+func TestStructWithNestedSlice(t *testing.T) {
+ type Item struct {
+ Name string
+ }
+
+ type Example struct {
+ Items []Item
+ }
+
+ fory := NewFory(true)
+ if err := fory.RegisterTagType("Example", Example{}); err != nil {
+ panic(err)
+ }
+ if err := fory.RegisterTagType("Item", Item{}); err != nil {
+ panic(err)
+ }
+
+ example := &Example{Items: []Item{
+ {Name: "test"},
+ }}
+ bytes, _ := fory.Marshal(example)
+ var deserialized2 interface{}
+ if err := fory.Unmarshal(bytes, &deserialized2); err != nil {
+ panic(err)
+ }
+ require.Equal(t, deserialized2, example)
+}
+
func convertRecursively(newVal, tmplVal reflect.Value) (reflect.Value, error) {
// Unwrap any interface{}
if newVal.Kind() == reflect.Interface && !newVal.IsNil() {
diff --git a/go/fory/slice.go b/go/fory/slice.go
index 3127b0824..ccd9d4b11 100644
--- a/go/fory/slice.go
+++ b/go/fory/slice.go
@@ -184,7 +184,7 @@ func (s sliceSerializer) writeDifferentTypes(f *Fory, buf
*ByteBuffer, value ref
// Get and write type info for each element (since types vary)
typeInfo, _ := f.typeResolver.getTypeInfo(elem, true)
- buf.WriteVarInt32(typeInfo.TypeID)
+ f.typeResolver.writeTypeInfo(buf, typeInfo)
// When writing the actual value, detect if elem is an array
and convert it
// to the corresponding slice type so the existing slice
serializer can be reused
if elem.Kind() == reflect.Array {
@@ -288,9 +288,7 @@ func (s sliceSerializer) readDifferentTypes(f *Fory, buf
*ByteBuffer, value refl
continue
}
- // Read type ID for each element (since types vary)
- typeID := buf.ReadVarUint32()
- typeInfo, _ := f.typeResolver.getTypeInfoById(int16(typeID))
+ typeInfo, _ := f.typeResolver.readTypeInfo(buf)
// Create new element and deserialize from buffer
elem := reflect.New(typeInfo.Type).Elem()
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]