iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Roman Huang’s audit of a local C campus-tour program reports 13 issues, led by a simple control-flow flaw: the login function can reject a password, but the caller ignores its result and opens the manager panel anyway. Huang describes a console application, not a networked service; the findings are the author’s account, not an independent security review.
What the C project does
Huang describes a console-based campus tour guide with no graphical interface or networking. It represents 12 campus locations as vertices in a weighted, undirected graph. The program stores the graph in an adjacency matrix, computes all-pairs shortest paths at startup with Floyd–Warshall, and uses depth-first search (DFS) to find paths between two locations. Huang reports 13 issues in the project.
How the login check can be bypassed
The central issue is not that the login routine necessarily accepts an incorrect password. As Huang describes it, Login() returns 1 for valid credentials, but the calling code discards that return value and invokes Manager() regardless. A user can therefore enter the wrong password and still reach the manager panel in the author’s example.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →The distinction is important: checking credentials is not enough if the code that controls access does not enforce the check’s result. The caller must condition the privileged operation on successful authentication. Huang’s proposed fix is to call Manager() only when Login() succeeds.
Enforce the result at the call site
Conceptually, the decision should look like this:
if (Login()) {
Manager();
}
If login fails, execution must not fall through to the privileged function. This is a local console-program finding; the account does not establish remote exploitation, deployment, or exposure over a network.
Replace recursive retries with a bounded loop
Huang also reports that the failed-login path calls Login() recursively and discards the recursive call’s result. Repeated failures can grow the call stack and may eventually cause a stack overflow, according to the author’s analysis. A loop with an attempt counter avoids adding a new stack frame for every retry and can return an explicit failure when attempts are exhausted.
Rank #2
Other code and input defects reported
Unbounded input into a fixed-size name field
The article shows a char name[20] field filled with fscanf using %s without a width limit. Since %s reads a sequence of non-whitespace characters without knowing the destination’s capacity, sufficiently long input can write past the end of the array. Huang’s example notes that a UTF-8 Chinese location name takes 24 bytes, so the number of visible characters is not a safe measure of the bytes needed in a C buffer. The author recommends sizing the buffer for the expected data and using a bounded conversion such as %63s for a suitably sized destination.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteUnsequenced modification and access in a printf call
Huang flags a call that decrements sNum and eNum in its arguments while also using them to index dist in that same call. The article says GCC warns about sequence-point or ordering concerns. The safer structure is to decrement the variables on separate statements, then pass the resulting values to printf; this avoids relying on the order in which function arguments are evaluated.
Build, file handling, and graph-input issues
- Broken Visual Studio references: Huang reports that a rename left references broken across the solution, project, and source-file chain, preventing the project from opening in Visual Studio as-is.
- Too many edge-reading iterations: The article says
fscanfruns for 18 iterations even though the input file contains 16 edges, duplicating the final edge on the last two iterations. - Writing through a read-only stream: The announcement feature opens a file with mode
"r"and then callsfprintf. The write fails, although the program reports success. - Hardcoded input limit: Huang reports a limit of 12 rather than deriving the value from the graph’s vertex count.
- Null stream passed to
fclose: Iffopenfails, one reported path callsfclose(NULL)instead of handling the open failure first.
What the audit says about the graph algorithms
Huang describes the Floyd–Warshall implementation as reconstructing routes through a path[i][j] intermediate-node table. The article also describes the DFS route search as using backtracking to reset visited nodes. The author considers these portions well-structured and notes a small quirk in path-length accumulation. These are the author’s assessments; the project was not independently validated for this account.
Quick Recap
What to take away from the findings
- Make authorization decisions explicit: a function that returns a success value does not protect anything unless its caller checks that value before continuing.
- Use bounded iteration for repeated input attempts, and make exhaustion produce an explicit failure rather than allowing unbounded recursion.
- Match string-input limits to the actual destination capacity, accounting for bytes in multibyte encodings such as UTF-8.
- Separate state changes from expressions that also read the changed variables, and check file-open results before using streams.
- Huang recommends enabling compiler warnings; the article’s report does not establish that every listed issue was independently reproduced.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

