-
Notifications
You must be signed in to change notification settings - Fork 13
Description
I'm not sure if this is the right place to ask this question since it affects multiple implementations, including this. I cross-posted to the uap-core project but sharing here just in case it is a bug with the specific implementation.
Background
There are certain user-agents where it is not possible to derive or infer the device family, brand or model from the user-agent alone.
In our application, we want to explicitly distinguish between user-agents we recognise but we don't know of the device family (which we want to output as an empty string), and user-agents we don't recognise (fallback to the "Other" value as defined in the specification).
We've observed a difference between the uap-ref-impl Javascript and uap-csharp C# implementations of ua-parser.
Even though the Javascript is described as the "reference" implementation, we're not sure if this is a bug or the intention of the specification since it is vague about how to handle a replacement value that is an empty string "".
The specification writes,
In case that no replacement for a match is given, the first match defines the family and the model. If a *_replacement string is specified it shall overwrite or replace the match.
One could interpret "no replacement" to mean either
undefinedornullundefinedornullor empty string
Repro
The regex YAML is defined as
device_parsers:
- regex: '(radiocomandroid)'
brand_replacement: ''
device_replacement: ''
model_replacement: ''
Testing with the user-agent string of radiocomandroid
The Javascript implementation outputs
{
"family": "radiocomandroid",
"brand": null,
"model": "radiocomandroid"
}
The C# implementation outputs
{
"IsSpider": false,
"Brand": "",
"Family": "",
"Model": ""
}
Side-by-side
| Javascript | .NET | |
|---|---|---|
| Device family | "radiocomandroid" |
"" |
| Device brand | null |
"" |
| Device model | "radiocomandroid" |
"" |
Question
The JavaScript implementation uses a conditional (ternary) operator which will treat an empty string "" as false, which means it will fallback to the first match value.
Line 24 in f038cf5
| family: (deviceRep ? replaceMatches(deviceRep, m) : m[1]) || 'Other', |
The C# implementation uses a == null condition which will use an empty string "" as the final value.
https://github.com/ua-parser/uap-csharp/blob/master/UAParser/UAParser.cs#L523
Which of these implementations is the intent of the specification? Is an empty string considered "no replacement"?