IVORY_REL_5_STABLE: clear some build warnings#1126
IVORY_REL_5_STABLE: clear some build warnings#1126gaoxueyu merged 8 commits intoIvorySQL:IVORY_REL_5_STABLEfrom
Conversation
WalkthroughAdds stricter CI/toolchain (GCC 14 + extra -W flags); converts many file-scope globals to static, initializes several previously-uninitialized locals, refactors loop/index usage, adjusts a few control-flow/error paths, and adds one header Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/bin/psql/common.c (1)
3639-3653: Loop-index change is fine, but buffer size is off‑by‑one and can overflowThe switch from an implicit index to
int j = 0;and usingsql[j]in the loop is fine and doesn’t change semantics. However, this block has a latent overflow:
newsqlis allocated aspg_malloc0(strlen(sql) * 2);.- In the worst case where every character is
', the loop writes two bytes per input byte, i.e.2 * strlen(sql)bytes, then writes a'\0'terminator. That write can land one byte past the allocated buffer.This is a correctness and potential security issue, even though it predates the index rename.
A minimal fix is to allocate one extra byte:
- /* double write quote */ - newsql = pg_malloc0(strlen(sql) * 2); /* enough */ + /* double write quote: worst case is two bytes per input byte, plus NUL */ + size_t sql_len = strlen(sql); + newsql = pg_malloc0(sql_len * 2 + 1); ptr = newsql; - while (sql[j] != '\0') + while (sql[j] != '\0') { - if (sql[j] == '\'') - *ptr++ = sql[j]; - *ptr++ = sql[j]; - j++; + if (sql[j] == '\'') + *ptr++ = sql[j]; + *ptr++ = sql[j]; + j++; }While you’re touching this area, consider also cleaning up the early-return leak on
ntuples == 1(not introduced by this PR):res,query, andnewsqlare currently leaked on that path. A small refactor to funnel all exits through a common cleanup block would address that.src/interfaces/libpq/ivy-exec.c (1)
3766-3811: Potential off‑by‑one overflow in newsql quote‑duplication buffersIn both
IvyreplacenamebindtopositionandIvyreplacenamebindtoposition2,newsqlis allocated asmalloc(<query_len> * 2)but the loop can write up to2 * query_lenbytes (when every character is') plus a terminating'\0', so in that worst case the final write overruns the buffer by one byte. This is undefined behavior and becomes more likely to be diagnosed under GCC 14.Suggest allocating one extra byte for the terminator in both places:
- newsql = malloc(stmtHandle->query_len * 2); /* enough */ + newsql = malloc(stmtHandle->query_len * 2 + 1); /* enough (+1 for NUL) */and similarly in
Ivyreplacenamebindtoposition2:- newsql = malloc(strlen(stmtHandle->query) * 2); /* enough */ + newsql = malloc(strlen(stmtHandle->query) * 2 + 1); /* enough (+1 for NUL) */Behavior of the quoting loop otherwise remains the same.
Also applies to: 4058-4097
🧹 Nitpick comments (7)
src/backend/catalog/genbki.pl (1)
1121-1141: Refactor the type exclusion list for better maintainability.The chain of
necomparisons is fragile and inefficient. Using an array with a hash lookup would be more maintainable and performant.Apply this diff to refactor using an array:
+ # Oracle-specific types that allow zero OID references + my %oracle_types_with_zero_oid = map { $_ => 1 } qw( + oracharchar oracharbyte oravarcharchar oravarcharbyte + oradate oratimestamp oratimestamptz oratimestampltz + yminterval dsinterval number binary_float binary_double + ); + if ($lookupname eq '-' or $lookupname eq '0') { - if (defined($bki_values->{type_name}) - and $bki_values->{type_name} ne 'oracharchar' - and $bki_values->{type_name} ne 'oracharbyte' - and $bki_values->{type_name} ne 'oravarcharchar' - and $bki_values->{type_name} ne 'oravarcharbyte' - and $bki_values->{type_name} ne 'oradate' - and $bki_values->{type_name} ne 'oratimestamp' - and $bki_values->{type_name} ne 'oratimestamptz' - and $bki_values->{type_name} ne 'oratimestampltz' - and $bki_values->{type_name} ne 'yminterval' - and $bki_values->{type_name} ne 'dsinterval' - and $bki_values->{type_name} ne 'number' - and $bki_values->{type_name} ne 'binary_float' - and $bki_values->{type_name} ne 'binary_double' - ) + if (defined($bki_values->{type_name}) + and !exists($oracle_types_with_zero_oid{$bki_values->{type_name}})) { warn sprintf - "invalid zero OID reference in %s.dat field %s line %s\n", - $catname, $attname, $bki_values->{line_number} - if !$lookup_opt; + "invalid zero OID reference in %s.dat field %s line %s\n", + $catname, $attname, $bki_values->{line_number} + if !$lookup_opt; } }This approach:
- Makes it easier to add/remove Oracle types
- Improves readability
- Provides O(1) lookup instead of O(n) comparisons
- Fixes the indentation inconsistency in the warning message
src/backend/utils/adt/ruleutils.c (1)
14413-14456: Clarify relation OID variable naming (relidvsrelid_1).The new
Oid relid_1is used correctly and doesn’t change behavior, but having bothrelidandrelid_1in the same function makes the control flow harder to read. Sincerelidis already scoped for this function and used in the rowtype branch, you could reuse it instead of introducingrelid_1(or rename to a more descriptive name likeattr_relid) to keep the code clearer.This is purely a readability / maintainability nit; no functional issue.
src/pl/plisql/src/pl_subproc_function.c (1)
409-462: Remove leftover commented-out local variable declaration
argvariableis already declared at function scope (earlier inplisql_build_variable_from_funcargs), and this block now correctly reuses it. The commented-out local declaration://PLiSQL_variable *argvariable;is just dead code and could be misleading about intended scoping. Recommend deleting it to keep the function clean and avoid confusion.
Suggested change:
- //PLiSQL_variable *argvariable;src/pl/plisql/src/pl_scanner.c (1)
121-121: Commented-out scanner globals look safe; consider removing or aligning helpersCommenting out
plisql_scannerandcur_line_numis behavior‑neutral here: both werestaticto this TU and all remaining references are now also commented, while the live code usesyyextra/PLiSQL_yylex_global_properfor scanner and line‑number state. To reduce future confusion, you could either delete these dead declarations and the associated commented assignments inplisql_get_yylex_global_proper/plisql_recover_yylex_global_proper, or (if you plan to keep the snapshot helpers) have them snapshot/restoreyyextra->cur_line_*instead of the old static proxies.Also applies to: 143-143
src/backend/commands/sequence.c (1)
2399-2424: Initializeattnumdefensively inprocess_owned_byInitializing
AttrNumber attnum = InvalidAttrNumber;removes the potential for GCC 14-Wmaybe-uninitializedwarnings and makes the code safer against future control-flow changes. Existing branches still assignattnumexplicitly forOWNED BY NONE(0) and fortable.columncases viaget_attnum(), and the defaultInvalidAttrNumber(0) correctly represents a relation-level dependency when we end up not binding to a specific column (e.g., ORA_PARSER paths whereseqname == attrname).No functional regressions here; this just codifies the previously implicit behavior.
src/pl/plisql/src/pl_comp.c (1)
3380-3452: Hash‑key argtype resolution is correct but leaks some per‑call memoryThe new
protypenames/argtypenameshandling incompute_function_hashkeycorrectly:
- Starts from catalog
proargtypesintohashkey->argtypes[i].- Overwrites entries when a package type or
%TYPE/%ROWTYPEname resolves viaLookupPkgTypeByTypename/LookupOraTypeName.- Falls back to
memcpywhenprotypenamesis NULL.- Still calls
plisql_resolve_polymorphic_argtypesso polymorphic behavior is preserved.Two non‑critical points:
deconstruct_array+TextDatumGetCStringallocateelemsand eachargtypenames[i]in the current memory context but nothing in this function frees them. Sincecompute_function_hashkeycan run multiple times over the backend lifetime (e.g., validator, cache eviction), that’s a small permanent leak.- The loop assumes the deconstructed array has at least
procStruct->pronargselements; that matches howget_func_typename_infois normally populated, but if catalog data were inconsistent it would read pastargtypenamesbounds.If you want to tighten this without changing behavior, I'd suggest:
- deconstruct_array(DatumGetArrayTypeP(protypenames), - TEXTOID, -1, false, 'i', - &elems, NULL, &nelems); - argtypenames = (char **) palloc(sizeof(char *) * nelems); - for (i = 0; i < nelems; i++) - argtypenames[i] = TextDatumGetCString(elems[i]); + deconstruct_array(DatumGetArrayTypeP(protypenames), + TEXTOID, -1, false, 'i', + &elems, NULL, &nelems); + argtypenames = (char **) palloc(sizeof(char *) * nelems); + for (i = 0; i < nelems; i++) + argtypenames[i] = TextDatumGetCString(elems[i]); + /* elems points into a palloc'ed ArrayType workspace */ + pfree(elems); @@ - if (argtypenames != NULL) + if (argtypenames != NULL) { - for (i = 0; i < procStruct->pronargs; i++) + int n = Min(procStruct->pronargs, nelems); + + for (i = 0; i < n; i++) { ... } + + for (i = 0; i < nelems; i++) + pfree(argtypenames[i]); + pfree(argtypenames); } - else + else memcpy(hashkey->argtypes, procStruct->proargtypes.values, procStruct->pronargs * sizeof(Oid));This keeps behavior but avoids leaking and defends against catalog length mismatches.
src/backend/commands/tablecmds.c (1)
15677-15684: Else-branch allocation looks correct; double‑checkFuncPkgDependsemantics.Allocating
dependentFuncPkgOidsviapalloc((*maxDependentFuncPkgOids) * sizeof(ObjectFunOrPkg))in theelsebranch cleanly covers the case where no external buffer is provided, so the pointer is always backed by storage before use.One thing to verify:
FuncPkgDependis only set totruein the branch that reuses*dependentFuncPkg. IfFuncPkgDependis meant to represent “this column has dependent funcs/pkgs to rebuild” rather than “caller supplied the buffer”, you may also want to set it in theelsebranch to avoid changing behavior.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (28)
.github/workflows/build.yml(2 hunks)contrib/gb18030_2022/utf8_and_gb18030_2022.c(1 hunks)contrib/ivorysql_ora/src/builtin_functions/datetime_datatype_functions.c(3 hunks)contrib/uuid-ossp/uuid-ossp.c(2 hunks)src/backend/access/transam/xlog.c(1 hunks)src/backend/catalog/genbki.pl(1 hunks)src/backend/commands/sequence.c(2 hunks)src/backend/commands/tablecmds.c(2 hunks)src/backend/executor/execExpr.c(1 hunks)src/backend/oracle_parser/liboracle_parser.c(1 hunks)src/backend/parser/parse_param.c(1 hunks)src/backend/utils/adt/arrayfuncs.c(1 hunks)src/backend/utils/adt/ruleutils.c(2 hunks)src/backend/utils/misc/ivy_guc.c(1 hunks)src/bin/pg_dump/pg_dump.c(1 hunks)src/bin/psql/common.c(5 hunks)src/bin/psql/psqlplusscan.l(1 hunks)src/bin/psql/startup.c(1 hunks)src/fe_utils/string_utils.c(1 hunks)src/include/utils/ora_compatible.h(1 hunks)src/interfaces/libpq/ivy-exec.c(9 hunks)src/oracle_test/isolation/isolation_main.c(1 hunks)src/oracle_test/isolation/specparse.y(1 hunks)src/pl/plisql/src/pl_comp.c(1 hunks)src/pl/plisql/src/pl_handler.c(1 hunks)src/pl/plisql/src/pl_package.c(1 hunks)src/pl/plisql/src/pl_scanner.c(2 hunks)src/pl/plisql/src/pl_subproc_function.c(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-24T08:19:29.453Z
Learnt from: OreoYang
Repo: IvorySQL/IvorySQL PR: 931
File: src/backend/oracle_parser/ora_gram.y:0-0
Timestamp: 2025-10-24T08:19:29.453Z
Learning: In IvorySQL’s parser (src/backend/oracle_parser/ora_gram.y and related headers), downcase_identifier has the 4-argument signature:
extern char *downcase_identifier(const char *ident, int len, bool warn, bool truncate);
Applied to files:
src/backend/oracle_parser/liboracle_parser.csrc/backend/utils/misc/ivy_guc.csrc/fe_utils/string_utils.c
🧬 Code graph analysis (6)
src/pl/plisql/src/pl_package.c (1)
src/include/nodes/pg_list.h (1)
list_length(151-155)
src/pl/plisql/src/pl_handler.c (2)
src/backend/oracle_parser/liboracle_parser.c (1)
_PG_fini(84-91)contrib/ivorysql_ora/src/ivorysql_ora.c (1)
_PG_fini(107-119)
src/backend/utils/adt/ruleutils.c (1)
src/backend/utils/cache/lsyscache.c (2)
get_attnum(955-972)get_atttypetypmodcoll(1040-1059)
src/pl/plisql/src/pl_comp.c (1)
src/backend/utils/fmgr/funcapi.c (1)
get_func_typename_info(1889-1933)
src/bin/psql/common.c (1)
src/bin/psql/variables.c (1)
BindVariableExist(1080-1108)
src/backend/commands/tablecmds.c (1)
src/backend/utils/mmgr/mcxt.c (1)
palloc(1320-1348)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: pg_regression (ubuntu-latest)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: meson_build (ubuntu-latest)
- GitHub Check: contrib_regression
- GitHub Check: oracle_pg_regression (ubuntu-latest)
- GitHub Check: oracle_regression (ubuntu-latest)
🔇 Additional comments (24)
src/fe_utils/string_utils.c (1)
107-115: LGTM! Resource allocation optimized.The reordering defers buffer allocation until after the Oracle mode check, avoiding unnecessary work when the early return is taken. This change eliminates wasted resource allocation and likely resolves a GCC 14.2 compiler warning about potentially unused initialization.
src/backend/utils/adt/arrayfuncs.c (1)
468-468: LGTM: Minor formatting improvement.This whitespace adjustment aligns with the PR's objective to address build warnings with GCC 14.2. The error handling logic remains correct and consistent with the similar error path at line 454.
contrib/uuid-ossp/uuid-ossp.c (1)
565-568: LGTM! Clean refactoring to eliminate build warnings.Consolidating the OSSP-specific variable declarations at the top of the function with proper conditional compilation guards addresses both "declaration after statement" and "unused variable" warnings. This change aligns with the PR's goal of enabling stricter GCC 14 compilation flags.
src/oracle_test/isolation/specparse.y (1)
18-19: Verify header file placement for extern declarations.These
externdeclarations for Bison-generated parser internals (spec_yycharandspec_yynerrs) are placed in the.yfile prologue. If these variables are accessed from other compilation units, they should be declared in a header file (e.g.,specparse.h) rather than in the grammar file prologue, as the latter only affects the generated parser source file. Verify whether these variables are used externally and consider moving their declarations to an appropriate header file for consistency with C best practices.src/backend/executor/execExpr.c (1)
5108-5120: Initializefunc_tupleto satisfy GCC 14 without changing behaviorInitializing
HeapTuple func_tuple = NULL;is safe and removes the GCC 14-Wmaybe-uninitializedwarning.func_tupleis only assigned and released inside theFUNC_EXPR_FROM_PG_PROC()branch, so this has no semantic impact and just quiets the new stricter warnings..github/workflows/build.yml (1)
21-41: GCC 14 setup and stricter CFLAGS are consistent with the PR goalsInstalling
gcc-14/g++-14and wiring them viaupdate-alternativesonubuntu-latest(Ubuntu 24.04, which providesgcc-1414.2.0-4ubuntu2~24.04) is valid, and the addedCFLAGSwarning/error options align with tightening CI under GCC 14. The sequence of installing gcc-14 first, thenbuild-essential, with higher alternative priority for gcc-14, should keep 14.x as the active compiler.If you later extend the
osmatrix beyond Ubuntu, ensure this step remains guarded by theubuntu-latestcheck, and be prepared for some existing code paths to start failing CI due to the new-Werror=*flags.src/backend/commands/sequence.c (1)
98-101: Restrictsession_idandscale_valueto file scopeMaking
session_id(int64) andscale_value(int32)staticconfines them to this translation unit while preserving zero-initialization. This aligns with-Wmissing-variable-declarationsand visibility best practices. Behavior is unchanged if these variables are only used within sequence.c.Before merging, confirm that no other translation unit declares or references
session_idorscale_value.src/pl/plisql/src/pl_comp.c (1)
1097-1116: Arg/return type reference tracking looks correct and self‑containedResetting
argtypenames/rettypenamebefore callingget_func_typename_infoand then walking the arrays to feedplisql_add_type_referenced_objectsis logically sound and matches how%TYPE/%ROWTYPEreferences are handled elsewhere. Thestrcmp(argtypenames[j], "") != 0guard also ensures you skip empty slots safely.No functional issues here from a correctness or lifetime perspective (given the subsequent
pfree(argtypenames)/pfree(rettypename)).src/pl/plisql/src/pl_handler.c (1)
228-234: _PG_fini prototype is appropriateAdding an explicit
void _PG_fini(void);prototype before the definition is correct for a non‑static module lifecycle function and will satisfy stricter compiler checks without changing behavior.src/bin/psql/psqlplusscan.l (1)
50-50: StaticNumKeywordsis fine and reduces symbol exportRestricting
NumKeywordsto internal linkage withstaticmatches its usage (only referenced in this file) and avoids exporting an unnecessary global.src/include/utils/ora_compatible.h (1)
61-61: New extern forbootstrap_database_modeis reasonable; ensure single definitionDeclaring
extern int bootstrap_database_mode;here is fine given this header’s role in compatibility mode plumbing. Please just verify there is exactly one non‑static definition ofbootstrap_database_modein the backend (and no leftover conflicting externs in other headers) to avoid link‑time issues.src/backend/oracle_parser/liboracle_parser.c (1)
52-52: Staticprev_quote_identifiermatches other saved‑hook variablesMarking
prev_quote_identifierasstaticis correct; it’s only used inside this module to save/restore the hook and no longer pollutes the global symbol table.src/backend/parser/parse_param.c (1)
74-75: MakingTopOraParamNode/CurrentOraParamNodestatic is appropriateThese stacks are only manipulated via the public helper functions in this file, so changing them to
staticis a good encapsulation step and should silence global‑symbol warnings. However, verify that no other.cfile still references these symbols directly by searching the codebase.src/bin/pg_dump/pg_dump.c (1)
19115-19131:SEQTYPE_CUSTINTis never handled and now always triggerspg_fatal
SeqTypedefinesSEQTYPE_CUSTINTandSeqTypeNames[]maps it to"pg_catalog.int8", but the default range computation indumpSequenceonly handlesSEQTYPE_SMALLINT,SEQTYPE_INTEGER, andSEQTYPE_BIGINT. Any sequence whose type parses asSEQTYPE_CUSTINTwill now fall into the finalelseand abortpg_dumpwith "unrecognized sequence type", even though it is explicitly recognized byparse_sequence_type.If
SEQTYPE_CUSTINTis intended to be an alias of bigint (which the"pg_catalog.int8"mapping strongly suggests), it should be treated likeSEQTYPE_BIGINThere rather than failing.Consider updating the conditional to group
SEQTYPE_CUSTINTwith the bigint case and keep thepg_fatalonly for truly unknown enum values:- else if (seq->seqtype == SEQTYPE_BIGINT) - { - default_minv = is_ascending ? 1 : PG_INT64_MIN; - default_maxv = is_ascending ? PG_INT64_MAX : -1; - } - else - { - pg_fatal("unrecognized sequence type: %d", seq->seqtype); - default_minv = default_maxv = 0; /* keep compiler quiet */ - } + else if (seq->seqtype == SEQTYPE_BIGINT || + seq->seqtype == SEQTYPE_CUSTINT) + { + default_minv = is_ascending ? 1 : PG_INT64_MIN; + default_maxv = is_ascending ? PG_INT64_MAX : -1; + } + else + { + pg_fatal("unrecognized sequence type: %d", seq->seqtype); + default_minv = default_maxv = 0; /* keep compiler quiet */ + }Please verify that sequences with
seqtypidformatting as"pg_catalog.int8"are handled correctly.src/backend/access/transam/xlog.c (1)
112-114: BootstrapTimeLineID macro looks correct and improves clarityDefining
BootstrapTimeLineIDas a single macro (set to1) matches its usage in the bootstrap WAL/control‑file paths and removes the hard‑coded magic value without changing behavior. No further changes needed here.contrib/gb18030_2022/utf8_and_gb18030_2022.c (1)
25-26: Static converter hooks look correctMaking
pre_gb18030_2022_to_utf8_hookandpre_utf8_to_gb18030_2022_hookstaticcorrectly restricts them to this translation unit without changing behavior, since they’re only used in_PG_init/_PG_fini.src/oracle_test/isolation/isolation_main.c (1)
21-23: Static globals for isolation tester path are fine
saved_argv0,isolation_exec, andlooked_up_isolation_execare only used in this file, so making themstaticis a safe visibility tightening and should not affect behavior.src/bin/psql/common.c (1)
3726-3735: InitializingiinSendQuery_PBEis harmless and silences warningsChanging
int i;toint i = 0;inSendQuery_PBEis behavior‑preserving (all uses ofiare infor (i = …)loops) and should quiet any “maybe uninitialized” warnings from GCC 14 around thesendquery_cleanuplabel.src/bin/psql/startup.c (1)
399-440: Explicit NULL initialization forscan_state/cond_stackis goodInitializing
PsqlScanState scan_state = NULL;andConditionalStack cond_stack = NULL;in theACT_SINGLE_SLASHpath avoids “maybe uninitialized” warnings and guarantees a known value ifdb_modewere ever something other thanDB_PG/DB_ORACLE(in addition to the existingAssert(scan_state != NULL)).src/pl/plisql/src/pl_package.c (1)
2732-2739: Improved assertion around package–function reference removalCapturing
pre_len = list_length(psource->source.funclist);beforelist_delete_ptr()and then assertingpre_len == list_length(...) + 1is a correct and clearer way to verify that exactly one entry was removed. This also makes it easier to detect cases wherefuncwasn’t present in the list.src/backend/utils/misc/ivy_guc.c (1)
37-39: Making NLS backing variablesstaticis reasonable; verify no externalexterndeclarationsRestricting
nls_territory,nls_currency, andnls_iso_currencyto internal linkage aligns with how they're used here (exclusively through the GUC machinery in this file) and reduces symbol exposure.Ensure there are no
externdeclarations or direct external references to these variables elsewhere in the codebase—if other files reference them directly rather than throughGetConfigOption*, linking will fail after this change.src/backend/commands/tablecmds.c (1)
15670-15673: Good defensive initialization ofdependentFuncPkgOids.Initializing
ObjectFunOrPkg *dependentFuncPkgOidstoNULLremoves the “maybe-uninitialized” risk and makes subsequent control-flow easier to reason about; no issues here.contrib/ivorysql_ora/src/builtin_functions/datetime_datatype_functions.c (1)
156-204: Static linkage for lookup tables looks goodMaking
ora_days,date_fmt, anddate_timezonestaticcorrectly limits their visibility to this translation unit and should help with GCC 14 warnings about unused globals, without changing behavior.src/interfaces/libpq/ivy-exec.c (1)
2997-3044: IvyaddValueToList initialization/scan logic is correctInitializing
pre,tmp, andfindand using thefor (tmp = list, pre = list; ...)pattern preserves the original “dedupe then append at tail” behavior while eliminating potential uninitialized‑use warnings. No functional issues here.
c2main
left a comment
There was a problem hiding this comment.
there are several places that can be rewritten with a more pointer traversal approach, why code is commented is not very clear.
There was a problem hiding this comment.
it'll hit a warning here also i think
| RangeVar *rel = makeRangeVar(NULL, NULL, typeName->location); | ||
| char *field = NULL; | ||
| Oid relid; | ||
| Oid relid_1; |
There was a problem hiding this comment.
isn't this code just supposed to use the relid defined previously ?! this relid_1 will then be missed instead, and relid will stay uninitialized while used later. Maybe on purpose, then please add a comment and change variable name to something more meaningful maybe ?
| char *newsql = NULL; | ||
| char *ptr = NULL; | ||
| int i = 0; | ||
| int j = 0; |
There was a problem hiding this comment.
you don't need an increment var, you can just move the 2 pointers.
| * back to the front. | ||
| */ | ||
| for (i = hv->length; i > 0; i--) | ||
| for (j = hv->length; j > 0; j--) |
There was a problem hiding this comment.
if you want to keep keys and don't use them after, you can do for (int i ...
| char *newsql = NULL; | ||
| char *ptr = NULL; | ||
| int i = 0; | ||
| int j = 0; |
| stmtHandle->nParams = n_tuples - 1; | ||
| memset(stmtHandle->paramNames, 0x00, sizeof(char *) * (n_tuples - 1)); | ||
| for (i = 1; i < n_tuples; i++) | ||
| for (j = 1; j < n_tuples; j++) |
There was a problem hiding this comment.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/bin/psql/common.c(3 hunks)src/interfaces/libpq/ivy-exec.c(10 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/interfaces/libpq/ivy-exec.c
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
- GitHub Check: build (ubuntu-latest)
- GitHub Check: oracle_pg_regression (ubuntu-latest)
- GitHub Check: meson_build (ubuntu-latest)
- GitHub Check: oracle_regression (ubuntu-latest)
- GitHub Check: contrib_regression
- GitHub Check: pg_regression (ubuntu-latest)
🔇 Additional comments (2)
src/bin/psql/common.c (2)
3852-3863: LGTM! Inline loop declaration and backward iteration are correct.The inline
int ideclaration follows modern C best practices and limits scope. The backward iteration correctly accesses indices fromhv->length - 1down to0usingi - 1, and the logic aligns with the Oracle error message ordering requirement mentioned in the comment.
4040-4044: LGTM! Inline loop declaration improves code clarity.The inline
int ideclaration properly scopes the loop variable and follows C99+ best practices. The loop bounds are correct.
| newsql = pg_malloc0(strlen(sql) * 2); /* enough */ | ||
| ptr = newsql; | ||
| while (sql[i] != '\0') | ||
|
|
||
| while (*sql != '\0') | ||
| { | ||
| if (sql[i] == '\'') | ||
| *ptr++ = sql[i]; | ||
| *ptr++ = sql[i]; | ||
| i++; | ||
| if (*sql == '\'') | ||
| *ptr++ = *sql; | ||
| *ptr++ = *sql; | ||
| sql++; | ||
| } | ||
| *ptr = '\0'; |
There was a problem hiding this comment.
Buffer overflow: allocation is 1 byte short.
The allocation at line 3645 is insufficient. In the worst case where sql contains all single quotes, the loop will write 2 * strlen(sql) characters, then attempt to write a null terminator at index 2 * strlen(sql), which is out of bounds.
Apply this diff to fix the allocation:
- newsql = pg_malloc0(strlen(sql) * 2); /* enough */
+ newsql = pg_malloc0(strlen(sql) * 2 + 1); /* enough for worst case + null terminator */📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| newsql = pg_malloc0(strlen(sql) * 2); /* enough */ | |
| ptr = newsql; | |
| while (sql[i] != '\0') | |
| while (*sql != '\0') | |
| { | |
| if (sql[i] == '\'') | |
| *ptr++ = sql[i]; | |
| *ptr++ = sql[i]; | |
| i++; | |
| if (*sql == '\'') | |
| *ptr++ = *sql; | |
| *ptr++ = *sql; | |
| sql++; | |
| } | |
| *ptr = '\0'; | |
| newsql = pg_malloc0(strlen(sql) * 2 + 1); /* enough for worst case + null terminator */ | |
| ptr = newsql; | |
| while (*sql != '\0') | |
| { | |
| if (*sql == '\'') | |
| *ptr++ = *sql; | |
| *ptr++ = *sql; | |
| sql++; | |
| } | |
| *ptr = '\0'; |
🤖 Prompt for AI Agents
In src/bin/psql/common.c around lines 3645-3655, the buffer allocation
pg_malloc0(strlen(sql) * 2) is one byte too small because the loop can write 2 *
strlen(sql) characters plus the terminating NUL; change the allocation to
reserve space for the terminator (e.g., pg_malloc0(strlen(sql) * 2 + 1)) so the
final NUL fits, keeping the rest of the loop logic unchanged.
done. |
|
@c2main Hi Cedric, due to the code freeze deadline for IvorySQL 5.1, we need to merge this code immediately. Let you know. |
Summary by CodeRabbit
Bug Fixes
Refactor
Chores
✏️ Tip: You can customize this high-level summary in your review settings.