| 11230 | } |
| 11231 | |
| 11232 | static int zipfileGetMode( |
| 11233 | sqlite3_value *pVal, |
| 11234 | int bIsDir, /* If true, default to directory */ |
| 11235 | u32 *pMode, /* OUT: Mode value */ |
| 11236 | char **pzErr /* OUT: Error message */ |
| 11237 | ){ |
| 11238 | const char *z = (const char*)sqlite3_value_text(pVal); |
| 11239 | u32 mode = 0; |
| 11240 | if( z==0 ){ |
| 11241 | mode = (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)); |
| 11242 | }else if( z[0]>='0' && z[0]<='9' ){ |
| 11243 | mode = (unsigned int)sqlite3_value_int(pVal); |
| 11244 | }else{ |
| 11245 | const char zTemplate[11] = "-rwxrwxrwx"; |
| 11246 | int i; |
| 11247 | if( strlen(z)!=10 ) goto parse_error; |
| 11248 | switch( z[0] ){ |
| 11249 | case '-': mode |= S_IFREG; break; |
| 11250 | case 'd': mode |= S_IFDIR; break; |
| 11251 | case 'l': mode |= S_IFLNK; break; |
| 11252 | default: goto parse_error; |
| 11253 | } |
| 11254 | for(i=1; i<10; i++){ |
| 11255 | if( z[i]==zTemplate[i] ) mode |= 1 << (9-i); |
| 11256 | else if( z[i]!='-' ) goto parse_error; |
| 11257 | } |
| 11258 | } |
| 11259 | if( ((mode & S_IFDIR)==0)==bIsDir ){ |
| 11260 | /* The "mode" attribute is a directory, but data has been specified. |
| 11261 | ** Or vice-versa - no data but "mode" is a file or symlink. */ |
| 11262 | *pzErr = sqlite3_mprintf("zipfile: mode does not match data"); |
| 11263 | return SQLITE_CONSTRAINT; |
| 11264 | } |
| 11265 | *pMode = mode; |
| 11266 | return SQLITE_OK; |
| 11267 | |
| 11268 | parse_error: |
| 11269 | *pzErr = sqlite3_mprintf("zipfile: parse error in mode: %s", z); |
| 11270 | return SQLITE_ERROR; |
| 11271 | } |
| 11272 | |
| 11273 | /* |
| 11274 | ** Both (const char*) arguments point to nul-terminated strings. Argument |
no outgoing calls
no test coverage detected