paramFile.c byte-swaps through unions (strict-aliasing UB): arParamLoad() returns garbage distortion with GCC -O3
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 57/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- backend, performance
Research direction
Start with lib/SRC/AR/paramFile.c, read byteSwapDouble(), byteSwapInt(), and byteswap(), then reproduce the reported arParamLoad() result with GCC at -O3. Check that the byte-swapped dist_factor values match the camera file; the report also identifies an MSVC numeric_limits<int>::max() issue in ARToolKitNFTCore::setup(), so check that expression and its Windows build behavior too.
Written by the indexing model from the issue text.
Description
What happens
lib/SRC/AR/paramFile.c byte-swaps the camera parameters through pointers to unions:
static void byteSwapDouble( const double *from, double *to )
{
SwapDoubleT *w1, *w2;
...
w1 = (SwapDoubleT *)from;
w2 = (SwapDoubleT *)to;
for( i = 0; i < 8; i++ ) {
w2->y[i] = w1->y[7-i];
}
}
byteSwapInt() does the same with SwapIntT. Accessing a double or an int object through a pointer to a union type breaks C's strict-aliasing rule.
GCC 13 at -O3 vectorises the dist_factor loop of byteswap(). arParamLoad() then returns garbage distortion factors (around 1e-310) instead of the file's values, while mat is right. AR2 projects the features with that distortion, and the NFT tracking loses every marker right after KPM finds it: ar2TrackingMod returns -3.
Evidence
From webarkit/jsartoolkitNFT#693, Ubuntu 24.04, gcc 13.3:
- a small program that calls
arParamLoad("camera_para.dat")and printsdist_factorgives the right values at-O2and garbage at-O3; - at
-O3, adding-fno-strict-aliasing, or disabling vectorisation (-fno-tree-loop-vectorize -fno-tree-slp-vectorize), gives the right values again; - the jsartoolkitNFT Python bindings were built at
-O3on Linux, which is the level of the Pythons fromactions/setup-python, and lost every marker. Bisecting with per-file-O2pointed toparamFile.calone.
Emscripten (clang) and MSVC builds are not affected.
Suggested fix
Swap through unsigned char pointers, which may alias any object:
static void byteSwapDouble( const double *from, double *to )
{
const unsigned char *f = (const unsigned char *)from;
unsigned char *t = (unsigned char *)to;
int i;
for( i = 0; i < 8; i++ ) t[i] = f[7-i];
}
Apply the same change to byteSwapInt(), and to the commented-out byteSwapFloat(). Then drop the three Swap*T unions. A native test that loads camera_para.dat and checks a known dist_factor value, built at -O3, would catch a regression.
A second, smaller item: MSVC and std::numeric_limits<int>::max()
ARToolKitNFTCore::setup() uses std::numeric_limits<int>::max(). On Windows, <AR/config.h> includes <windows.h>, whose max macro breaks that expression (error C2589) unless NOMINMAX is defined. Writing it as (std::numeric_limits<int>::max)() makes it compile either way.
jsartoolkitNFT's Python build currently works around both problems: -fno-strict-aliasing for paramFile.c, and NOMINMAX on Windows.
- Dominant language
- C++
- Stars
- 21
- Forks
- 8
- Avg merge
- 7h 30m
- Merged PRs (30d)
- 25
Getting set up
- No Dockerfile or Docker Compose file
- No pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from webarkit/WebARKitLib
-
Sync workflow: handle a conflicting sync branch with no open PR, and PRs the workflow did not openOpenCI enhancement
Difficulty 3/5 Half a day Newbie friendliness 45/100
webarkit/WebARKitLib#92 ·
Maintainers usually reply within 1 day
-
Optical tracker: frames without a marker run detection twice since the #53 full-resolution retryOpenC/C++ code enhancement
Difficulty 4/5 3-5 days Newbie friendliness 35/100
webarkit/WebARKitLib#91 ·
Maintainers usually reply within 1 day
-
C/C++ code enhancement
Difficulty 4/5 3-5 days Newbie friendliness 25/100
webarkit/WebARKitLib#87 ·
Maintainers usually reply within 1 day
-
Real-world pose scale from a physical marker width at init (ArtoolkitX-style), not the _pattern.size/2 pixel centre offsetMay be free again @kalwalt claimed this 105 days ago, and no pull request is open. Openenhancement question
webarkit/WebARKitLib#62 · 1 assignee ·
Maintainers usually reply within 1 day
-
Difficulty 5/5 Over a week Newbie friendliness 20/100
webarkit/WebARKitLib#48 ·
Maintainers usually reply within 1 day
All issues in webarkit/WebARKitLib
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 83/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
-
[BUG] Clipboard History: Buffer over-read in WideCharToMultiByte on double-click pastePossibly taken @softmgr claimed this today. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
notepad-plus-plus/notepad-plus-plus#18519 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
justcallmekoko/ESP32Marauder#1635 ·
Maintainers usually reply within 1 day
-
3.7.6-dev commit 80481ea - files not centered when resolution differs and zoom = "pixel-to-pixel"Open
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
grizzlypeak3d/DJV#931 ·