Bug Report: Incorrect Conversion of Numeric Strings to JSON in RouterOS

Hello Mikrotik Support Team,

I am an official Mikrotik trainer, and I would like to report a bug related to the conversion of data structures to JSON in RouterOS.

Issue Description
When using the :serialize command to convert data structures to JSON in RouterOS, values that are originally strings containing numeric data (especially those starting with zero) are being incorrectly converted to float types. This results in the loss of information and alters the original data.

For instance, when extracting the system identity name configured as 0123, the conversion to JSON changes the value to 123.000000, removing the leading zero and changing the data type from string to float. This behavior is problematic as it alters the semantics of the data and can cause issues in integrations that rely on the accuracy and preservation of the original data type.

Steps to Reproduce
Set the device identity name to a numeric value starting with zero, such as 0123:

/system identity set name=0123
Retrieve the value using the command:

:put [/system/identity/get]
Convert the value to JSON using:

:put [:serialize value=[/system/identity/get] to=json];
Observe that the converted JSON value is altered to:

{“name”:123.000000}
Expected Behavior
The original data type should be preserved in the JSON conversion. Strings containing numeric values should remain as strings in JSON, without removing leading zeros or converting them to floats. The expected output in this case should be {“name”:“0123”}.

Environment
RouterOS Version: 7.16rc5
Device Model: CRS125-24G-1S-2HnD
Impact
This issue affects data integrity when using JSON for extraction or integration with other systems, particularly in cases where values such as PPP account names or identifiers with leading zeros are common.

Thank you for your attention to this matter. Please let me know if you need any additional information.

Best regards,


Ademir Vida

You are an official trainer (but your 5 minutes only 1-post-account says no…) and you don’t know that bugs should be reported to support, not (only) on the user forum???


The best part on the post, and probably the only reason the post was written.

Anyway, what is written is wrong, and then it should have been tested on 7.16 that has already been released.

Correct text:
Anything that looks like a number, written inside a string, is exported as a number.
Anything that looks like a (part of) IPv4, written inside a string, is exported as a full IPv4.

But the error is NOT only on serialize, is generic error on how RouterOS work…
[admin@1.1] /system/identity> export

2024-09-26 11:47:49 by RouterOS 7.16

software id =

/system identity
set name=1.1

[admin@1.1] /system/identity> :put [:typeof [get name]]
str

[admin@1.1] /system/identity> :put [:typeof [get]]
array

[admin@1.1] > :put [/system/identity/get]
name=1.1

[admin@1.1] > :put [:typeof ([/system/identity/get]->“name”)]
str

[admin@1.1] > :put [:serialize value=[/system/identity/get] to=json];
{“name”:1.100000}
So, is OBVIOUS and CORRECT that name=1.1 is converted into one number…

[admin@1.1] > :put [:typeof ({name=“70”}->“name”)]
str
[admin@1.1] > :put [:typeof ({name=70}->“name”)]
num
[admin@1.1] > :put [:serialize value={name=“70”} to=json];
{“name”:70.000000}
[admin@1.1] > :put [:serialize value={name=70} to=json];
{“name”:70}

[admin@1.1] > :put [:typeof ({name=“70.1”}->“name”)]
str
[admin@1.1] > :put [:typeof ({name=70.1}->“name”)]
ip
[admin@1.1] > :put [:serialize value={name=“70.1”} to=json];
{“name”:70.100000}
[admin@1.1] > :put [:serialize value={name=70.1} to=json];
{“name”:“70.0.0.1”}

Thank you for your feedback. I understand that RouterOS currently performs this automatic conversion, but my concern is about preserving data integrity during serialization to JSON. Converting numeric strings into numbers can lead to the loss of important information, such as leading zeros, which are critical in many cases. I believe it would be beneficial for the community if RouterOS maintained the original data types when serializing to JSON, in accordance with the format’s specifications.

[admin@1.1] > :put [:typeof ({name="70"}->"name")]
str
[admin@1.1] > :put [:serialize value={name="70.1"} to=json];
{"name":70.100000}

What is going on here? It appears to be an implicit type conversion from a string to a number, there is probably some rational reason for it being that way, thought it breaks expectations.

Fortunately there appears to be “json.no-string-conversion” in the documentations for RouterOS for “serialize” - however my system is missing it. It would be helpful for communicating with JSON api where a string is expected regardless of if it happens to be a number.
I’m running firmware 7.16.1.

Do you happen to know how to get this feature?

Probably is on beta, nothing on changelog.

I opened a ticket a while back on a related issue*… they did say they were going to add the no-string-conversion option, and also said it’s not released yet… but did get impression it’s in the pipeline to be some future build in an update late last month.


* Similar oddness with :serialize when a str had a leading 0… but from the ticket I learned “convert to float” for JSON is a feature, not a bug - BUT they were still working on the side-effects of that… why the new un-released / planned option.

:global zero6str "0000000"    
:put "$zero6str $[:typeof $zero6str]"
# 0000000 str
:put [:serialize to=json $zero6str]
# 0.000000

(and was a difficult bug to find since it was part of script for ZT, which I thought it was ZT API doing something wrong… but it was the float: http://forum.mikrotik.com/t/howto-import-zerotier-members-into-mikrotik-dns-using-zt2dns/173937/1)