It's not just the size of the code that is the problem, although that alone practically guarantees that there will be bugs. Ethereum has a couple of unique properties that can cause all sorts of chaos in ways that 'normal' language developers never need worry about.
First of all, code requires 'gas' to run. If there isn't enough gas, then the execution stops. But critically, some but not all of the code's actions are rolled back. Transfers from one party to another still take place. You can imagine a situation where an attacker runs a contract with just enough gas to make the code transfer some money but halt before it records the payout, allowing the withdrawal to be repeated.
Secondly, there's a stack limit for code, again triggering an exception and a partial rollback. Developers are used to having to reason about stack overflows in normal programming situations, e.g. a recursive algorithm. But Ethereum's stack has more problems. It allows attackers to control the available stack space before your code gets run. e.g. an evil-doer could use up almost all of the stack, then call your contract. If the stack runs out at a select inopportune moment, there is potential for abuse.