-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
json: Improve tolerance to uncovered C members during JSON encoding #53333
json: Improve tolerance to uncovered C members during JSON encoding #53333
Conversation
@mrfuchs can you please take a look? |
@mrfuchs could you please take a look? Thanks! |
@M1cha can you take a look? |
tests/lib/json/src/main.c
Outdated
struct obj_array_array obj_array_array_ts; | ||
|
||
ZTEST(lib_json_test, test_json_decoding_array_array) | ||
{ | ||
int ret; | ||
struct obj_array_array obj_array_array_ts; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this change doesn't look necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, reverted that
include/zephyr/data/json.h
Outdated
@@ -137,6 +138,9 @@ typedef int (*json_append_bytes_t)(const char *bytes, size_t len, | |||
__alignof__(type) == 2 ? 1 : \ | |||
__alignof__(type) == 4 ? 2 : 3) | |||
|
|||
/* Helper to get the size of a member within a struct. */ | |||
#define Z_MEMBER_SIZE(type, member) sizeof(((type *)0)->member) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given how often I needed this in other zephyr projects I'd say it's finally time to add this to include/zephyr/sys/util.h
with the name SIZEOF_FIELD
(that's what the linux kernel calls this, just lowercase).
include/zephyr/data/json.h
Outdated
size_t sub_descr_len; | ||
uint16_t sub_descr_len; | ||
uint16_t sub_struct_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the reason for the type change and why did you choose uint16_t
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the change to add a new field "sub_struct_size" without increasing the size of the structure
I made the hypothesis that a 16-bit unsigned integer would be sufficient to represent the values needed for these fields.
Should I use two size_t
instead ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer not to touch sub_descr_len
and thus keep it as size_t
.
However, I'm wondering if this (unnamed) union is even the right place to add the struct size as it is primarily used to describe the descriptor (not the actual object). Couldn't we move the struct size outside of the union?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reverted the type for sub_descr_len
to size_t
.
I do agree, I moved the field sub_struct_size
up and renamed it to struct_size
. It just required a little more work to have all descriptors defined correctly: I needed to explicitly define the struct_size
member to an arbitrary value (e.g. 0).
058d937
to
5b486cf
Compare
5b486cf
to
de6b69c
Compare
@mrfuchs please take a look |
include/zephyr/data/json.h
Outdated
size_t sub_descr_len; | ||
uint16_t sub_descr_len; | ||
uint16_t sub_struct_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer not to touch sub_descr_len
and thus keep it as size_t
.
However, I'm wondering if this (unnamed) union is even the right place to add the struct size as it is primarily used to describe the descriptor (not the actual object). Couldn't we move the struct size outside of the union?
lib/os/json.c
Outdated
} else { | ||
field = (char *)field + elem_descr->offset; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When the field
pointer is updated and skipped over a (unused?) field, shouldn't the last_elem
variable also be updated?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this new design get_elem_size()
returns the actual size of the underlying object, so last_elem
correctly reflects the address of the last element.
However I'm still not convinced the way field
is adjusted when parsing the nested array (when parsing an array of array).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However I'm still not convinced the way
field
is adjusted when parsing the nested array (when parsing an array of array).
Indeed. I hope that'll be fixed soon by #50816.
de6b69c
to
4520699
Compare
Did several modifications, but I still need to do additional testing. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
The |
@lucasdietrich care to update the PR for the latest comments, thanks The tests in my PR #59485 succeed using this one. |
Thank you for your review, I will make the changes this evening. |
16b2f34
to
d37204c
Compare
@lucasdietrich #50816 has been merged, please rebase and resolve conflicts, thanks! |
Ok, i will rebase this evening. |
Unfortunately I didn't have time to work on it yet, moreover the merge seems to be tricky. |
@lucasdietrich any update on this? |
After more investigation, I managed to get almost everything working except for the test "test_json_decoding_array_array", which has become a blocker for me. I've somewhat lost track of the issue, but I can redirect my attention to it by tomorrow evening. However, I might require some help to resolve it completely. |
d37204c
to
1008bf9
Compare
I managed to get almost everything working; we don't "guess" anymore the size of a structure but we compute it at build time and we use this to determine offsets. The most tricky part was (and still is) the handling of nested arrays (array of arrays), which requires dedicated handling I'm not able to fully explain. To be honest I tried to have the unit tests working rather than designing an accurate solution for nested arrays. This is where I would greatly benefit from external insight. Consequently this has left the following key issue unresolved : Yet, the member of the structure describing the nested array should remain at the start of the structure. Using the "test_json_encoding_array_array" test as example: I'm not yet able to calculate the correct offset of "objects" within the "struct array". Consequently the test fails (crashes) if we uncomment the line. Actually I don't fully understand when the adjustment should be made. To conclude, I've successfully tested these commits with a personnal project. |
cf38367
to
5b088a1
Compare
I've just rebased and noticed that the new tests introduced in #60046 are failing with the current changes(2 dim array encoding). I'll need more time to address this issue. |
This macro is used to get the size of a specific field in a structure type. It will return the size of the field in bytes. Signed-off-by: Lucas Dietrich <[email protected]>
Enable the computation of a struct member's size during compile-time to enhance accuracy, removing the need for speculative size determinations during runtime. Signed-off-by: Lucas Dietrich <[email protected]>
Add special handling for nested arrays This enhancement fix encoding of JSON objects for which descriptors do not covers all members of the C structure represented. Fixes zephyrproject-rtos#50976 Signed-off-by: Lucas Dietrich <[email protected]>
This commit updates various structs in the JSON test suite to include unused members. These additions aim to test the improved tolerance of JSON encoding for C struct members that may not be fully described by JSON descriptors. As a consequence of the addition of unused fields, prefer designated initializers instead of postionnal ones. Add a note about a test which constantly fails with a unused field. Signed-off-by: Lucas Dietrich <[email protected]>
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
This enhancement fixes encoding of JSON objects for which descriptors do not covers all members of the C structure represented.
Fix #50976
Signed-off-by: Lucas Dietrich [email protected]