Closed gt74745 closed 1 month ago
@dlmiles : The syntax change in DRCtech.c line 829 from
char *locargv[2][10] = {"style", "default};
to
char *locargv[2][10] = {{"style"}, {"default"}};
is causing this segfault. What is the solution that both has the correct behavior and does not produce compiler warnings?
I think the answer is that the original declaration was wrong although I'm not sure why it used to compile correctly. It should have been
char *locargv[2] = {"style", "default"};
and should not have a second array bound. The second array bound was being ignored (probably just wasting memory), but when the double brace was added, it became incorrect when passed to DRCTechLine
which was expecting char *argv[]
. I have a fix and will push it now.
@gt74745 : This has been fixed on opencircuitdesign.com and will update on github if I force a mirror by end of day today; otherwise, it will update automatically overnight. Thank you for the bug report.
The issue is the incorrect use of *
let me attach test case to demonstrate. More fully
char locargv[2][10] = {{"style"}, {"default"}}; // note the '*' is removed, these are not pointers
the idiom char [2][10]
reads, like it is wanting to perform the equivalent of:
char locargv[2][10];
strcpy(&locargv[0], "style");
strcpy(&locargv[1], "default");
// This allows the passing is writable-strings to the API call
Just checking other changes for this pattern.
@dlmiles: But this works too, and is as far as I know syntactically "correct":
char *locargv[2] = {"style", "default"};
I do not expect that other changes would have caused an error; the error was in the original declaration which specified an array of one more dimension than needed, and the tools analyzing the code tried to fix the value instead of the declaration, not knowing any better. Which I guess validates the strict syntax checking. : )
Yes that can work as well (inferred array size of const char *
) but this will not pass writable-strings to the API. Given the timescale / history of the codebase, I would assume the API needs writable-strings. If original code is written in that way, to copy from constant/rodata into writable data on the stack. The original buffer was meant to be 20 bytes.
Okay, you've convinced me that a fixed array + strcpy( ) is the safer way to go.
I think just removing the *
from my commit, but no hurry if you have a fix for overnight, will attach testcase shortly to documented. As in char locargv[2][10] = {{"style"}, {"default"}};
will work as intended, but will know after a little more investigation.
I'm pretty sure that was the first thing I tried and it didn't work.
It is a recursive function call. So easy to audit if it requires writable strings, it will StrDup() when needed in some places to store data but has: https://github.com/RTimothyEdwards/magic/blob/master/drc/DRCtech.c#L745 https://github.com/RTimothyEdwards/magic/blob/master/drc/DRCtech.c#L803 https://github.com/RTimothyEdwards/magic/blob/master/drc/DRCtech.c#L895 https://github.com/RTimothyEdwards/magic/blob/master/drc/DRCtech.c#L897 that looks like it could write into the argv[] strings if these lines are triggered (needing writable-strings to be passed).
so the smallest and quickest to audit solution looks like:
char bufargv[2][10];
strcpy(bufargv[0], "style");
strcpy(bufargv[1], "default");
char *locargv[2];
locargv[0] = bufargv[0];
locargv[1] = bufargv[1];
if (DRCTechLine(sectionName, 2, locargv) == FALSE)
return FALSE;
Note the 2 phases, the preparation of a writable strings buffer, then the preparation of the argv[] pointers, to have the correct layout for the function call.
Testcase file to help confirming.
I'm pretty sure that was the first thing I tried and it didn't work.
Probably because it did the writable-string buffer preparation part ok, but it doesn't provide the correct pointer layout as the function expects.
I believe the original code passed in the correct layout, with pointers to read-only/constant strings and did not trigger the 4 lines of code I link to in previous comment.
I have adopted your final recommendation and committed the code.
This fix works on my system. Thanks for the prompt response, guys! :)
Using either magic 8.3.496 from the OCD website, or this repo, I'm unable to load any tech files.
Here's my console output:
And trying to load the techfile at run exits immediately:
Trying to load a techfile in the gui produces this message:
All of these problems persist no matter which tech file I try to use.