// Switch certain class of snprintf to use internal macro crm_snprintf_max // jpokorny@redhat.com @ has_crm_internal @ @@ #include //@ snprintf_eligible exists @ //expression E1, E2; //identifier fn, id_str, id_max, id_offset; //type t_max, t_offset; //@@ //fn(...) { //... //( //t_offset id_offset = E1; //... //- static t_max id_max = E2; //+ static const t_max id_max = E2; //| //- static t_max id_max = E2; //+ static const t_max id_max = E2; //... //t_offset id_offset = E1; //) //<... //id_offset += snprintf(id_str + id_offset, id_max - id_offset, ...); //...> //} @ snprintf_rewrite @ identifier id_str; identifier fn, id_max, id_offset; @@ fn(...) { <... id_offset += - snprintf(id_str + id_offset, id_max - id_offset + crm_snprintf_offset(id_str, id_offset, id_max , ...); ...> } @ snprintf_assert forall @ identifier snprintf_rewrite.fn, snprintf_rewrite.id_max, snprintf_rewrite.id_offset; @@ fn(...) { <... - CRM_LOG_ASSERT(id_offset > 0); + CRM_LOG_ASSERT(id_offset > 0 && id_offset < id_max); ...> } // this is not the best placement, it serves a subsequent manual review // to denote necessity to add the include at all, and the reviewer will // (hopefully) move the include to the correct location @ snprintf_include depends on (snprintf_rewrite && !(has_crm_internal)) exists @ identifier snprintf_rewrite.fn; @@ + #include /* crm_snprintf_offset */ fn(...) { ... }