xmlschemas.c 806 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971
  1. /*
  2. * schemas.c : implementation of the XML Schema handling and
  3. * schema validity checking
  4. *
  5. * See Copyright for the status of this software.
  6. *
  7. * Daniel Veillard <veillard@redhat.com>
  8. */
  9. /*
  10. * TODO:
  11. * - when types are redefined in includes, check that all
  12. * types in the redef list are equal
  13. * -> need a type equality operation.
  14. * - if we don't intend to use the schema for schemas, we
  15. * need to validate all schema attributes (ref, type, name)
  16. * against their types.
  17. * - Eliminate item creation for: ??
  18. *
  19. * URGENT TODO:
  20. * - For xsi-driven schema acquisition, augment the IDCs after every
  21. * acquisition episode (xmlSchemaAugmentIDC).
  22. *
  23. * NOTES:
  24. * - Eliminated item creation for: <restriction>, <extension>,
  25. * <simpleContent>, <complexContent>, <list>, <union>
  26. *
  27. * PROBLEMS:
  28. * - http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0337.html
  29. * IDC XPath expression and chameleon includes: the targetNamespace is changed, so
  30. * XPath will have trouble to resolve to this namespace, since not known.
  31. *
  32. *
  33. * CONSTRAINTS:
  34. *
  35. * Schema Component Constraint:
  36. * All Group Limited (cos-all-limited)
  37. * Status: complete
  38. * (1.2)
  39. * In xmlSchemaGroupDefReferenceTermFixup() and
  40. * (2)
  41. * In xmlSchemaParseModelGroup()
  42. * TODO: Actually this should go to component-level checks,
  43. * but is done here due to performance. Move it to an other layer
  44. * is schema construction via an API is implemented.
  45. */
  46. /* To avoid EBCDIC trouble when parsing on zOS */
  47. #if defined(__MVS__)
  48. #pragma convert("ISO8859-1")
  49. #endif
  50. #define IN_LIBXML
  51. #include "libxml.h"
  52. #ifdef LIBXML_SCHEMAS_ENABLED
  53. #include <string.h>
  54. #include <libxml/xmlmemory.h>
  55. #include <libxml/parser.h>
  56. #include <libxml/parserInternals.h>
  57. #include <libxml/hash.h>
  58. #include <libxml/uri.h>
  59. #include <libxml/xmlschemas.h>
  60. #include <libxml/schemasInternals.h>
  61. #include <libxml/xmlschemastypes.h>
  62. #include <libxml/xmlautomata.h>
  63. #include <libxml/xmlregexp.h>
  64. #include <libxml/dict.h>
  65. #include <libxml/encoding.h>
  66. #include <libxml/xmlIO.h>
  67. #ifdef LIBXML_PATTERN_ENABLED
  68. #include <libxml/pattern.h>
  69. #endif
  70. #ifdef LIBXML_READER_ENABLED
  71. #include <libxml/xmlreader.h>
  72. #endif
  73. /* #define DEBUG 1 */
  74. /* #define DEBUG_CONTENT 1 */
  75. /* #define DEBUG_TYPE 1 */
  76. /* #define DEBUG_CONTENT_REGEXP 1 */
  77. /* #define DEBUG_AUTOMATA 1 */
  78. /* #define DEBUG_IDC */
  79. /* #define DEBUG_IDC_NODE_TABLE */
  80. /* #define WXS_ELEM_DECL_CONS_ENABLED */
  81. #ifdef DEBUG_IDC
  82. #ifndef DEBUG_IDC_NODE_TABLE
  83. #define DEBUG_IDC_NODE_TABLE
  84. #endif
  85. #endif
  86. /* #define ENABLE_PARTICLE_RESTRICTION 1 */
  87. #define ENABLE_REDEFINE
  88. /* #define ENABLE_NAMED_LOCALS */
  89. /* #define ENABLE_IDC_NODE_TABLES_TEST */
  90. #define DUMP_CONTENT_MODEL
  91. #ifdef LIBXML_READER_ENABLED
  92. /* #define XML_SCHEMA_READER_ENABLED */
  93. #endif
  94. #define UNBOUNDED (1 << 30)
  95. #define TODO \
  96. xmlGenericError(xmlGenericErrorContext, \
  97. "Unimplemented block at %s:%d\n", \
  98. __FILE__, __LINE__);
  99. #define XML_SCHEMAS_NO_NAMESPACE (const xmlChar *) "##"
  100. /*
  101. * The XML Schemas namespaces
  102. */
  103. static const xmlChar *xmlSchemaNs = (const xmlChar *)
  104. "http://www.w3.org/2001/XMLSchema";
  105. static const xmlChar *xmlSchemaInstanceNs = (const xmlChar *)
  106. "http://www.w3.org/2001/XMLSchema-instance";
  107. static const xmlChar *xmlNamespaceNs = (const xmlChar *)
  108. "http://www.w3.org/2000/xmlns/";
  109. /*
  110. * Come casting macros.
  111. */
  112. #define ACTXT_CAST (xmlSchemaAbstractCtxtPtr)
  113. #define PCTXT_CAST (xmlSchemaParserCtxtPtr)
  114. #define VCTXT_CAST (xmlSchemaValidCtxtPtr)
  115. #define WXS_BASIC_CAST (xmlSchemaBasicItemPtr)
  116. #define WXS_TREE_CAST (xmlSchemaTreeItemPtr)
  117. #define WXS_PTC_CAST (xmlSchemaParticlePtr)
  118. #define WXS_TYPE_CAST (xmlSchemaTypePtr)
  119. #define WXS_ELEM_CAST (xmlSchemaElementPtr)
  120. #define WXS_ATTR_GROUP_CAST (xmlSchemaAttributeGroupPtr)
  121. #define WXS_ATTR_CAST (xmlSchemaAttributePtr)
  122. #define WXS_ATTR_USE_CAST (xmlSchemaAttributeUsePtr)
  123. #define WXS_ATTR_PROHIB_CAST (xmlSchemaAttributeUseProhibPtr)
  124. #define WXS_MODEL_GROUPDEF_CAST (xmlSchemaModelGroupDefPtr)
  125. #define WXS_MODEL_GROUP_CAST (xmlSchemaModelGroupPtr)
  126. #define WXS_IDC_CAST (xmlSchemaIDCPtr)
  127. #define WXS_QNAME_CAST (xmlSchemaQNameRefPtr)
  128. #define WXS_LIST_CAST (xmlSchemaItemListPtr)
  129. /*
  130. * Macros to query common properties of components.
  131. */
  132. #define WXS_ITEM_NODE(i) xmlSchemaGetComponentNode(WXS_BASIC_CAST (i))
  133. #define WXS_ITEM_TYPE_NAME(i) xmlSchemaGetComponentTypeStr(WXS_BASIC_CAST (i))
  134. /*
  135. * Macros for element declarations.
  136. */
  137. #define WXS_ELEM_TYPEDEF(e) (e)->subtypes
  138. #define WXS_SUBST_HEAD(item) (item)->refDecl
  139. /*
  140. * Macros for attribute declarations.
  141. */
  142. #define WXS_ATTR_TYPEDEF(a) (a)->subtypes
  143. /*
  144. * Macros for attribute uses.
  145. */
  146. #define WXS_ATTRUSE_DECL(au) (WXS_ATTR_USE_CAST (au))->attrDecl
  147. #define WXS_ATTRUSE_TYPEDEF(au) WXS_ATTR_TYPEDEF(WXS_ATTRUSE_DECL( WXS_ATTR_USE_CAST au))
  148. #define WXS_ATTRUSE_DECL_NAME(au) (WXS_ATTRUSE_DECL(au))->name
  149. #define WXS_ATTRUSE_DECL_TNS(au) (WXS_ATTRUSE_DECL(au))->targetNamespace
  150. /*
  151. * Macros for attribute groups.
  152. */
  153. #define WXS_ATTR_GROUP_HAS_REFS(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS)
  154. #define WXS_ATTR_GROUP_EXPANDED(ag) ((WXS_ATTR_GROUP_CAST (ag))->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED)
  155. /*
  156. * Macros for particles.
  157. */
  158. #define WXS_PARTICLE(p) WXS_PTC_CAST (p)
  159. #define WXS_PARTICLE_TERM(p) (WXS_PARTICLE(p))->children
  160. #define WXS_PARTICLE_TERM_AS_ELEM(p) (WXS_ELEM_CAST WXS_PARTICLE_TERM(p))
  161. #define WXS_PARTICLE_MODEL(p) WXS_MODEL_GROUP_CAST WXS_PARTICLE(p)->children
  162. /*
  163. * Macros for model groups definitions.
  164. */
  165. #define WXS_MODELGROUPDEF_MODEL(mgd) (WXS_MODEL_GROUP_CAST (mgd))->children
  166. /*
  167. * Macros for model groups.
  168. */
  169. #define WXS_IS_MODEL_GROUP(i) \
  170. (((i)->type == XML_SCHEMA_TYPE_SEQUENCE) || \
  171. ((i)->type == XML_SCHEMA_TYPE_CHOICE) || \
  172. ((i)->type == XML_SCHEMA_TYPE_ALL))
  173. #define WXS_MODELGROUP_PARTICLE(mg) WXS_PTC_CAST (mg)->children
  174. /*
  175. * Macros for schema buckets.
  176. */
  177. #define WXS_IS_BUCKET_INCREDEF(t) (((t) == XML_SCHEMA_SCHEMA_INCLUDE) || \
  178. ((t) == XML_SCHEMA_SCHEMA_REDEFINE))
  179. #define WXS_IS_BUCKET_IMPMAIN(t) (((t) == XML_SCHEMA_SCHEMA_MAIN) || \
  180. ((t) == XML_SCHEMA_SCHEMA_IMPORT))
  181. #define WXS_IMPBUCKET(b) ((xmlSchemaImportPtr) (b))
  182. #define WXS_INCBUCKET(b) ((xmlSchemaIncludePtr) (b))
  183. /*
  184. * Macros for complex/simple types.
  185. */
  186. #define WXS_IS_ANYTYPE(i) \
  187. (( (i)->type == XML_SCHEMA_TYPE_BASIC) && \
  188. ( (WXS_TYPE_CAST (i))->builtInType == XML_SCHEMAS_ANYTYPE))
  189. #define WXS_IS_COMPLEX(i) \
  190. (((i)->type == XML_SCHEMA_TYPE_COMPLEX) || \
  191. ((i)->builtInType == XML_SCHEMAS_ANYTYPE))
  192. #define WXS_IS_SIMPLE(item) \
  193. ((item->type == XML_SCHEMA_TYPE_SIMPLE) || \
  194. ((item->type == XML_SCHEMA_TYPE_BASIC) && \
  195. (item->builtInType != XML_SCHEMAS_ANYTYPE)))
  196. #define WXS_IS_ANY_SIMPLE_TYPE(i) \
  197. (((i)->type == XML_SCHEMA_TYPE_BASIC) && \
  198. ((i)->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  199. #define WXS_IS_RESTRICTION(t) \
  200. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION)
  201. #define WXS_IS_EXTENSION(t) \
  202. ((t)->flags & XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION)
  203. #define WXS_IS_TYPE_NOT_FIXED(i) \
  204. (((i)->type != XML_SCHEMA_TYPE_BASIC) && \
  205. (((i)->flags & XML_SCHEMAS_TYPE_INTERNAL_RESOLVED) == 0))
  206. #define WXS_IS_TYPE_NOT_FIXED_1(item) \
  207. (((item)->type != XML_SCHEMA_TYPE_BASIC) && \
  208. (((item)->flags & XML_SCHEMAS_TYPE_FIXUP_1) == 0))
  209. #define WXS_TYPE_IS_GLOBAL(t) ((t)->flags & XML_SCHEMAS_TYPE_GLOBAL)
  210. #define WXS_TYPE_IS_LOCAL(t) (((t)->flags & XML_SCHEMAS_TYPE_GLOBAL) == 0)
  211. /*
  212. * Macros for exclusively for complex types.
  213. */
  214. #define WXS_HAS_COMPLEX_CONTENT(item) \
  215. ((item->contentType == XML_SCHEMA_CONTENT_MIXED) || \
  216. (item->contentType == XML_SCHEMA_CONTENT_EMPTY) || \
  217. (item->contentType == XML_SCHEMA_CONTENT_ELEMENTS))
  218. #define WXS_HAS_SIMPLE_CONTENT(item) \
  219. ((item->contentType == XML_SCHEMA_CONTENT_SIMPLE) || \
  220. (item->contentType == XML_SCHEMA_CONTENT_BASIC))
  221. #define WXS_HAS_MIXED_CONTENT(item) \
  222. (item->contentType == XML_SCHEMA_CONTENT_MIXED)
  223. #define WXS_EMPTIABLE(t) \
  224. (xmlSchemaIsParticleEmptiable(WXS_PTC_CAST (t)->subtypes))
  225. #define WXS_TYPE_CONTENTTYPE(t) (t)->subtypes
  226. #define WXS_TYPE_PARTICLE(t) WXS_PTC_CAST (t)->subtypes
  227. #define WXS_TYPE_PARTICLE_TERM(t) WXS_PARTICLE_TERM(WXS_TYPE_PARTICLE(t))
  228. /*
  229. * Macros for exclusively for simple types.
  230. */
  231. #define WXS_LIST_ITEMTYPE(t) (t)->subtypes
  232. #define WXS_IS_ATOMIC(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_ATOMIC)
  233. #define WXS_IS_LIST(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_LIST)
  234. #define WXS_IS_UNION(t) (t->flags & XML_SCHEMAS_TYPE_VARIETY_UNION)
  235. /*
  236. * Misc parser context macros.
  237. */
  238. #define WXS_CONSTRUCTOR(ctx) (ctx)->constructor
  239. #define WXS_HAS_BUCKETS(ctx) \
  240. ( (WXS_CONSTRUCTOR((ctx))->buckets != NULL) && \
  241. (WXS_CONSTRUCTOR((ctx))->buckets->nbItems > 0) )
  242. #define WXS_SUBST_GROUPS(ctx) WXS_CONSTRUCTOR((ctx))->substGroups
  243. #define WXS_BUCKET(ctx) WXS_CONSTRUCTOR((ctx))->bucket
  244. #define WXS_SCHEMA(ctx) (ctx)->schema
  245. #define WXS_ADD_LOCAL(ctx, item) \
  246. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->locals), 10, item)
  247. #define WXS_ADD_GLOBAL(ctx, item) \
  248. xmlSchemaAddItemSize(&(WXS_BUCKET(ctx)->globals), 5, item)
  249. #define WXS_ADD_PENDING(ctx, item) \
  250. xmlSchemaAddItemSize(&((ctx)->constructor->pending), 10, item)
  251. /*
  252. * xmlSchemaItemList macros.
  253. */
  254. #define WXS_ILIST_IS_EMPTY(l) ((l == NULL) || ((l)->nbItems == 0))
  255. /*
  256. * Misc macros.
  257. */
  258. #define IS_SCHEMA(node, type) \
  259. ((node != NULL) && (node->ns != NULL) && \
  260. (xmlStrEqual(node->name, (const xmlChar *) type)) && \
  261. (xmlStrEqual(node->ns->href, xmlSchemaNs)))
  262. #define FREE_AND_NULL(str) if ((str) != NULL) { xmlFree((xmlChar *) (str)); str = NULL; }
  263. /*
  264. * Since we put the default/fixed values into the dict, we can
  265. * use pointer comparison for those values.
  266. * REMOVED: (xmlStrEqual((v1), (v2)))
  267. */
  268. #define WXS_ARE_DEFAULT_STR_EQUAL(v1, v2) ((v1) == (v2))
  269. #define INODE_NILLED(item) (item->flags & XML_SCHEMA_ELEM_INFO_NILLED)
  270. #define CAN_PARSE_SCHEMA(b) (((b)->doc != NULL) && ((b)->parsed == 0))
  271. #define HFAILURE if (res == -1) goto exit_failure;
  272. #define HERROR if (res != 0) goto exit_error;
  273. #define HSTOP(ctx) if ((ctx)->stop) goto exit;
  274. /*
  275. * Some flags used for various schema constraints.
  276. */
  277. #define SUBSET_RESTRICTION 1<<0
  278. #define SUBSET_EXTENSION 1<<1
  279. #define SUBSET_SUBSTITUTION 1<<2
  280. #define SUBSET_LIST 1<<3
  281. #define SUBSET_UNION 1<<4
  282. typedef struct _xmlSchemaNodeInfo xmlSchemaNodeInfo;
  283. typedef xmlSchemaNodeInfo *xmlSchemaNodeInfoPtr;
  284. typedef struct _xmlSchemaItemList xmlSchemaItemList;
  285. typedef xmlSchemaItemList *xmlSchemaItemListPtr;
  286. struct _xmlSchemaItemList {
  287. void **items; /* used for dynamic addition of schemata */
  288. int nbItems; /* used for dynamic addition of schemata */
  289. int sizeItems; /* used for dynamic addition of schemata */
  290. };
  291. #define XML_SCHEMA_CTXT_PARSER 1
  292. #define XML_SCHEMA_CTXT_VALIDATOR 2
  293. typedef struct _xmlSchemaAbstractCtxt xmlSchemaAbstractCtxt;
  294. typedef xmlSchemaAbstractCtxt *xmlSchemaAbstractCtxtPtr;
  295. struct _xmlSchemaAbstractCtxt {
  296. int type; /* E.g. XML_SCHEMA_CTXT_VALIDATOR */
  297. void *dummy; /* Fix alignment issues */
  298. };
  299. typedef struct _xmlSchemaBucket xmlSchemaBucket;
  300. typedef xmlSchemaBucket *xmlSchemaBucketPtr;
  301. #define XML_SCHEMA_SCHEMA_MAIN 0
  302. #define XML_SCHEMA_SCHEMA_IMPORT 1
  303. #define XML_SCHEMA_SCHEMA_INCLUDE 2
  304. #define XML_SCHEMA_SCHEMA_REDEFINE 3
  305. /**
  306. * xmlSchemaSchemaRelation:
  307. *
  308. * Used to create a graph of schema relationships.
  309. */
  310. typedef struct _xmlSchemaSchemaRelation xmlSchemaSchemaRelation;
  311. typedef xmlSchemaSchemaRelation *xmlSchemaSchemaRelationPtr;
  312. struct _xmlSchemaSchemaRelation {
  313. xmlSchemaSchemaRelationPtr next;
  314. int type; /* E.g. XML_SCHEMA_SCHEMA_IMPORT */
  315. const xmlChar *importNamespace;
  316. xmlSchemaBucketPtr bucket;
  317. };
  318. #define XML_SCHEMA_BUCKET_MARKED 1<<0
  319. #define XML_SCHEMA_BUCKET_COMPS_ADDED 1<<1
  320. struct _xmlSchemaBucket {
  321. int type;
  322. int flags;
  323. const xmlChar *schemaLocation;
  324. const xmlChar *origTargetNamespace;
  325. const xmlChar *targetNamespace;
  326. xmlDocPtr doc;
  327. xmlSchemaSchemaRelationPtr relations;
  328. int located;
  329. int parsed;
  330. int imported;
  331. int preserveDoc;
  332. xmlSchemaItemListPtr globals; /* Global components. */
  333. xmlSchemaItemListPtr locals; /* Local components. */
  334. };
  335. /**
  336. * xmlSchemaImport:
  337. * (extends xmlSchemaBucket)
  338. *
  339. * Reflects a schema. Holds some information
  340. * about the schema and its toplevel components. Duplicate
  341. * toplevel components are not checked at this level.
  342. */
  343. typedef struct _xmlSchemaImport xmlSchemaImport;
  344. typedef xmlSchemaImport *xmlSchemaImportPtr;
  345. struct _xmlSchemaImport {
  346. int type; /* Main OR import OR include. */
  347. int flags;
  348. const xmlChar *schemaLocation; /* The URI of the schema document. */
  349. /* For chameleon includes, @origTargetNamespace will be NULL */
  350. const xmlChar *origTargetNamespace;
  351. /*
  352. * For chameleon includes, @targetNamespace will be the
  353. * targetNamespace of the including schema.
  354. */
  355. const xmlChar *targetNamespace;
  356. xmlDocPtr doc; /* The schema node-tree. */
  357. /* @relations will hold any included/imported/redefined schemas. */
  358. xmlSchemaSchemaRelationPtr relations;
  359. int located;
  360. int parsed;
  361. int imported;
  362. int preserveDoc;
  363. xmlSchemaItemListPtr globals;
  364. xmlSchemaItemListPtr locals;
  365. /* The imported schema. */
  366. xmlSchemaPtr schema;
  367. };
  368. /*
  369. * (extends xmlSchemaBucket)
  370. */
  371. typedef struct _xmlSchemaInclude xmlSchemaInclude;
  372. typedef xmlSchemaInclude *xmlSchemaIncludePtr;
  373. struct _xmlSchemaInclude {
  374. int type;
  375. int flags;
  376. const xmlChar *schemaLocation;
  377. const xmlChar *origTargetNamespace;
  378. const xmlChar *targetNamespace;
  379. xmlDocPtr doc;
  380. xmlSchemaSchemaRelationPtr relations;
  381. int located;
  382. int parsed;
  383. int imported;
  384. int preserveDoc;
  385. xmlSchemaItemListPtr globals; /* Global components. */
  386. xmlSchemaItemListPtr locals; /* Local components. */
  387. /* The owning main or import schema bucket. */
  388. xmlSchemaImportPtr ownerImport;
  389. };
  390. /**
  391. * xmlSchemaBasicItem:
  392. *
  393. * The abstract base type for schema components.
  394. */
  395. typedef struct _xmlSchemaBasicItem xmlSchemaBasicItem;
  396. typedef xmlSchemaBasicItem *xmlSchemaBasicItemPtr;
  397. struct _xmlSchemaBasicItem {
  398. xmlSchemaTypeType type;
  399. void *dummy; /* Fix alignment issues */
  400. };
  401. /**
  402. * xmlSchemaAnnotItem:
  403. *
  404. * The abstract base type for annotated schema components.
  405. * (Extends xmlSchemaBasicItem)
  406. */
  407. typedef struct _xmlSchemaAnnotItem xmlSchemaAnnotItem;
  408. typedef xmlSchemaAnnotItem *xmlSchemaAnnotItemPtr;
  409. struct _xmlSchemaAnnotItem {
  410. xmlSchemaTypeType type;
  411. xmlSchemaAnnotPtr annot;
  412. };
  413. /**
  414. * xmlSchemaTreeItem:
  415. *
  416. * The abstract base type for tree-like structured schema components.
  417. * (Extends xmlSchemaAnnotItem)
  418. */
  419. typedef struct _xmlSchemaTreeItem xmlSchemaTreeItem;
  420. typedef xmlSchemaTreeItem *xmlSchemaTreeItemPtr;
  421. struct _xmlSchemaTreeItem {
  422. xmlSchemaTypeType type;
  423. xmlSchemaAnnotPtr annot;
  424. xmlSchemaTreeItemPtr next;
  425. xmlSchemaTreeItemPtr children;
  426. };
  427. #define XML_SCHEMA_ATTR_USE_FIXED 1<<0
  428. /**
  429. * xmlSchemaAttributeUsePtr:
  430. *
  431. * The abstract base type for tree-like structured schema components.
  432. * (Extends xmlSchemaTreeItem)
  433. */
  434. typedef struct _xmlSchemaAttributeUse xmlSchemaAttributeUse;
  435. typedef xmlSchemaAttributeUse *xmlSchemaAttributeUsePtr;
  436. struct _xmlSchemaAttributeUse {
  437. xmlSchemaTypeType type;
  438. xmlSchemaAnnotPtr annot;
  439. xmlSchemaAttributeUsePtr next; /* The next attr. use. */
  440. /*
  441. * The attr. decl. OR a QName-ref. to an attr. decl. OR
  442. * a QName-ref. to an attribute group definition.
  443. */
  444. xmlSchemaAttributePtr attrDecl;
  445. int flags;
  446. xmlNodePtr node;
  447. int occurs; /* required, optional */
  448. const xmlChar * defValue;
  449. xmlSchemaValPtr defVal;
  450. };
  451. /**
  452. * xmlSchemaAttributeUseProhibPtr:
  453. *
  454. * A helper component to reflect attribute prohibitions.
  455. * (Extends xmlSchemaBasicItem)
  456. */
  457. typedef struct _xmlSchemaAttributeUseProhib xmlSchemaAttributeUseProhib;
  458. typedef xmlSchemaAttributeUseProhib *xmlSchemaAttributeUseProhibPtr;
  459. struct _xmlSchemaAttributeUseProhib {
  460. xmlSchemaTypeType type; /* == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB */
  461. xmlNodePtr node;
  462. const xmlChar *name;
  463. const xmlChar *targetNamespace;
  464. int isRef;
  465. };
  466. /**
  467. * xmlSchemaRedef:
  468. */
  469. typedef struct _xmlSchemaRedef xmlSchemaRedef;
  470. typedef xmlSchemaRedef *xmlSchemaRedefPtr;
  471. struct _xmlSchemaRedef {
  472. xmlSchemaRedefPtr next;
  473. xmlSchemaBasicItemPtr item; /* The redefining component. */
  474. xmlSchemaBasicItemPtr reference; /* The referencing component. */
  475. xmlSchemaBasicItemPtr target; /* The to-be-redefined component. */
  476. const xmlChar *refName; /* The name of the to-be-redefined component. */
  477. const xmlChar *refTargetNs; /* The target namespace of the
  478. to-be-redefined comp. */
  479. xmlSchemaBucketPtr targetBucket; /* The redefined schema. */
  480. };
  481. /**
  482. * xmlSchemaConstructionCtxt:
  483. */
  484. typedef struct _xmlSchemaConstructionCtxt xmlSchemaConstructionCtxt;
  485. typedef xmlSchemaConstructionCtxt *xmlSchemaConstructionCtxtPtr;
  486. struct _xmlSchemaConstructionCtxt {
  487. xmlSchemaPtr mainSchema; /* The main schema. */
  488. xmlSchemaBucketPtr mainBucket; /* The main schema bucket */
  489. xmlDictPtr dict;
  490. xmlSchemaItemListPtr buckets; /* List of schema buckets. */
  491. /* xmlSchemaItemListPtr relations; */ /* List of schema relations. */
  492. xmlSchemaBucketPtr bucket; /* The current schema bucket */
  493. xmlSchemaItemListPtr pending; /* All Components of all schemas that
  494. need to be fixed. */
  495. xmlHashTablePtr substGroups;
  496. xmlSchemaRedefPtr redefs;
  497. xmlSchemaRedefPtr lastRedef;
  498. };
  499. #define XML_SCHEMAS_PARSE_ERROR 1
  500. #define SCHEMAS_PARSE_OPTIONS XML_PARSE_NOENT
  501. struct _xmlSchemaParserCtxt {
  502. int type;
  503. void *errCtxt; /* user specific error context */
  504. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  505. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  506. int err;
  507. int nberrors;
  508. xmlStructuredErrorFunc serror;
  509. xmlSchemaConstructionCtxtPtr constructor;
  510. int ownsConstructor; /* TODO: Move this to parser *flags*. */
  511. /* xmlSchemaPtr topschema; */
  512. /* xmlHashTablePtr namespaces; */
  513. xmlSchemaPtr schema; /* The main schema in use */
  514. int counter;
  515. const xmlChar *URL;
  516. xmlDocPtr doc;
  517. int preserve; /* Whether the doc should be freed */
  518. const char *buffer;
  519. int size;
  520. /*
  521. * Used to build complex element content models
  522. */
  523. xmlAutomataPtr am;
  524. xmlAutomataStatePtr start;
  525. xmlAutomataStatePtr end;
  526. xmlAutomataStatePtr state;
  527. xmlDictPtr dict; /* dictionary for interned string names */
  528. xmlSchemaTypePtr ctxtType; /* The current context simple/complex type */
  529. int options;
  530. xmlSchemaValidCtxtPtr vctxt;
  531. int isS4S;
  532. int isRedefine;
  533. int xsiAssemble;
  534. int stop; /* If the parser should stop; i.e. a critical error. */
  535. const xmlChar *targetNamespace;
  536. xmlSchemaBucketPtr redefined; /* The schema to be redefined. */
  537. xmlSchemaRedefPtr redef; /* Used for redefinitions. */
  538. int redefCounter; /* Used for redefinitions. */
  539. xmlSchemaItemListPtr attrProhibs;
  540. };
  541. /**
  542. * xmlSchemaQNameRef:
  543. *
  544. * A component reference item (not a schema component)
  545. * (Extends xmlSchemaBasicItem)
  546. */
  547. typedef struct _xmlSchemaQNameRef xmlSchemaQNameRef;
  548. typedef xmlSchemaQNameRef *xmlSchemaQNameRefPtr;
  549. struct _xmlSchemaQNameRef {
  550. xmlSchemaTypeType type;
  551. xmlSchemaBasicItemPtr item; /* The resolved referenced item. */
  552. xmlSchemaTypeType itemType;
  553. const xmlChar *name;
  554. const xmlChar *targetNamespace;
  555. xmlNodePtr node;
  556. };
  557. /**
  558. * xmlSchemaParticle:
  559. *
  560. * A particle component.
  561. * (Extends xmlSchemaTreeItem)
  562. */
  563. typedef struct _xmlSchemaParticle xmlSchemaParticle;
  564. typedef xmlSchemaParticle *xmlSchemaParticlePtr;
  565. struct _xmlSchemaParticle {
  566. xmlSchemaTypeType type;
  567. xmlSchemaAnnotPtr annot;
  568. xmlSchemaTreeItemPtr next; /* next particle */
  569. xmlSchemaTreeItemPtr children; /* the "term" (e.g. a model group,
  570. a group definition, a XML_SCHEMA_EXTRA_QNAMEREF (if a reference),
  571. etc.) */
  572. int minOccurs;
  573. int maxOccurs;
  574. xmlNodePtr node;
  575. };
  576. /**
  577. * xmlSchemaModelGroup:
  578. *
  579. * A model group component.
  580. * (Extends xmlSchemaTreeItem)
  581. */
  582. typedef struct _xmlSchemaModelGroup xmlSchemaModelGroup;
  583. typedef xmlSchemaModelGroup *xmlSchemaModelGroupPtr;
  584. struct _xmlSchemaModelGroup {
  585. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_SEQUENCE, XML_SCHEMA_TYPE_CHOICE, XML_SCHEMA_TYPE_ALL */
  586. xmlSchemaAnnotPtr annot;
  587. xmlSchemaTreeItemPtr next; /* not used */
  588. xmlSchemaTreeItemPtr children; /* first particle (OR "element decl" OR "wildcard") */
  589. xmlNodePtr node;
  590. };
  591. #define XML_SCHEMA_MODEL_GROUP_DEF_MARKED 1<<0
  592. #define XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED 1<<1
  593. /**
  594. * xmlSchemaModelGroupDef:
  595. *
  596. * A model group definition component.
  597. * (Extends xmlSchemaTreeItem)
  598. */
  599. typedef struct _xmlSchemaModelGroupDef xmlSchemaModelGroupDef;
  600. typedef xmlSchemaModelGroupDef *xmlSchemaModelGroupDefPtr;
  601. struct _xmlSchemaModelGroupDef {
  602. xmlSchemaTypeType type; /* XML_SCHEMA_TYPE_GROUP */
  603. xmlSchemaAnnotPtr annot;
  604. xmlSchemaTreeItemPtr next; /* not used */
  605. xmlSchemaTreeItemPtr children; /* the "model group" */
  606. const xmlChar *name;
  607. const xmlChar *targetNamespace;
  608. xmlNodePtr node;
  609. int flags;
  610. };
  611. typedef struct _xmlSchemaIDC xmlSchemaIDC;
  612. typedef xmlSchemaIDC *xmlSchemaIDCPtr;
  613. /**
  614. * xmlSchemaIDCSelect:
  615. *
  616. * The identity-constraint "field" and "selector" item, holding the
  617. * XPath expression.
  618. */
  619. typedef struct _xmlSchemaIDCSelect xmlSchemaIDCSelect;
  620. typedef xmlSchemaIDCSelect *xmlSchemaIDCSelectPtr;
  621. struct _xmlSchemaIDCSelect {
  622. xmlSchemaIDCSelectPtr next;
  623. xmlSchemaIDCPtr idc;
  624. int index; /* an index position if significant for IDC key-sequences */
  625. const xmlChar *xpath; /* the XPath expression */
  626. void *xpathComp; /* the compiled XPath expression */
  627. };
  628. /**
  629. * xmlSchemaIDC:
  630. *
  631. * The identity-constraint definition component.
  632. * (Extends xmlSchemaAnnotItem)
  633. */
  634. struct _xmlSchemaIDC {
  635. xmlSchemaTypeType type;
  636. xmlSchemaAnnotPtr annot;
  637. xmlSchemaIDCPtr next;
  638. xmlNodePtr node;
  639. const xmlChar *name;
  640. const xmlChar *targetNamespace;
  641. xmlSchemaIDCSelectPtr selector;
  642. xmlSchemaIDCSelectPtr fields;
  643. int nbFields;
  644. xmlSchemaQNameRefPtr ref;
  645. };
  646. /**
  647. * xmlSchemaIDCAug:
  648. *
  649. * The augmented IDC information used for validation.
  650. */
  651. typedef struct _xmlSchemaIDCAug xmlSchemaIDCAug;
  652. typedef xmlSchemaIDCAug *xmlSchemaIDCAugPtr;
  653. struct _xmlSchemaIDCAug {
  654. xmlSchemaIDCAugPtr next; /* next in a list */
  655. xmlSchemaIDCPtr def; /* the IDC definition */
  656. int keyrefDepth; /* the lowest tree level to which IDC
  657. tables need to be bubbled upwards */
  658. };
  659. /**
  660. * xmlSchemaPSVIIDCKeySequence:
  661. *
  662. * The key sequence of a node table item.
  663. */
  664. typedef struct _xmlSchemaPSVIIDCKey xmlSchemaPSVIIDCKey;
  665. typedef xmlSchemaPSVIIDCKey *xmlSchemaPSVIIDCKeyPtr;
  666. struct _xmlSchemaPSVIIDCKey {
  667. xmlSchemaTypePtr type;
  668. xmlSchemaValPtr val;
  669. };
  670. /**
  671. * xmlSchemaPSVIIDCNode:
  672. *
  673. * The node table item of a node table.
  674. */
  675. typedef struct _xmlSchemaPSVIIDCNode xmlSchemaPSVIIDCNode;
  676. typedef xmlSchemaPSVIIDCNode *xmlSchemaPSVIIDCNodePtr;
  677. struct _xmlSchemaPSVIIDCNode {
  678. xmlNodePtr node;
  679. xmlSchemaPSVIIDCKeyPtr *keys;
  680. int nodeLine;
  681. int nodeQNameID;
  682. };
  683. /**
  684. * xmlSchemaPSVIIDCBinding:
  685. *
  686. * The identity-constraint binding item of the [identity-constraint table].
  687. */
  688. typedef struct _xmlSchemaPSVIIDCBinding xmlSchemaPSVIIDCBinding;
  689. typedef xmlSchemaPSVIIDCBinding *xmlSchemaPSVIIDCBindingPtr;
  690. struct _xmlSchemaPSVIIDCBinding {
  691. xmlSchemaPSVIIDCBindingPtr next; /* next binding of a specific node */
  692. xmlSchemaIDCPtr definition; /* the IDC definition */
  693. xmlSchemaPSVIIDCNodePtr *nodeTable; /* array of key-sequences */
  694. int nbNodes; /* number of entries in the node table */
  695. int sizeNodes; /* size of the node table */
  696. xmlSchemaItemListPtr dupls;
  697. };
  698. #define XPATH_STATE_OBJ_TYPE_IDC_SELECTOR 1
  699. #define XPATH_STATE_OBJ_TYPE_IDC_FIELD 2
  700. #define XPATH_STATE_OBJ_MATCHES -2
  701. #define XPATH_STATE_OBJ_BLOCKED -3
  702. typedef struct _xmlSchemaIDCMatcher xmlSchemaIDCMatcher;
  703. typedef xmlSchemaIDCMatcher *xmlSchemaIDCMatcherPtr;
  704. /**
  705. * xmlSchemaIDCStateObj:
  706. *
  707. * The state object used to evaluate XPath expressions.
  708. */
  709. typedef struct _xmlSchemaIDCStateObj xmlSchemaIDCStateObj;
  710. typedef xmlSchemaIDCStateObj *xmlSchemaIDCStateObjPtr;
  711. struct _xmlSchemaIDCStateObj {
  712. int type;
  713. xmlSchemaIDCStateObjPtr next; /* next if in a list */
  714. int depth; /* depth of creation */
  715. int *history; /* list of (depth, state-id) tuples */
  716. int nbHistory;
  717. int sizeHistory;
  718. xmlSchemaIDCMatcherPtr matcher; /* the correspondent field/selector
  719. matcher */
  720. xmlSchemaIDCSelectPtr sel;
  721. void *xpathCtxt;
  722. };
  723. #define IDC_MATCHER 0
  724. /**
  725. * xmlSchemaIDCMatcher:
  726. *
  727. * Used to evaluate IDC selectors (and fields).
  728. */
  729. struct _xmlSchemaIDCMatcher {
  730. int type;
  731. int depth; /* the tree depth at creation time */
  732. xmlSchemaIDCMatcherPtr next; /* next in the list */
  733. xmlSchemaIDCMatcherPtr nextCached; /* next in the cache list */
  734. xmlSchemaIDCAugPtr aidc; /* the augmented IDC item */
  735. int idcType;
  736. xmlSchemaPSVIIDCKeyPtr **keySeqs; /* the key-sequences of the target
  737. elements */
  738. int sizeKeySeqs;
  739. xmlSchemaItemListPtr targets; /* list of target-node
  740. (xmlSchemaPSVIIDCNodePtr) entries */
  741. };
  742. /*
  743. * Element info flags.
  744. */
  745. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES 1<<0
  746. #define XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES 1<<1
  747. #define XML_SCHEMA_ELEM_INFO_NILLED 1<<2
  748. #define XML_SCHEMA_ELEM_INFO_LOCAL_TYPE 1<<3
  749. #define XML_SCHEMA_NODE_INFO_VALUE_NEEDED 1<<4
  750. #define XML_SCHEMA_ELEM_INFO_EMPTY 1<<5
  751. #define XML_SCHEMA_ELEM_INFO_HAS_CONTENT 1<<6
  752. #define XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT 1<<7
  753. #define XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT 1<<8
  754. #define XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED 1<<9
  755. #define XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE 1<<10
  756. /**
  757. * xmlSchemaNodeInfo:
  758. *
  759. * Holds information of an element node.
  760. */
  761. struct _xmlSchemaNodeInfo {
  762. int nodeType;
  763. xmlNodePtr node;
  764. int nodeLine;
  765. const xmlChar *localName;
  766. const xmlChar *nsName;
  767. const xmlChar *value;
  768. xmlSchemaValPtr val; /* the pre-computed value if any */
  769. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  770. int flags; /* combination of node info flags */
  771. int valNeeded;
  772. int normVal;
  773. xmlSchemaElementPtr decl; /* the element/attribute declaration */
  774. int depth;
  775. xmlSchemaPSVIIDCBindingPtr idcTable; /* the table of PSVI IDC bindings
  776. for the scope element*/
  777. xmlSchemaIDCMatcherPtr idcMatchers; /* the IDC matchers for the scope
  778. element */
  779. xmlRegExecCtxtPtr regexCtxt;
  780. const xmlChar **nsBindings; /* Namespace bindings on this element */
  781. int nbNsBindings;
  782. int sizeNsBindings;
  783. int hasKeyrefs;
  784. int appliedXPath; /* Indicates that an XPath has been applied. */
  785. };
  786. #define XML_SCHEMAS_ATTR_UNKNOWN 1
  787. #define XML_SCHEMAS_ATTR_ASSESSED 2
  788. #define XML_SCHEMAS_ATTR_PROHIBITED 3
  789. #define XML_SCHEMAS_ATTR_ERR_MISSING 4
  790. #define XML_SCHEMAS_ATTR_INVALID_VALUE 5
  791. #define XML_SCHEMAS_ATTR_ERR_NO_TYPE 6
  792. #define XML_SCHEMAS_ATTR_ERR_FIXED_VALUE 7
  793. #define XML_SCHEMAS_ATTR_DEFAULT 8
  794. #define XML_SCHEMAS_ATTR_VALIDATE_VALUE 9
  795. #define XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL 10
  796. #define XML_SCHEMAS_ATTR_HAS_ATTR_USE 11
  797. #define XML_SCHEMAS_ATTR_HAS_ATTR_DECL 12
  798. #define XML_SCHEMAS_ATTR_WILD_SKIP 13
  799. #define XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL 14
  800. #define XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID 15
  801. #define XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID 16
  802. #define XML_SCHEMAS_ATTR_META 17
  803. /*
  804. * @metaType values of xmlSchemaAttrInfo.
  805. */
  806. #define XML_SCHEMA_ATTR_INFO_META_XSI_TYPE 1
  807. #define XML_SCHEMA_ATTR_INFO_META_XSI_NIL 2
  808. #define XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC 3
  809. #define XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC 4
  810. #define XML_SCHEMA_ATTR_INFO_META_XMLNS 5
  811. typedef struct _xmlSchemaAttrInfo xmlSchemaAttrInfo;
  812. typedef xmlSchemaAttrInfo *xmlSchemaAttrInfoPtr;
  813. struct _xmlSchemaAttrInfo {
  814. int nodeType;
  815. xmlNodePtr node;
  816. int nodeLine;
  817. const xmlChar *localName;
  818. const xmlChar *nsName;
  819. const xmlChar *value;
  820. xmlSchemaValPtr val; /* the pre-computed value if any */
  821. xmlSchemaTypePtr typeDef; /* the complex/simple type definition if any */
  822. int flags; /* combination of node info flags */
  823. xmlSchemaAttributePtr decl; /* the attribute declaration */
  824. xmlSchemaAttributeUsePtr use; /* the attribute use */
  825. int state;
  826. int metaType;
  827. const xmlChar *vcValue; /* the value constraint value */
  828. xmlSchemaNodeInfoPtr parent;
  829. };
  830. #define XML_SCHEMA_VALID_CTXT_FLAG_STREAM 1
  831. /**
  832. * xmlSchemaValidCtxt:
  833. *
  834. * A Schemas validation context
  835. */
  836. struct _xmlSchemaValidCtxt {
  837. int type;
  838. void *errCtxt; /* user specific data block */
  839. xmlSchemaValidityErrorFunc error; /* the callback in case of errors */
  840. xmlSchemaValidityWarningFunc warning; /* the callback in case of warning */
  841. xmlStructuredErrorFunc serror;
  842. xmlSchemaPtr schema; /* The schema in use */
  843. xmlDocPtr doc;
  844. xmlParserInputBufferPtr input;
  845. xmlCharEncoding enc;
  846. xmlSAXHandlerPtr sax;
  847. xmlParserCtxtPtr parserCtxt;
  848. void *user_data; /* TODO: What is this for? */
  849. char *filename;
  850. int err;
  851. int nberrors;
  852. xmlNodePtr node;
  853. xmlNodePtr cur;
  854. /* xmlSchemaTypePtr type; */
  855. xmlRegExecCtxtPtr regexp;
  856. xmlSchemaValPtr value;
  857. int valueWS;
  858. int options;
  859. xmlNodePtr validationRoot;
  860. xmlSchemaParserCtxtPtr pctxt;
  861. int xsiAssemble;
  862. int depth;
  863. xmlSchemaNodeInfoPtr *elemInfos; /* array of element informations */
  864. int sizeElemInfos;
  865. xmlSchemaNodeInfoPtr inode; /* the current element information */
  866. xmlSchemaIDCAugPtr aidcs; /* a list of augmented IDC informations */
  867. xmlSchemaIDCStateObjPtr xpathStates; /* first active state object. */
  868. xmlSchemaIDCStateObjPtr xpathStatePool; /* first stored state object. */
  869. xmlSchemaIDCMatcherPtr idcMatcherCache; /* Cache for IDC matcher objects. */
  870. xmlSchemaPSVIIDCNodePtr *idcNodes; /* list of all IDC node-table entries*/
  871. int nbIdcNodes;
  872. int sizeIdcNodes;
  873. xmlSchemaPSVIIDCKeyPtr *idcKeys; /* list of all IDC node-table entries */
  874. int nbIdcKeys;
  875. int sizeIdcKeys;
  876. int flags;
  877. xmlDictPtr dict;
  878. #ifdef LIBXML_READER_ENABLED
  879. xmlTextReaderPtr reader;
  880. #endif
  881. xmlSchemaAttrInfoPtr *attrInfos;
  882. int nbAttrInfos;
  883. int sizeAttrInfos;
  884. int skipDepth;
  885. xmlSchemaItemListPtr nodeQNames;
  886. int hasKeyrefs;
  887. int createIDCNodeTables;
  888. int psviExposeIDCNodeTables;
  889. /* Locator for error reporting in streaming mode */
  890. xmlSchemaValidityLocatorFunc locFunc;
  891. void *locCtxt;
  892. };
  893. /**
  894. * xmlSchemaSubstGroup:
  895. *
  896. *
  897. */
  898. typedef struct _xmlSchemaSubstGroup xmlSchemaSubstGroup;
  899. typedef xmlSchemaSubstGroup *xmlSchemaSubstGroupPtr;
  900. struct _xmlSchemaSubstGroup {
  901. xmlSchemaElementPtr head;
  902. xmlSchemaItemListPtr members;
  903. };
  904. /************************************************************************
  905. * *
  906. * Some predeclarations *
  907. * *
  908. ************************************************************************/
  909. static int xmlSchemaParseInclude(xmlSchemaParserCtxtPtr ctxt,
  910. xmlSchemaPtr schema,
  911. xmlNodePtr node);
  912. static int xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr ctxt,
  913. xmlSchemaPtr schema,
  914. xmlNodePtr node);
  915. static int
  916. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  917. xmlSchemaAbstractCtxtPtr ctxt);
  918. static const xmlChar *
  919. xmlSchemaFacetTypeToString(xmlSchemaTypeType type);
  920. static int
  921. xmlSchemaParseImport(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  922. xmlNodePtr node);
  923. static int
  924. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  925. xmlSchemaParserCtxtPtr ctxt);
  926. static void
  927. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt);
  928. static xmlSchemaWhitespaceValueType
  929. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type);
  930. static xmlSchemaTreeItemPtr
  931. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  932. xmlNodePtr node, xmlSchemaTypeType type,
  933. int withParticle);
  934. static const xmlChar *
  935. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item);
  936. static xmlSchemaTypeLinkPtr
  937. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type);
  938. static void
  939. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  940. const char *funcName,
  941. const char *message) LIBXML_ATTR_FORMAT(3,0);
  942. static int
  943. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr ctxt,
  944. xmlSchemaTypePtr type,
  945. xmlSchemaTypePtr baseType,
  946. int subset);
  947. static void
  948. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  949. xmlSchemaParserCtxtPtr ctxt);
  950. static void
  951. xmlSchemaComponentListFree(xmlSchemaItemListPtr list);
  952. static xmlSchemaQNameRefPtr
  953. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  954. xmlSchemaPtr schema,
  955. xmlNodePtr node);
  956. /************************************************************************
  957. * *
  958. * Helper functions *
  959. * *
  960. ************************************************************************/
  961. /**
  962. * xmlSchemaItemTypeToStr:
  963. * @type: the type of the schema item
  964. *
  965. * Returns the component name of a schema item.
  966. */
  967. static const xmlChar *
  968. xmlSchemaItemTypeToStr(xmlSchemaTypeType type)
  969. {
  970. switch (type) {
  971. case XML_SCHEMA_TYPE_BASIC:
  972. return(BAD_CAST "simple type definition");
  973. case XML_SCHEMA_TYPE_SIMPLE:
  974. return(BAD_CAST "simple type definition");
  975. case XML_SCHEMA_TYPE_COMPLEX:
  976. return(BAD_CAST "complex type definition");
  977. case XML_SCHEMA_TYPE_ELEMENT:
  978. return(BAD_CAST "element declaration");
  979. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  980. return(BAD_CAST "attribute use");
  981. case XML_SCHEMA_TYPE_ATTRIBUTE:
  982. return(BAD_CAST "attribute declaration");
  983. case XML_SCHEMA_TYPE_GROUP:
  984. return(BAD_CAST "model group definition");
  985. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  986. return(BAD_CAST "attribute group definition");
  987. case XML_SCHEMA_TYPE_NOTATION:
  988. return(BAD_CAST "notation declaration");
  989. case XML_SCHEMA_TYPE_SEQUENCE:
  990. return(BAD_CAST "model group (sequence)");
  991. case XML_SCHEMA_TYPE_CHOICE:
  992. return(BAD_CAST "model group (choice)");
  993. case XML_SCHEMA_TYPE_ALL:
  994. return(BAD_CAST "model group (all)");
  995. case XML_SCHEMA_TYPE_PARTICLE:
  996. return(BAD_CAST "particle");
  997. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  998. return(BAD_CAST "unique identity-constraint");
  999. /* return(BAD_CAST "IDC (unique)"); */
  1000. case XML_SCHEMA_TYPE_IDC_KEY:
  1001. return(BAD_CAST "key identity-constraint");
  1002. /* return(BAD_CAST "IDC (key)"); */
  1003. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1004. return(BAD_CAST "keyref identity-constraint");
  1005. /* return(BAD_CAST "IDC (keyref)"); */
  1006. case XML_SCHEMA_TYPE_ANY:
  1007. return(BAD_CAST "wildcard (any)");
  1008. case XML_SCHEMA_EXTRA_QNAMEREF:
  1009. return(BAD_CAST "[helper component] QName reference");
  1010. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  1011. return(BAD_CAST "[helper component] attribute use prohibition");
  1012. default:
  1013. return(BAD_CAST "Not a schema component");
  1014. }
  1015. }
  1016. /**
  1017. * xmlSchemaGetComponentTypeStr:
  1018. * @type: the type of the schema item
  1019. *
  1020. * Returns the component name of a schema item.
  1021. */
  1022. static const xmlChar *
  1023. xmlSchemaGetComponentTypeStr(xmlSchemaBasicItemPtr item)
  1024. {
  1025. switch (item->type) {
  1026. case XML_SCHEMA_TYPE_BASIC:
  1027. if (WXS_IS_COMPLEX(WXS_TYPE_CAST item))
  1028. return(BAD_CAST "complex type definition");
  1029. else
  1030. return(BAD_CAST "simple type definition");
  1031. default:
  1032. return(xmlSchemaItemTypeToStr(item->type));
  1033. }
  1034. }
  1035. /**
  1036. * xmlSchemaGetComponentNode:
  1037. * @item: a schema component
  1038. *
  1039. * Returns node associated with the schema component.
  1040. * NOTE that such a node need not be available; plus, a component's
  1041. * node need not to reflect the component directly, since there is no
  1042. * one-to-one relationship between the XML Schema representation and
  1043. * the component representation.
  1044. */
  1045. static xmlNodePtr
  1046. xmlSchemaGetComponentNode(xmlSchemaBasicItemPtr item)
  1047. {
  1048. switch (item->type) {
  1049. case XML_SCHEMA_TYPE_ELEMENT:
  1050. return (((xmlSchemaElementPtr) item)->node);
  1051. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1052. return (((xmlSchemaAttributePtr) item)->node);
  1053. case XML_SCHEMA_TYPE_COMPLEX:
  1054. case XML_SCHEMA_TYPE_SIMPLE:
  1055. return (((xmlSchemaTypePtr) item)->node);
  1056. case XML_SCHEMA_TYPE_ANY:
  1057. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1058. return (((xmlSchemaWildcardPtr) item)->node);
  1059. case XML_SCHEMA_TYPE_PARTICLE:
  1060. return (((xmlSchemaParticlePtr) item)->node);
  1061. case XML_SCHEMA_TYPE_SEQUENCE:
  1062. case XML_SCHEMA_TYPE_CHOICE:
  1063. case XML_SCHEMA_TYPE_ALL:
  1064. return (((xmlSchemaModelGroupPtr) item)->node);
  1065. case XML_SCHEMA_TYPE_GROUP:
  1066. return (((xmlSchemaModelGroupDefPtr) item)->node);
  1067. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1068. return (((xmlSchemaAttributeGroupPtr) item)->node);
  1069. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1070. case XML_SCHEMA_TYPE_IDC_KEY:
  1071. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1072. return (((xmlSchemaIDCPtr) item)->node);
  1073. case XML_SCHEMA_EXTRA_QNAMEREF:
  1074. return(((xmlSchemaQNameRefPtr) item)->node);
  1075. /* TODO: What to do with NOTATIONs?
  1076. case XML_SCHEMA_TYPE_NOTATION:
  1077. return (((xmlSchemaNotationPtr) item)->node);
  1078. */
  1079. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1080. return (((xmlSchemaAttributeUsePtr) item)->node);
  1081. default:
  1082. return (NULL);
  1083. }
  1084. }
  1085. #if 0
  1086. /**
  1087. * xmlSchemaGetNextComponent:
  1088. * @item: a schema component
  1089. *
  1090. * Returns the next sibling of the schema component.
  1091. */
  1092. static xmlSchemaBasicItemPtr
  1093. xmlSchemaGetNextComponent(xmlSchemaBasicItemPtr item)
  1094. {
  1095. switch (item->type) {
  1096. case XML_SCHEMA_TYPE_ELEMENT:
  1097. return ((xmlSchemaBasicItemPtr) ((xmlSchemaElementPtr) item)->next);
  1098. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1099. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributePtr) item)->next);
  1100. case XML_SCHEMA_TYPE_COMPLEX:
  1101. case XML_SCHEMA_TYPE_SIMPLE:
  1102. return ((xmlSchemaBasicItemPtr) ((xmlSchemaTypePtr) item)->next);
  1103. case XML_SCHEMA_TYPE_ANY:
  1104. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1105. return (NULL);
  1106. case XML_SCHEMA_TYPE_PARTICLE:
  1107. return ((xmlSchemaBasicItemPtr) ((xmlSchemaParticlePtr) item)->next);
  1108. case XML_SCHEMA_TYPE_SEQUENCE:
  1109. case XML_SCHEMA_TYPE_CHOICE:
  1110. case XML_SCHEMA_TYPE_ALL:
  1111. return (NULL);
  1112. case XML_SCHEMA_TYPE_GROUP:
  1113. return (NULL);
  1114. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1115. return ((xmlSchemaBasicItemPtr) ((xmlSchemaAttributeGroupPtr) item)->next);
  1116. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1117. case XML_SCHEMA_TYPE_IDC_KEY:
  1118. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1119. return ((xmlSchemaBasicItemPtr) ((xmlSchemaIDCPtr) item)->next);
  1120. default:
  1121. return (NULL);
  1122. }
  1123. }
  1124. #endif
  1125. /**
  1126. * xmlSchemaFormatQName:
  1127. * @buf: the string buffer
  1128. * @namespaceName: the namespace name
  1129. * @localName: the local name
  1130. *
  1131. * Returns the given QName in the format "{namespaceName}localName" or
  1132. * just "localName" if @namespaceName is NULL.
  1133. *
  1134. * Returns the localName if @namespaceName is NULL, a formatted
  1135. * string otherwise.
  1136. */
  1137. static const xmlChar*
  1138. xmlSchemaFormatQName(xmlChar **buf,
  1139. const xmlChar *namespaceName,
  1140. const xmlChar *localName)
  1141. {
  1142. FREE_AND_NULL(*buf)
  1143. if (namespaceName != NULL) {
  1144. *buf = xmlStrdup(BAD_CAST "{");
  1145. *buf = xmlStrcat(*buf, namespaceName);
  1146. *buf = xmlStrcat(*buf, BAD_CAST "}");
  1147. }
  1148. if (localName != NULL) {
  1149. if (namespaceName == NULL)
  1150. return(localName);
  1151. *buf = xmlStrcat(*buf, localName);
  1152. } else {
  1153. *buf = xmlStrcat(*buf, BAD_CAST "(NULL)");
  1154. }
  1155. return ((const xmlChar *) *buf);
  1156. }
  1157. static const xmlChar*
  1158. xmlSchemaFormatQNameNs(xmlChar **buf, xmlNsPtr ns, const xmlChar *localName)
  1159. {
  1160. if (ns != NULL)
  1161. return (xmlSchemaFormatQName(buf, ns->href, localName));
  1162. else
  1163. return (xmlSchemaFormatQName(buf, NULL, localName));
  1164. }
  1165. static const xmlChar *
  1166. xmlSchemaGetComponentName(xmlSchemaBasicItemPtr item)
  1167. {
  1168. switch (item->type) {
  1169. case XML_SCHEMA_TYPE_ELEMENT:
  1170. return (((xmlSchemaElementPtr) item)->name);
  1171. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1172. return (((xmlSchemaAttributePtr) item)->name);
  1173. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1174. return (((xmlSchemaAttributeGroupPtr) item)->name);
  1175. case XML_SCHEMA_TYPE_BASIC:
  1176. case XML_SCHEMA_TYPE_SIMPLE:
  1177. case XML_SCHEMA_TYPE_COMPLEX:
  1178. return (((xmlSchemaTypePtr) item)->name);
  1179. case XML_SCHEMA_TYPE_GROUP:
  1180. return (((xmlSchemaModelGroupDefPtr) item)->name);
  1181. case XML_SCHEMA_TYPE_IDC_KEY:
  1182. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1183. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1184. return (((xmlSchemaIDCPtr) item)->name);
  1185. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1186. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1187. return(xmlSchemaGetComponentName(
  1188. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1189. } else
  1190. return(NULL);
  1191. case XML_SCHEMA_EXTRA_QNAMEREF:
  1192. return (((xmlSchemaQNameRefPtr) item)->name);
  1193. case XML_SCHEMA_TYPE_NOTATION:
  1194. return (((xmlSchemaNotationPtr) item)->name);
  1195. default:
  1196. /*
  1197. * Other components cannot have names.
  1198. */
  1199. break;
  1200. }
  1201. return (NULL);
  1202. }
  1203. #define xmlSchemaGetQNameRefName(r) (WXS_QNAME_CAST (r))->name
  1204. #define xmlSchemaGetQNameRefTargetNs(r) (WXS_QNAME_CAST (r))->targetNamespace
  1205. /*
  1206. static const xmlChar *
  1207. xmlSchemaGetQNameRefName(void *ref)
  1208. {
  1209. return(((xmlSchemaQNameRefPtr) ref)->name);
  1210. }
  1211. static const xmlChar *
  1212. xmlSchemaGetQNameRefTargetNs(void *ref)
  1213. {
  1214. return(((xmlSchemaQNameRefPtr) ref)->targetNamespace);
  1215. }
  1216. */
  1217. static const xmlChar *
  1218. xmlSchemaGetComponentTargetNs(xmlSchemaBasicItemPtr item)
  1219. {
  1220. switch (item->type) {
  1221. case XML_SCHEMA_TYPE_ELEMENT:
  1222. return (((xmlSchemaElementPtr) item)->targetNamespace);
  1223. case XML_SCHEMA_TYPE_ATTRIBUTE:
  1224. return (((xmlSchemaAttributePtr) item)->targetNamespace);
  1225. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1226. return (((xmlSchemaAttributeGroupPtr) item)->targetNamespace);
  1227. case XML_SCHEMA_TYPE_BASIC:
  1228. return (BAD_CAST "http://www.w3.org/2001/XMLSchema");
  1229. case XML_SCHEMA_TYPE_SIMPLE:
  1230. case XML_SCHEMA_TYPE_COMPLEX:
  1231. return (((xmlSchemaTypePtr) item)->targetNamespace);
  1232. case XML_SCHEMA_TYPE_GROUP:
  1233. return (((xmlSchemaModelGroupDefPtr) item)->targetNamespace);
  1234. case XML_SCHEMA_TYPE_IDC_KEY:
  1235. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1236. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1237. return (((xmlSchemaIDCPtr) item)->targetNamespace);
  1238. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  1239. if (WXS_ATTRUSE_DECL(item) != NULL) {
  1240. return(xmlSchemaGetComponentTargetNs(
  1241. WXS_BASIC_CAST WXS_ATTRUSE_DECL(item)));
  1242. }
  1243. /* TODO: Will returning NULL break something? */
  1244. break;
  1245. case XML_SCHEMA_EXTRA_QNAMEREF:
  1246. return (((xmlSchemaQNameRefPtr) item)->targetNamespace);
  1247. case XML_SCHEMA_TYPE_NOTATION:
  1248. return (((xmlSchemaNotationPtr) item)->targetNamespace);
  1249. default:
  1250. /*
  1251. * Other components cannot have names.
  1252. */
  1253. break;
  1254. }
  1255. return (NULL);
  1256. }
  1257. static const xmlChar*
  1258. xmlSchemaGetComponentQName(xmlChar **buf,
  1259. void *item)
  1260. {
  1261. return (xmlSchemaFormatQName(buf,
  1262. xmlSchemaGetComponentTargetNs((xmlSchemaBasicItemPtr) item),
  1263. xmlSchemaGetComponentName((xmlSchemaBasicItemPtr) item)));
  1264. }
  1265. static const xmlChar*
  1266. xmlSchemaGetComponentDesignation(xmlChar **buf, void *item)
  1267. {
  1268. xmlChar *str = NULL;
  1269. *buf = xmlStrcat(*buf, WXS_ITEM_TYPE_NAME(item));
  1270. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1271. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str,
  1272. (xmlSchemaBasicItemPtr) item));
  1273. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1274. FREE_AND_NULL(str);
  1275. return(*buf);
  1276. }
  1277. static const xmlChar*
  1278. xmlSchemaGetIDCDesignation(xmlChar **buf, xmlSchemaIDCPtr idc)
  1279. {
  1280. return(xmlSchemaGetComponentDesignation(buf, idc));
  1281. }
  1282. /**
  1283. * xmlSchemaWildcardPCToString:
  1284. * @pc: the type of processContents
  1285. *
  1286. * Returns a string representation of the type of
  1287. * processContents.
  1288. */
  1289. static const xmlChar *
  1290. xmlSchemaWildcardPCToString(int pc)
  1291. {
  1292. switch (pc) {
  1293. case XML_SCHEMAS_ANY_SKIP:
  1294. return (BAD_CAST "skip");
  1295. case XML_SCHEMAS_ANY_LAX:
  1296. return (BAD_CAST "lax");
  1297. case XML_SCHEMAS_ANY_STRICT:
  1298. return (BAD_CAST "strict");
  1299. default:
  1300. return (BAD_CAST "invalid process contents");
  1301. }
  1302. }
  1303. /**
  1304. * xmlSchemaGetCanonValueWhtspExt:
  1305. * @val: the precomputed value
  1306. * @retValue: the returned value
  1307. * @ws: the whitespace type of the value
  1308. *
  1309. * Get a the canonical representation of the value.
  1310. * The caller has to free the returned retValue.
  1311. *
  1312. * Returns 0 if the value could be built and -1 in case of
  1313. * API errors or if the value type is not supported yet.
  1314. */
  1315. static int
  1316. xmlSchemaGetCanonValueWhtspExt(xmlSchemaValPtr val,
  1317. xmlSchemaWhitespaceValueType ws,
  1318. xmlChar **retValue)
  1319. {
  1320. int list;
  1321. xmlSchemaValType valType;
  1322. const xmlChar *value, *value2 = NULL;
  1323. if ((retValue == NULL) || (val == NULL))
  1324. return (-1);
  1325. list = xmlSchemaValueGetNext(val) ? 1 : 0;
  1326. *retValue = NULL;
  1327. do {
  1328. value = NULL;
  1329. valType = xmlSchemaGetValType(val);
  1330. switch (valType) {
  1331. case XML_SCHEMAS_STRING:
  1332. case XML_SCHEMAS_NORMSTRING:
  1333. case XML_SCHEMAS_ANYSIMPLETYPE:
  1334. value = xmlSchemaValueGetAsString(val);
  1335. if (value != NULL) {
  1336. if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
  1337. value2 = xmlSchemaCollapseString(value);
  1338. else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
  1339. value2 = xmlSchemaWhiteSpaceReplace(value);
  1340. if (value2 != NULL)
  1341. value = value2;
  1342. }
  1343. break;
  1344. default:
  1345. if (xmlSchemaGetCanonValue(val, &value2) == -1) {
  1346. if (value2 != NULL)
  1347. xmlFree((xmlChar *) value2);
  1348. goto internal_error;
  1349. }
  1350. value = value2;
  1351. }
  1352. if (*retValue == NULL)
  1353. if (value == NULL) {
  1354. if (! list)
  1355. *retValue = xmlStrdup(BAD_CAST "");
  1356. } else
  1357. *retValue = xmlStrdup(value);
  1358. else if (value != NULL) {
  1359. /* List. */
  1360. *retValue = xmlStrcat((xmlChar *) *retValue, BAD_CAST " ");
  1361. *retValue = xmlStrcat((xmlChar *) *retValue, value);
  1362. }
  1363. FREE_AND_NULL(value2)
  1364. val = xmlSchemaValueGetNext(val);
  1365. } while (val != NULL);
  1366. return (0);
  1367. internal_error:
  1368. if (*retValue != NULL)
  1369. xmlFree((xmlChar *) (*retValue));
  1370. if (value2 != NULL)
  1371. xmlFree((xmlChar *) value2);
  1372. return (-1);
  1373. }
  1374. /**
  1375. * xmlSchemaFormatItemForReport:
  1376. * @buf: the string buffer
  1377. * @itemDes: the designation of the item
  1378. * @itemName: the name of the item
  1379. * @item: the item as an object
  1380. * @itemNode: the node of the item
  1381. * @local: the local name
  1382. * @parsing: if the function is used during the parse
  1383. *
  1384. * Returns a representation of the given item used
  1385. * for error reports.
  1386. *
  1387. * The following order is used to build the resulting
  1388. * designation if the arguments are not NULL:
  1389. * 1a. If itemDes not NULL -> itemDes
  1390. * 1b. If (itemDes not NULL) and (itemName not NULL)
  1391. * -> itemDes + itemName
  1392. * 2. If the preceding was NULL and (item not NULL) -> item
  1393. * 3. If the preceding was NULL and (itemNode not NULL) -> itemNode
  1394. *
  1395. * If the itemNode is an attribute node, the name of the attribute
  1396. * will be appended to the result.
  1397. *
  1398. * Returns the formatted string and sets @buf to the resulting value.
  1399. */
  1400. static xmlChar*
  1401. xmlSchemaFormatItemForReport(xmlChar **buf,
  1402. const xmlChar *itemDes,
  1403. xmlSchemaBasicItemPtr item,
  1404. xmlNodePtr itemNode)
  1405. {
  1406. xmlChar *str = NULL;
  1407. int named = 1;
  1408. if (*buf != NULL) {
  1409. xmlFree(*buf);
  1410. *buf = NULL;
  1411. }
  1412. if (itemDes != NULL) {
  1413. *buf = xmlStrdup(itemDes);
  1414. } else if (item != NULL) {
  1415. switch (item->type) {
  1416. case XML_SCHEMA_TYPE_BASIC: {
  1417. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1418. if (WXS_IS_ATOMIC(type))
  1419. *buf = xmlStrdup(BAD_CAST "atomic type 'xs:");
  1420. else if (WXS_IS_LIST(type))
  1421. *buf = xmlStrdup(BAD_CAST "list type 'xs:");
  1422. else if (WXS_IS_UNION(type))
  1423. *buf = xmlStrdup(BAD_CAST "union type 'xs:");
  1424. else
  1425. *buf = xmlStrdup(BAD_CAST "simple type 'xs:");
  1426. *buf = xmlStrcat(*buf, type->name);
  1427. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1428. }
  1429. break;
  1430. case XML_SCHEMA_TYPE_SIMPLE: {
  1431. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1432. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1433. *buf = xmlStrdup(BAD_CAST"");
  1434. } else {
  1435. *buf = xmlStrdup(BAD_CAST "local ");
  1436. }
  1437. if (WXS_IS_ATOMIC(type))
  1438. *buf = xmlStrcat(*buf, BAD_CAST "atomic type");
  1439. else if (WXS_IS_LIST(type))
  1440. *buf = xmlStrcat(*buf, BAD_CAST "list type");
  1441. else if (WXS_IS_UNION(type))
  1442. *buf = xmlStrcat(*buf, BAD_CAST "union type");
  1443. else
  1444. *buf = xmlStrcat(*buf, BAD_CAST "simple type");
  1445. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1446. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1447. *buf = xmlStrcat(*buf, type->name);
  1448. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1449. }
  1450. }
  1451. break;
  1452. case XML_SCHEMA_TYPE_COMPLEX: {
  1453. xmlSchemaTypePtr type = WXS_TYPE_CAST item;
  1454. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL)
  1455. *buf = xmlStrdup(BAD_CAST "");
  1456. else
  1457. *buf = xmlStrdup(BAD_CAST "local ");
  1458. *buf = xmlStrcat(*buf, BAD_CAST "complex type");
  1459. if (type->flags & XML_SCHEMAS_TYPE_GLOBAL) {
  1460. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1461. *buf = xmlStrcat(*buf, type->name);
  1462. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1463. }
  1464. }
  1465. break;
  1466. case XML_SCHEMA_TYPE_ATTRIBUTE_USE: {
  1467. xmlSchemaAttributeUsePtr ause;
  1468. ause = WXS_ATTR_USE_CAST item;
  1469. *buf = xmlStrdup(BAD_CAST "attribute use ");
  1470. if (WXS_ATTRUSE_DECL(ause) != NULL) {
  1471. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1472. *buf = xmlStrcat(*buf,
  1473. xmlSchemaGetComponentQName(&str, WXS_ATTRUSE_DECL(ause)));
  1474. FREE_AND_NULL(str)
  1475. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1476. } else {
  1477. *buf = xmlStrcat(*buf, BAD_CAST "(unknown)");
  1478. }
  1479. }
  1480. break;
  1481. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  1482. xmlSchemaAttributePtr attr;
  1483. attr = (xmlSchemaAttributePtr) item;
  1484. *buf = xmlStrdup(BAD_CAST "attribute decl.");
  1485. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1486. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1487. attr->targetNamespace, attr->name));
  1488. FREE_AND_NULL(str)
  1489. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1490. }
  1491. break;
  1492. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  1493. xmlSchemaGetComponentDesignation(buf, item);
  1494. break;
  1495. case XML_SCHEMA_TYPE_ELEMENT: {
  1496. xmlSchemaElementPtr elem;
  1497. elem = (xmlSchemaElementPtr) item;
  1498. *buf = xmlStrdup(BAD_CAST "element decl.");
  1499. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1500. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1501. elem->targetNamespace, elem->name));
  1502. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1503. }
  1504. break;
  1505. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  1506. case XML_SCHEMA_TYPE_IDC_KEY:
  1507. case XML_SCHEMA_TYPE_IDC_KEYREF:
  1508. if (item->type == XML_SCHEMA_TYPE_IDC_UNIQUE)
  1509. *buf = xmlStrdup(BAD_CAST "unique '");
  1510. else if (item->type == XML_SCHEMA_TYPE_IDC_KEY)
  1511. *buf = xmlStrdup(BAD_CAST "key '");
  1512. else
  1513. *buf = xmlStrdup(BAD_CAST "keyRef '");
  1514. *buf = xmlStrcat(*buf, ((xmlSchemaIDCPtr) item)->name);
  1515. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1516. break;
  1517. case XML_SCHEMA_TYPE_ANY:
  1518. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  1519. *buf = xmlStrdup(xmlSchemaWildcardPCToString(
  1520. ((xmlSchemaWildcardPtr) item)->processContents));
  1521. *buf = xmlStrcat(*buf, BAD_CAST " wildcard");
  1522. break;
  1523. case XML_SCHEMA_FACET_MININCLUSIVE:
  1524. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  1525. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  1526. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  1527. case XML_SCHEMA_FACET_TOTALDIGITS:
  1528. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  1529. case XML_SCHEMA_FACET_PATTERN:
  1530. case XML_SCHEMA_FACET_ENUMERATION:
  1531. case XML_SCHEMA_FACET_WHITESPACE:
  1532. case XML_SCHEMA_FACET_LENGTH:
  1533. case XML_SCHEMA_FACET_MAXLENGTH:
  1534. case XML_SCHEMA_FACET_MINLENGTH:
  1535. *buf = xmlStrdup(BAD_CAST "facet '");
  1536. *buf = xmlStrcat(*buf, xmlSchemaFacetTypeToString(item->type));
  1537. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1538. break;
  1539. case XML_SCHEMA_TYPE_GROUP: {
  1540. *buf = xmlStrdup(BAD_CAST "model group def.");
  1541. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1542. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1543. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1544. FREE_AND_NULL(str)
  1545. }
  1546. break;
  1547. case XML_SCHEMA_TYPE_SEQUENCE:
  1548. case XML_SCHEMA_TYPE_CHOICE:
  1549. case XML_SCHEMA_TYPE_ALL:
  1550. case XML_SCHEMA_TYPE_PARTICLE:
  1551. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1552. break;
  1553. case XML_SCHEMA_TYPE_NOTATION: {
  1554. *buf = xmlStrdup(WXS_ITEM_TYPE_NAME(item));
  1555. *buf = xmlStrcat(*buf, BAD_CAST " '");
  1556. *buf = xmlStrcat(*buf, xmlSchemaGetComponentQName(&str, item));
  1557. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1558. FREE_AND_NULL(str);
  1559. }
  1560. /* Falls through. */
  1561. default:
  1562. named = 0;
  1563. }
  1564. } else
  1565. named = 0;
  1566. if ((named == 0) && (itemNode != NULL)) {
  1567. xmlNodePtr elem;
  1568. if (itemNode->type == XML_ATTRIBUTE_NODE)
  1569. elem = itemNode->parent;
  1570. else
  1571. elem = itemNode;
  1572. *buf = xmlStrdup(BAD_CAST "Element '");
  1573. if (elem->ns != NULL) {
  1574. *buf = xmlStrcat(*buf,
  1575. xmlSchemaFormatQName(&str, elem->ns->href, elem->name));
  1576. FREE_AND_NULL(str)
  1577. } else
  1578. *buf = xmlStrcat(*buf, elem->name);
  1579. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1580. }
  1581. if ((itemNode != NULL) && (itemNode->type == XML_ATTRIBUTE_NODE)) {
  1582. *buf = xmlStrcat(*buf, BAD_CAST ", attribute '");
  1583. if (itemNode->ns != NULL) {
  1584. *buf = xmlStrcat(*buf, xmlSchemaFormatQName(&str,
  1585. itemNode->ns->href, itemNode->name));
  1586. FREE_AND_NULL(str)
  1587. } else
  1588. *buf = xmlStrcat(*buf, itemNode->name);
  1589. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1590. }
  1591. FREE_AND_NULL(str)
  1592. return (xmlEscapeFormatString(buf));
  1593. }
  1594. /**
  1595. * xmlSchemaFormatFacetEnumSet:
  1596. * @buf: the string buffer
  1597. * @type: the type holding the enumeration facets
  1598. *
  1599. * Builds a string consisting of all enumeration elements.
  1600. *
  1601. * Returns a string of all enumeration elements.
  1602. */
  1603. static const xmlChar *
  1604. xmlSchemaFormatFacetEnumSet(xmlSchemaAbstractCtxtPtr actxt,
  1605. xmlChar **buf, xmlSchemaTypePtr type)
  1606. {
  1607. xmlSchemaFacetPtr facet;
  1608. xmlSchemaWhitespaceValueType ws;
  1609. xmlChar *value = NULL;
  1610. int res, found = 0;
  1611. if (*buf != NULL)
  1612. xmlFree(*buf);
  1613. *buf = NULL;
  1614. do {
  1615. /*
  1616. * Use the whitespace type of the base type.
  1617. */
  1618. ws = xmlSchemaGetWhiteSpaceFacetValue(type->baseType);
  1619. for (facet = type->facets; facet != NULL; facet = facet->next) {
  1620. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  1621. continue;
  1622. found = 1;
  1623. res = xmlSchemaGetCanonValueWhtspExt(facet->val,
  1624. ws, &value);
  1625. if (res == -1) {
  1626. xmlSchemaInternalErr(actxt,
  1627. "xmlSchemaFormatFacetEnumSet",
  1628. "compute the canonical lexical representation");
  1629. if (*buf != NULL)
  1630. xmlFree(*buf);
  1631. *buf = NULL;
  1632. return (NULL);
  1633. }
  1634. if (*buf == NULL)
  1635. *buf = xmlStrdup(BAD_CAST "'");
  1636. else
  1637. *buf = xmlStrcat(*buf, BAD_CAST ", '");
  1638. *buf = xmlStrcat(*buf, BAD_CAST value);
  1639. *buf = xmlStrcat(*buf, BAD_CAST "'");
  1640. if (value != NULL) {
  1641. xmlFree((xmlChar *)value);
  1642. value = NULL;
  1643. }
  1644. }
  1645. /*
  1646. * The enumeration facet of a type restricts the enumeration
  1647. * facet of the ancestor type; i.e., such restricted enumerations
  1648. * do not belong to the set of the given type. Thus we break
  1649. * on the first found enumeration.
  1650. */
  1651. if (found)
  1652. break;
  1653. type = type->baseType;
  1654. } while ((type != NULL) && (type->type != XML_SCHEMA_TYPE_BASIC));
  1655. return ((const xmlChar *) *buf);
  1656. }
  1657. /************************************************************************
  1658. * *
  1659. * Error functions *
  1660. * *
  1661. ************************************************************************/
  1662. #if 0
  1663. static void
  1664. xmlSchemaErrMemory(const char *msg)
  1665. {
  1666. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1667. msg);
  1668. }
  1669. #endif
  1670. static void
  1671. xmlSchemaPSimpleErr(const char *msg)
  1672. {
  1673. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, NULL, NULL,
  1674. msg);
  1675. }
  1676. /**
  1677. * xmlSchemaPErrMemory:
  1678. * @node: a context node
  1679. * @extra: extra informations
  1680. *
  1681. * Handle an out of memory condition
  1682. */
  1683. static void
  1684. xmlSchemaPErrMemory(xmlSchemaParserCtxtPtr ctxt,
  1685. const char *extra, xmlNodePtr node)
  1686. {
  1687. if (ctxt != NULL)
  1688. ctxt->nberrors++;
  1689. __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
  1690. extra);
  1691. }
  1692. /**
  1693. * xmlSchemaPErr:
  1694. * @ctxt: the parsing context
  1695. * @node: the context node
  1696. * @error: the error code
  1697. * @msg: the error message
  1698. * @str1: extra data
  1699. * @str2: extra data
  1700. *
  1701. * Handle a parser error
  1702. */
  1703. static void LIBXML_ATTR_FORMAT(4,0)
  1704. xmlSchemaPErr(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1705. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1706. {
  1707. xmlGenericErrorFunc channel = NULL;
  1708. xmlStructuredErrorFunc schannel = NULL;
  1709. void *data = NULL;
  1710. if (ctxt != NULL) {
  1711. ctxt->nberrors++;
  1712. ctxt->err = error;
  1713. channel = ctxt->error;
  1714. data = ctxt->errCtxt;
  1715. schannel = ctxt->serror;
  1716. }
  1717. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1718. error, XML_ERR_ERROR, NULL, 0,
  1719. (const char *) str1, (const char *) str2, NULL, 0, 0,
  1720. msg, str1, str2);
  1721. }
  1722. /**
  1723. * xmlSchemaPErr2:
  1724. * @ctxt: the parsing context
  1725. * @node: the context node
  1726. * @node: the current child
  1727. * @error: the error code
  1728. * @msg: the error message
  1729. * @str1: extra data
  1730. * @str2: extra data
  1731. *
  1732. * Handle a parser error
  1733. */
  1734. static void LIBXML_ATTR_FORMAT(5,0)
  1735. xmlSchemaPErr2(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  1736. xmlNodePtr child, int error,
  1737. const char *msg, const xmlChar * str1, const xmlChar * str2)
  1738. {
  1739. if (child != NULL)
  1740. xmlSchemaPErr(ctxt, child, error, msg, str1, str2);
  1741. else
  1742. xmlSchemaPErr(ctxt, node, error, msg, str1, str2);
  1743. }
  1744. /**
  1745. * xmlSchemaPErrExt:
  1746. * @ctxt: the parsing context
  1747. * @node: the context node
  1748. * @error: the error code
  1749. * @strData1: extra data
  1750. * @strData2: extra data
  1751. * @strData3: extra data
  1752. * @msg: the message
  1753. * @str1: extra parameter for the message display
  1754. * @str2: extra parameter for the message display
  1755. * @str3: extra parameter for the message display
  1756. * @str4: extra parameter for the message display
  1757. * @str5: extra parameter for the message display
  1758. *
  1759. * Handle a parser error
  1760. */
  1761. static void LIBXML_ATTR_FORMAT(7,0)
  1762. xmlSchemaPErrExt(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int error,
  1763. const xmlChar * strData1, const xmlChar * strData2,
  1764. const xmlChar * strData3, const char *msg, const xmlChar * str1,
  1765. const xmlChar * str2, const xmlChar * str3, const xmlChar * str4,
  1766. const xmlChar * str5)
  1767. {
  1768. xmlGenericErrorFunc channel = NULL;
  1769. xmlStructuredErrorFunc schannel = NULL;
  1770. void *data = NULL;
  1771. if (ctxt != NULL) {
  1772. ctxt->nberrors++;
  1773. ctxt->err = error;
  1774. channel = ctxt->error;
  1775. data = ctxt->errCtxt;
  1776. schannel = ctxt->serror;
  1777. }
  1778. __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
  1779. error, XML_ERR_ERROR, NULL, 0,
  1780. (const char *) strData1, (const char *) strData2,
  1781. (const char *) strData3, 0, 0, msg, str1, str2,
  1782. str3, str4, str5);
  1783. }
  1784. /************************************************************************
  1785. * *
  1786. * Allround error functions *
  1787. * *
  1788. ************************************************************************/
  1789. /**
  1790. * xmlSchemaVTypeErrMemory:
  1791. * @node: a context node
  1792. * @extra: extra informations
  1793. *
  1794. * Handle an out of memory condition
  1795. */
  1796. static void
  1797. xmlSchemaVErrMemory(xmlSchemaValidCtxtPtr ctxt,
  1798. const char *extra, xmlNodePtr node)
  1799. {
  1800. if (ctxt != NULL) {
  1801. ctxt->nberrors++;
  1802. ctxt->err = XML_SCHEMAV_INTERNAL;
  1803. }
  1804. __xmlSimpleError(XML_FROM_SCHEMASV, XML_ERR_NO_MEMORY, node, NULL,
  1805. extra);
  1806. }
  1807. static void LIBXML_ATTR_FORMAT(2,0)
  1808. xmlSchemaPSimpleInternalErr(xmlNodePtr node,
  1809. const char *msg, const xmlChar *str)
  1810. {
  1811. __xmlSimpleError(XML_FROM_SCHEMASP, XML_SCHEMAP_INTERNAL, node,
  1812. msg, (const char *) str);
  1813. }
  1814. #define WXS_ERROR_TYPE_ERROR 1
  1815. #define WXS_ERROR_TYPE_WARNING 2
  1816. /**
  1817. * xmlSchemaErr4Line:
  1818. * @ctxt: the validation context
  1819. * @errorLevel: the error level
  1820. * @error: the error code
  1821. * @node: the context node
  1822. * @line: the line number
  1823. * @msg: the error message
  1824. * @str1: extra data
  1825. * @str2: extra data
  1826. * @str3: extra data
  1827. * @str4: extra data
  1828. *
  1829. * Handle a validation error
  1830. */
  1831. static void LIBXML_ATTR_FORMAT(6,0)
  1832. xmlSchemaErr4Line(xmlSchemaAbstractCtxtPtr ctxt,
  1833. xmlErrorLevel errorLevel,
  1834. int error, xmlNodePtr node, int line, const char *msg,
  1835. const xmlChar *str1, const xmlChar *str2,
  1836. const xmlChar *str3, const xmlChar *str4)
  1837. {
  1838. xmlStructuredErrorFunc schannel = NULL;
  1839. xmlGenericErrorFunc channel = NULL;
  1840. void *data = NULL;
  1841. if (ctxt != NULL) {
  1842. if (ctxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  1843. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctxt;
  1844. const char *file = NULL;
  1845. int col = 0;
  1846. if (errorLevel != XML_ERR_WARNING) {
  1847. vctxt->nberrors++;
  1848. vctxt->err = error;
  1849. channel = vctxt->error;
  1850. } else {
  1851. channel = vctxt->warning;
  1852. }
  1853. schannel = vctxt->serror;
  1854. data = vctxt->errCtxt;
  1855. /*
  1856. * Error node. If we specify a line number, then
  1857. * do not channel any node to the error function.
  1858. */
  1859. if (line == 0) {
  1860. if ((node == NULL) &&
  1861. (vctxt->depth >= 0) &&
  1862. (vctxt->inode != NULL)) {
  1863. node = vctxt->inode->node;
  1864. }
  1865. /*
  1866. * Get filename and line if no node-tree.
  1867. */
  1868. if ((node == NULL) &&
  1869. (vctxt->parserCtxt != NULL) &&
  1870. (vctxt->parserCtxt->input != NULL)) {
  1871. file = vctxt->parserCtxt->input->filename;
  1872. line = vctxt->parserCtxt->input->line;
  1873. col = vctxt->parserCtxt->input->col;
  1874. }
  1875. } else {
  1876. /*
  1877. * Override the given node's (if any) position
  1878. * and channel only the given line number.
  1879. */
  1880. node = NULL;
  1881. /*
  1882. * Get filename.
  1883. */
  1884. if (vctxt->doc != NULL)
  1885. file = (const char *) vctxt->doc->URL;
  1886. else if ((vctxt->parserCtxt != NULL) &&
  1887. (vctxt->parserCtxt->input != NULL))
  1888. file = vctxt->parserCtxt->input->filename;
  1889. }
  1890. if (vctxt->locFunc != NULL) {
  1891. if ((file == NULL) || (line == 0)) {
  1892. unsigned long l;
  1893. const char *f;
  1894. vctxt->locFunc(vctxt->locCtxt, &f, &l);
  1895. if (file == NULL)
  1896. file = f;
  1897. if (line == 0)
  1898. line = (int) l;
  1899. }
  1900. }
  1901. if ((file == NULL) && (vctxt->filename != NULL))
  1902. file = vctxt->filename;
  1903. __xmlRaiseError(schannel, channel, data, ctxt,
  1904. node, XML_FROM_SCHEMASV,
  1905. error, errorLevel, file, line,
  1906. (const char *) str1, (const char *) str2,
  1907. (const char *) str3, 0, col, msg, str1, str2, str3, str4);
  1908. } else if (ctxt->type == XML_SCHEMA_CTXT_PARSER) {
  1909. xmlSchemaParserCtxtPtr pctxt = (xmlSchemaParserCtxtPtr) ctxt;
  1910. if (errorLevel != XML_ERR_WARNING) {
  1911. pctxt->nberrors++;
  1912. pctxt->err = error;
  1913. channel = pctxt->error;
  1914. } else {
  1915. channel = pctxt->warning;
  1916. }
  1917. schannel = pctxt->serror;
  1918. data = pctxt->errCtxt;
  1919. __xmlRaiseError(schannel, channel, data, ctxt,
  1920. node, XML_FROM_SCHEMASP, error,
  1921. errorLevel, NULL, 0,
  1922. (const char *) str1, (const char *) str2,
  1923. (const char *) str3, 0, 0, msg, str1, str2, str3, str4);
  1924. } else {
  1925. TODO
  1926. }
  1927. }
  1928. }
  1929. /**
  1930. * xmlSchemaErr3:
  1931. * @ctxt: the validation context
  1932. * @node: the context node
  1933. * @error: the error code
  1934. * @msg: the error message
  1935. * @str1: extra data
  1936. * @str2: extra data
  1937. * @str3: extra data
  1938. *
  1939. * Handle a validation error
  1940. */
  1941. static void LIBXML_ATTR_FORMAT(4,0)
  1942. xmlSchemaErr3(xmlSchemaAbstractCtxtPtr actxt,
  1943. int error, xmlNodePtr node, const char *msg,
  1944. const xmlChar *str1, const xmlChar *str2, const xmlChar *str3)
  1945. {
  1946. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  1947. msg, str1, str2, str3, NULL);
  1948. }
  1949. static void LIBXML_ATTR_FORMAT(4,0)
  1950. xmlSchemaErr4(xmlSchemaAbstractCtxtPtr actxt,
  1951. int error, xmlNodePtr node, const char *msg,
  1952. const xmlChar *str1, const xmlChar *str2,
  1953. const xmlChar *str3, const xmlChar *str4)
  1954. {
  1955. xmlSchemaErr4Line(actxt, XML_ERR_ERROR, error, node, 0,
  1956. msg, str1, str2, str3, str4);
  1957. }
  1958. static void LIBXML_ATTR_FORMAT(4,0)
  1959. xmlSchemaErr(xmlSchemaAbstractCtxtPtr actxt,
  1960. int error, xmlNodePtr node, const char *msg,
  1961. const xmlChar *str1, const xmlChar *str2)
  1962. {
  1963. xmlSchemaErr4(actxt, error, node, msg, str1, str2, NULL, NULL);
  1964. }
  1965. static xmlChar *
  1966. xmlSchemaFormatNodeForError(xmlChar ** msg,
  1967. xmlSchemaAbstractCtxtPtr actxt,
  1968. xmlNodePtr node)
  1969. {
  1970. xmlChar *str = NULL;
  1971. *msg = NULL;
  1972. if ((node != NULL) &&
  1973. (node->type != XML_ELEMENT_NODE) &&
  1974. (node->type != XML_ATTRIBUTE_NODE))
  1975. {
  1976. /*
  1977. * Don't try to format other nodes than element and
  1978. * attribute nodes.
  1979. * Play safe and return an empty string.
  1980. */
  1981. *msg = xmlStrdup(BAD_CAST "");
  1982. return(*msg);
  1983. }
  1984. if (node != NULL) {
  1985. /*
  1986. * Work on tree nodes.
  1987. */
  1988. if (node->type == XML_ATTRIBUTE_NODE) {
  1989. xmlNodePtr elem = node->parent;
  1990. *msg = xmlStrdup(BAD_CAST "Element '");
  1991. if (elem->ns != NULL)
  1992. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  1993. elem->ns->href, elem->name));
  1994. else
  1995. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  1996. NULL, elem->name));
  1997. FREE_AND_NULL(str);
  1998. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  1999. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2000. } else {
  2001. *msg = xmlStrdup(BAD_CAST "Element '");
  2002. }
  2003. if (node->ns != NULL)
  2004. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2005. node->ns->href, node->name));
  2006. else
  2007. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2008. NULL, node->name));
  2009. FREE_AND_NULL(str);
  2010. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2011. } else if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  2012. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) actxt;
  2013. /*
  2014. * Work on node infos.
  2015. */
  2016. if (vctxt->inode->nodeType == XML_ATTRIBUTE_NODE) {
  2017. xmlSchemaNodeInfoPtr ielem =
  2018. vctxt->elemInfos[vctxt->depth];
  2019. *msg = xmlStrdup(BAD_CAST "Element '");
  2020. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2021. ielem->nsName, ielem->localName));
  2022. FREE_AND_NULL(str);
  2023. *msg = xmlStrcat(*msg, BAD_CAST "', ");
  2024. *msg = xmlStrcat(*msg, BAD_CAST "attribute '");
  2025. } else {
  2026. *msg = xmlStrdup(BAD_CAST "Element '");
  2027. }
  2028. *msg = xmlStrcat(*msg, xmlSchemaFormatQName(&str,
  2029. vctxt->inode->nsName, vctxt->inode->localName));
  2030. FREE_AND_NULL(str);
  2031. *msg = xmlStrcat(*msg, BAD_CAST "': ");
  2032. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  2033. /*
  2034. * Hmm, no node while parsing?
  2035. * Return an empty string, in case NULL will break something.
  2036. */
  2037. *msg = xmlStrdup(BAD_CAST "");
  2038. } else {
  2039. TODO
  2040. return (NULL);
  2041. }
  2042. /*
  2043. * xmlSchemaFormatItemForReport() also returns an escaped format
  2044. * string, so do this before calling it below (in the future).
  2045. */
  2046. xmlEscapeFormatString(msg);
  2047. /*
  2048. * VAL TODO: The output of the given schema component is currently
  2049. * disabled.
  2050. */
  2051. #if 0
  2052. if ((type != NULL) && (xmlSchemaIsGlobalItem(type))) {
  2053. *msg = xmlStrcat(*msg, BAD_CAST " [");
  2054. *msg = xmlStrcat(*msg, xmlSchemaFormatItemForReport(&str,
  2055. NULL, type, NULL, 0));
  2056. FREE_AND_NULL(str)
  2057. *msg = xmlStrcat(*msg, BAD_CAST "]");
  2058. }
  2059. #endif
  2060. return (*msg);
  2061. }
  2062. static void LIBXML_ATTR_FORMAT(3,0)
  2063. xmlSchemaInternalErr2(xmlSchemaAbstractCtxtPtr actxt,
  2064. const char *funcName,
  2065. const char *message,
  2066. const xmlChar *str1,
  2067. const xmlChar *str2)
  2068. {
  2069. xmlChar *msg = NULL;
  2070. if (actxt == NULL)
  2071. return;
  2072. msg = xmlStrdup(BAD_CAST "Internal error: %s, ");
  2073. msg = xmlStrcat(msg, BAD_CAST message);
  2074. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2075. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR)
  2076. xmlSchemaErr3(actxt, XML_SCHEMAV_INTERNAL, NULL,
  2077. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2078. else if (actxt->type == XML_SCHEMA_CTXT_PARSER)
  2079. xmlSchemaErr3(actxt, XML_SCHEMAP_INTERNAL, NULL,
  2080. (const char *) msg, (const xmlChar *) funcName, str1, str2);
  2081. FREE_AND_NULL(msg)
  2082. }
  2083. static void LIBXML_ATTR_FORMAT(3,0)
  2084. xmlSchemaInternalErr(xmlSchemaAbstractCtxtPtr actxt,
  2085. const char *funcName,
  2086. const char *message)
  2087. {
  2088. xmlSchemaInternalErr2(actxt, funcName, "%s", message, NULL);
  2089. }
  2090. #if 0
  2091. static void LIBXML_ATTR_FORMAT(3,0)
  2092. xmlSchemaPInternalErr(xmlSchemaParserCtxtPtr pctxt,
  2093. const char *funcName,
  2094. const char *message,
  2095. const xmlChar *str1,
  2096. const xmlChar *str2)
  2097. {
  2098. xmlSchemaInternalErr2(ACTXT_CAST pctxt, funcName, message,
  2099. str1, str2);
  2100. }
  2101. #endif
  2102. static void LIBXML_ATTR_FORMAT(5,0)
  2103. xmlSchemaCustomErr4(xmlSchemaAbstractCtxtPtr actxt,
  2104. xmlParserErrors error,
  2105. xmlNodePtr node,
  2106. xmlSchemaBasicItemPtr item,
  2107. const char *message,
  2108. const xmlChar *str1, const xmlChar *str2,
  2109. const xmlChar *str3, const xmlChar *str4)
  2110. {
  2111. xmlChar *msg = NULL;
  2112. if ((node == NULL) && (item != NULL) &&
  2113. (actxt->type == XML_SCHEMA_CTXT_PARSER)) {
  2114. node = WXS_ITEM_NODE(item);
  2115. xmlSchemaFormatItemForReport(&msg, NULL, item, NULL);
  2116. msg = xmlStrcat(msg, BAD_CAST ": ");
  2117. } else
  2118. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2119. msg = xmlStrcat(msg, (const xmlChar *) message);
  2120. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2121. xmlSchemaErr4(actxt, error, node,
  2122. message, str1, str2, str3, str4);
  2123. FREE_AND_NULL(msg)
  2124. }
  2125. static void LIBXML_ATTR_FORMAT(5,0)
  2126. xmlSchemaCustomErr(xmlSchemaAbstractCtxtPtr actxt,
  2127. xmlParserErrors error,
  2128. xmlNodePtr node,
  2129. xmlSchemaBasicItemPtr item,
  2130. const char *message,
  2131. const xmlChar *str1,
  2132. const xmlChar *str2)
  2133. {
  2134. xmlSchemaCustomErr4(actxt, error, node, item,
  2135. message, str1, str2, NULL, NULL);
  2136. }
  2137. static void LIBXML_ATTR_FORMAT(5,0)
  2138. xmlSchemaCustomWarning(xmlSchemaAbstractCtxtPtr actxt,
  2139. xmlParserErrors error,
  2140. xmlNodePtr node,
  2141. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2142. const char *message,
  2143. const xmlChar *str1,
  2144. const xmlChar *str2,
  2145. const xmlChar *str3)
  2146. {
  2147. xmlChar *msg = NULL;
  2148. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2149. msg = xmlStrcat(msg, (const xmlChar *) message);
  2150. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2151. /* URGENT TODO: Set the error code to something sane. */
  2152. xmlSchemaErr4Line(actxt, XML_ERR_WARNING, error, node, 0,
  2153. message, str1, str2, str3, NULL);
  2154. FREE_AND_NULL(msg)
  2155. }
  2156. static void LIBXML_ATTR_FORMAT(5,0)
  2157. xmlSchemaKeyrefErr(xmlSchemaValidCtxtPtr vctxt,
  2158. xmlParserErrors error,
  2159. xmlSchemaPSVIIDCNodePtr idcNode,
  2160. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2161. const char *message,
  2162. const xmlChar *str1,
  2163. const xmlChar *str2)
  2164. {
  2165. xmlChar *msg = NULL, *qname = NULL;
  2166. msg = xmlStrdup(BAD_CAST "Element '%s': ");
  2167. msg = xmlStrcat(msg, (const xmlChar *) message);
  2168. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2169. xmlSchemaErr4Line(ACTXT_CAST vctxt, XML_ERR_ERROR,
  2170. error, NULL, idcNode->nodeLine, (const char *) msg,
  2171. xmlSchemaFormatQName(&qname,
  2172. vctxt->nodeQNames->items[idcNode->nodeQNameID +1],
  2173. vctxt->nodeQNames->items[idcNode->nodeQNameID]),
  2174. str1, str2, NULL);
  2175. FREE_AND_NULL(qname);
  2176. FREE_AND_NULL(msg);
  2177. }
  2178. static int
  2179. xmlSchemaEvalErrorNodeType(xmlSchemaAbstractCtxtPtr actxt,
  2180. xmlNodePtr node)
  2181. {
  2182. if (node != NULL)
  2183. return (node->type);
  2184. if ((actxt->type == XML_SCHEMA_CTXT_VALIDATOR) &&
  2185. (((xmlSchemaValidCtxtPtr) actxt)->inode != NULL))
  2186. return ( ((xmlSchemaValidCtxtPtr) actxt)->inode->nodeType);
  2187. return (-1);
  2188. }
  2189. static int
  2190. xmlSchemaIsGlobalItem(xmlSchemaTypePtr item)
  2191. {
  2192. switch (item->type) {
  2193. case XML_SCHEMA_TYPE_COMPLEX:
  2194. case XML_SCHEMA_TYPE_SIMPLE:
  2195. if (item->flags & XML_SCHEMAS_TYPE_GLOBAL)
  2196. return(1);
  2197. break;
  2198. case XML_SCHEMA_TYPE_GROUP:
  2199. return (1);
  2200. case XML_SCHEMA_TYPE_ELEMENT:
  2201. if ( ((xmlSchemaElementPtr) item)->flags &
  2202. XML_SCHEMAS_ELEM_GLOBAL)
  2203. return(1);
  2204. break;
  2205. case XML_SCHEMA_TYPE_ATTRIBUTE:
  2206. if ( ((xmlSchemaAttributePtr) item)->flags &
  2207. XML_SCHEMAS_ATTR_GLOBAL)
  2208. return(1);
  2209. break;
  2210. /* Note that attribute groups are always global. */
  2211. default:
  2212. return(1);
  2213. }
  2214. return (0);
  2215. }
  2216. static void
  2217. xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2218. xmlParserErrors error,
  2219. xmlNodePtr node,
  2220. const xmlChar *value,
  2221. xmlSchemaTypePtr type,
  2222. int displayValue)
  2223. {
  2224. xmlChar *msg = NULL;
  2225. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2226. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2227. XML_ATTRIBUTE_NODE))
  2228. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2229. else
  2230. msg = xmlStrcat(msg, BAD_CAST "The character content is not a valid "
  2231. "value of ");
  2232. if (! xmlSchemaIsGlobalItem(type))
  2233. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2234. else
  2235. msg = xmlStrcat(msg, BAD_CAST "the ");
  2236. if (WXS_IS_ATOMIC(type))
  2237. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2238. else if (WXS_IS_LIST(type))
  2239. msg = xmlStrcat(msg, BAD_CAST "list type");
  2240. else if (WXS_IS_UNION(type))
  2241. msg = xmlStrcat(msg, BAD_CAST "union type");
  2242. if (xmlSchemaIsGlobalItem(type)) {
  2243. xmlChar *str = NULL;
  2244. msg = xmlStrcat(msg, BAD_CAST " '");
  2245. if (type->builtInType != 0) {
  2246. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2247. str = xmlStrdup(type->name);
  2248. } else {
  2249. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2250. if (!str)
  2251. str = xmlStrdup(qName);
  2252. }
  2253. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2254. msg = xmlStrcat(msg, BAD_CAST "'");
  2255. FREE_AND_NULL(str);
  2256. }
  2257. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2258. if (displayValue || (xmlSchemaEvalErrorNodeType(actxt, node) ==
  2259. XML_ATTRIBUTE_NODE))
  2260. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2261. else
  2262. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2263. FREE_AND_NULL(msg)
  2264. }
  2265. static const xmlChar *
  2266. xmlSchemaFormatErrorNodeQName(xmlChar ** str,
  2267. xmlSchemaNodeInfoPtr ni,
  2268. xmlNodePtr node)
  2269. {
  2270. if (node != NULL) {
  2271. if (node->ns != NULL)
  2272. return (xmlSchemaFormatQName(str, node->ns->href, node->name));
  2273. else
  2274. return (xmlSchemaFormatQName(str, NULL, node->name));
  2275. } else if (ni != NULL)
  2276. return (xmlSchemaFormatQName(str, ni->nsName, ni->localName));
  2277. return (NULL);
  2278. }
  2279. static void
  2280. xmlSchemaIllegalAttrErr(xmlSchemaAbstractCtxtPtr actxt,
  2281. xmlParserErrors error,
  2282. xmlSchemaAttrInfoPtr ni,
  2283. xmlNodePtr node)
  2284. {
  2285. xmlChar *msg = NULL, *str = NULL;
  2286. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2287. msg = xmlStrcat(msg, BAD_CAST "The attribute '%s' is not allowed.\n");
  2288. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2289. xmlSchemaFormatErrorNodeQName(&str, (xmlSchemaNodeInfoPtr) ni, node),
  2290. NULL);
  2291. FREE_AND_NULL(str)
  2292. FREE_AND_NULL(msg)
  2293. }
  2294. static void LIBXML_ATTR_FORMAT(5,0)
  2295. xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
  2296. xmlParserErrors error,
  2297. xmlNodePtr node,
  2298. xmlSchemaTypePtr type ATTRIBUTE_UNUSED,
  2299. const char *message,
  2300. int nbval,
  2301. int nbneg,
  2302. xmlChar **values)
  2303. {
  2304. xmlChar *str = NULL, *msg = NULL;
  2305. xmlChar *localName, *nsName;
  2306. const xmlChar *cur, *end;
  2307. int i;
  2308. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2309. msg = xmlStrcat(msg, (const xmlChar *) message);
  2310. msg = xmlStrcat(msg, BAD_CAST ".");
  2311. /*
  2312. * Note that is does not make sense to report that we have a
  2313. * wildcard here, since the wildcard might be unfolded into
  2314. * multiple transitions.
  2315. */
  2316. if (nbval + nbneg > 0) {
  2317. if (nbval + nbneg > 1) {
  2318. str = xmlStrdup(BAD_CAST " Expected is one of ( ");
  2319. } else
  2320. str = xmlStrdup(BAD_CAST " Expected is ( ");
  2321. nsName = NULL;
  2322. for (i = 0; i < nbval + nbneg; i++) {
  2323. cur = values[i];
  2324. if (cur == NULL)
  2325. continue;
  2326. if ((cur[0] == 'n') && (cur[1] == 'o') && (cur[2] == 't') &&
  2327. (cur[3] == ' ')) {
  2328. cur += 4;
  2329. str = xmlStrcat(str, BAD_CAST "##other");
  2330. }
  2331. /*
  2332. * Get the local name.
  2333. */
  2334. localName = NULL;
  2335. end = cur;
  2336. if (*end == '*') {
  2337. localName = xmlStrdup(BAD_CAST "*");
  2338. end++;
  2339. } else {
  2340. while ((*end != 0) && (*end != '|'))
  2341. end++;
  2342. localName = xmlStrncat(localName, BAD_CAST cur, end - cur);
  2343. }
  2344. if (*end != 0) {
  2345. end++;
  2346. /*
  2347. * Skip "*|*" if they come with negated expressions, since
  2348. * they represent the same negated wildcard.
  2349. */
  2350. if ((nbneg == 0) || (*end != '*') || (*localName != '*')) {
  2351. /*
  2352. * Get the namespace name.
  2353. */
  2354. cur = end;
  2355. if (*end == '*') {
  2356. nsName = xmlStrdup(BAD_CAST "{*}");
  2357. } else {
  2358. while (*end != 0)
  2359. end++;
  2360. if (i >= nbval)
  2361. nsName = xmlStrdup(BAD_CAST "{##other:");
  2362. else
  2363. nsName = xmlStrdup(BAD_CAST "{");
  2364. nsName = xmlStrncat(nsName, BAD_CAST cur, end - cur);
  2365. nsName = xmlStrcat(nsName, BAD_CAST "}");
  2366. }
  2367. str = xmlStrcat(str, BAD_CAST nsName);
  2368. FREE_AND_NULL(nsName)
  2369. } else {
  2370. FREE_AND_NULL(localName);
  2371. continue;
  2372. }
  2373. }
  2374. str = xmlStrcat(str, BAD_CAST localName);
  2375. FREE_AND_NULL(localName);
  2376. if (i < nbval + nbneg -1)
  2377. str = xmlStrcat(str, BAD_CAST ", ");
  2378. }
  2379. str = xmlStrcat(str, BAD_CAST " ).\n");
  2380. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2381. FREE_AND_NULL(str)
  2382. } else
  2383. msg = xmlStrcat(msg, BAD_CAST "\n");
  2384. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2385. xmlFree(msg);
  2386. }
  2387. static void LIBXML_ATTR_FORMAT(8,0)
  2388. xmlSchemaFacetErr(xmlSchemaAbstractCtxtPtr actxt,
  2389. xmlParserErrors error,
  2390. xmlNodePtr node,
  2391. const xmlChar *value,
  2392. unsigned long length,
  2393. xmlSchemaTypePtr type,
  2394. xmlSchemaFacetPtr facet,
  2395. const char *message,
  2396. const xmlChar *str1,
  2397. const xmlChar *str2)
  2398. {
  2399. xmlChar *str = NULL, *msg = NULL;
  2400. xmlSchemaTypeType facetType;
  2401. int nodeType = xmlSchemaEvalErrorNodeType(actxt, node);
  2402. xmlSchemaFormatNodeForError(&msg, actxt, node);
  2403. if (error == XML_SCHEMAV_CVC_ENUMERATION_VALID) {
  2404. facetType = XML_SCHEMA_FACET_ENUMERATION;
  2405. /*
  2406. * If enumerations are validated, one must not expect the
  2407. * facet to be given.
  2408. */
  2409. } else
  2410. facetType = facet->type;
  2411. msg = xmlStrcat(msg, BAD_CAST "[");
  2412. msg = xmlStrcat(msg, BAD_CAST "facet '");
  2413. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facetType));
  2414. msg = xmlStrcat(msg, BAD_CAST "'] ");
  2415. if (message == NULL) {
  2416. /*
  2417. * Use a default message.
  2418. */
  2419. if ((facetType == XML_SCHEMA_FACET_LENGTH) ||
  2420. (facetType == XML_SCHEMA_FACET_MINLENGTH) ||
  2421. (facetType == XML_SCHEMA_FACET_MAXLENGTH)) {
  2422. char len[25], actLen[25];
  2423. /* FIXME, TODO: What is the max expected string length of the
  2424. * this value?
  2425. */
  2426. if (nodeType == XML_ATTRIBUTE_NODE)
  2427. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has a length of '%s'; ");
  2428. else
  2429. msg = xmlStrcat(msg, BAD_CAST "The value has a length of '%s'; ");
  2430. snprintf(len, 24, "%lu", xmlSchemaGetFacetValueAsULong(facet));
  2431. snprintf(actLen, 24, "%lu", length);
  2432. if (facetType == XML_SCHEMA_FACET_LENGTH)
  2433. msg = xmlStrcat(msg,
  2434. BAD_CAST "this differs from the allowed length of '%s'.\n");
  2435. else if (facetType == XML_SCHEMA_FACET_MAXLENGTH)
  2436. msg = xmlStrcat(msg,
  2437. BAD_CAST "this exceeds the allowed maximum length of '%s'.\n");
  2438. else if (facetType == XML_SCHEMA_FACET_MINLENGTH)
  2439. msg = xmlStrcat(msg,
  2440. BAD_CAST "this underruns the allowed minimum length of '%s'.\n");
  2441. if (nodeType == XML_ATTRIBUTE_NODE)
  2442. xmlSchemaErr3(actxt, error, node, (const char *) msg,
  2443. value, (const xmlChar *) actLen, (const xmlChar *) len);
  2444. else
  2445. xmlSchemaErr(actxt, error, node, (const char *) msg,
  2446. (const xmlChar *) actLen, (const xmlChar *) len);
  2447. } else if (facetType == XML_SCHEMA_FACET_ENUMERATION) {
  2448. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not an element "
  2449. "of the set {%s}.\n");
  2450. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2451. xmlSchemaFormatFacetEnumSet(actxt, &str, type));
  2452. } else if (facetType == XML_SCHEMA_FACET_PATTERN) {
  2453. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not accepted "
  2454. "by the pattern '%s'.\n");
  2455. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2456. facet->value);
  2457. } else if (facetType == XML_SCHEMA_FACET_MININCLUSIVE) {
  2458. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is less than the "
  2459. "minimum value allowed ('%s').\n");
  2460. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2461. facet->value);
  2462. } else if (facetType == XML_SCHEMA_FACET_MAXINCLUSIVE) {
  2463. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is greater than the "
  2464. "maximum value allowed ('%s').\n");
  2465. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2466. facet->value);
  2467. } else if (facetType == XML_SCHEMA_FACET_MINEXCLUSIVE) {
  2468. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be greater than "
  2469. "'%s'.\n");
  2470. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2471. facet->value);
  2472. } else if (facetType == XML_SCHEMA_FACET_MAXEXCLUSIVE) {
  2473. msg = xmlStrcat(msg, BAD_CAST "The value '%s' must be less than "
  2474. "'%s'.\n");
  2475. xmlSchemaErr(actxt, error, node, (const char *) msg, value,
  2476. facet->value);
  2477. } else if (facetType == XML_SCHEMA_FACET_TOTALDIGITS) {
  2478. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more "
  2479. "digits than are allowed ('%s').\n");
  2480. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2481. facet->value);
  2482. } else if (facetType == XML_SCHEMA_FACET_FRACTIONDIGITS) {
  2483. msg = xmlStrcat(msg, BAD_CAST "The value '%s' has more fractional "
  2484. "digits than are allowed ('%s').\n");
  2485. xmlSchemaErr(actxt, error, node, (const char*) msg, value,
  2486. facet->value);
  2487. } else if (nodeType == XML_ATTRIBUTE_NODE) {
  2488. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not facet-valid.\n");
  2489. xmlSchemaErr(actxt, error, node, (const char *) msg, value, NULL);
  2490. } else {
  2491. msg = xmlStrcat(msg, BAD_CAST "The value is not facet-valid.\n");
  2492. xmlSchemaErr(actxt, error, node, (const char *) msg, NULL, NULL);
  2493. }
  2494. } else {
  2495. msg = xmlStrcat(msg, (const xmlChar *) message);
  2496. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2497. xmlSchemaErr(actxt, error, node, (const char *) msg, str1, str2);
  2498. }
  2499. FREE_AND_NULL(str)
  2500. xmlFree(msg);
  2501. }
  2502. #define VERROR(err, type, msg) \
  2503. xmlSchemaCustomErr(ACTXT_CAST vctxt, err, NULL, type, "%s", msg, NULL);
  2504. #define VERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST vctxt, func, msg);
  2505. #define PERROR_INT(func, msg) xmlSchemaInternalErr(ACTXT_CAST pctxt, func, msg);
  2506. #define PERROR_INT2(func, msg) xmlSchemaInternalErr(ACTXT_CAST ctxt, func, msg);
  2507. #define AERROR_INT(func, msg) xmlSchemaInternalErr(actxt, func, msg);
  2508. /**
  2509. * xmlSchemaPMissingAttrErr:
  2510. * @ctxt: the schema validation context
  2511. * @ownerItem: the owner as a schema object
  2512. * @ownerElem: the owner as an element node
  2513. * @node: the parent element node of the missing attribute node
  2514. * @type: the corresponding type of the attribute node
  2515. *
  2516. * Reports an illegal attribute.
  2517. */
  2518. static void
  2519. xmlSchemaPMissingAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2520. xmlParserErrors error,
  2521. xmlSchemaBasicItemPtr ownerItem,
  2522. xmlNodePtr ownerElem,
  2523. const char *name,
  2524. const char *message)
  2525. {
  2526. xmlChar *des = NULL;
  2527. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2528. if (message != NULL)
  2529. xmlSchemaPErr(ctxt, ownerElem, error, "%s: %s.\n", BAD_CAST des, BAD_CAST message);
  2530. else
  2531. xmlSchemaPErr(ctxt, ownerElem, error,
  2532. "%s: The attribute '%s' is required but missing.\n",
  2533. BAD_CAST des, BAD_CAST name);
  2534. FREE_AND_NULL(des);
  2535. }
  2536. /**
  2537. * xmlSchemaPResCompAttrErr:
  2538. * @ctxt: the schema validation context
  2539. * @error: the error code
  2540. * @ownerItem: the owner as a schema object
  2541. * @ownerElem: the owner as an element node
  2542. * @name: the name of the attribute holding the QName
  2543. * @refName: the referenced local name
  2544. * @refURI: the referenced namespace URI
  2545. * @message: optional message
  2546. *
  2547. * Used to report QName attribute values that failed to resolve
  2548. * to schema components.
  2549. */
  2550. static void
  2551. xmlSchemaPResCompAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2552. xmlParserErrors error,
  2553. xmlSchemaBasicItemPtr ownerItem,
  2554. xmlNodePtr ownerElem,
  2555. const char *name,
  2556. const xmlChar *refName,
  2557. const xmlChar *refURI,
  2558. xmlSchemaTypeType refType,
  2559. const char *refTypeStr)
  2560. {
  2561. xmlChar *des = NULL, *strA = NULL;
  2562. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2563. if (refTypeStr == NULL)
  2564. refTypeStr = (const char *) xmlSchemaItemTypeToStr(refType);
  2565. xmlSchemaPErrExt(ctxt, ownerElem, error,
  2566. NULL, NULL, NULL,
  2567. "%s, attribute '%s': The QName value '%s' does not resolve to a(n) "
  2568. "%s.\n", BAD_CAST des, BAD_CAST name,
  2569. xmlSchemaFormatQName(&strA, refURI, refName),
  2570. BAD_CAST refTypeStr, NULL);
  2571. FREE_AND_NULL(des)
  2572. FREE_AND_NULL(strA)
  2573. }
  2574. /**
  2575. * xmlSchemaPCustomAttrErr:
  2576. * @ctxt: the schema parser context
  2577. * @error: the error code
  2578. * @ownerDes: the designation of the owner
  2579. * @ownerItem: the owner as a schema object
  2580. * @attr: the illegal attribute node
  2581. *
  2582. * Reports an illegal attribute during the parse.
  2583. */
  2584. static void
  2585. xmlSchemaPCustomAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2586. xmlParserErrors error,
  2587. xmlChar **ownerDes,
  2588. xmlSchemaBasicItemPtr ownerItem,
  2589. xmlAttrPtr attr,
  2590. const char *msg)
  2591. {
  2592. xmlChar *des = NULL;
  2593. if (ownerDes == NULL)
  2594. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, attr->parent);
  2595. else if (*ownerDes == NULL) {
  2596. xmlSchemaFormatItemForReport(ownerDes, NULL, ownerItem, attr->parent);
  2597. des = *ownerDes;
  2598. } else
  2599. des = *ownerDes;
  2600. if (attr == NULL) {
  2601. xmlSchemaPErrExt(ctxt, NULL, error, NULL, NULL, NULL,
  2602. "%s, attribute '%s': %s.\n",
  2603. BAD_CAST des, (const xmlChar *) "Unknown",
  2604. (const xmlChar *) msg, NULL, NULL);
  2605. } else {
  2606. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2607. "%s, attribute '%s': %s.\n",
  2608. BAD_CAST des, attr->name, (const xmlChar *) msg, NULL, NULL);
  2609. }
  2610. if (ownerDes == NULL)
  2611. FREE_AND_NULL(des);
  2612. }
  2613. /**
  2614. * xmlSchemaPIllegalAttrErr:
  2615. * @ctxt: the schema parser context
  2616. * @error: the error code
  2617. * @ownerItem: the attribute's owner item
  2618. * @attr: the illegal attribute node
  2619. *
  2620. * Reports an illegal attribute during the parse.
  2621. */
  2622. static void
  2623. xmlSchemaPIllegalAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2624. xmlParserErrors error,
  2625. xmlSchemaBasicItemPtr ownerComp ATTRIBUTE_UNUSED,
  2626. xmlAttrPtr attr)
  2627. {
  2628. xmlChar *strA = NULL, *strB = NULL;
  2629. xmlSchemaFormatNodeForError(&strA, ACTXT_CAST ctxt, attr->parent);
  2630. xmlSchemaErr4(ACTXT_CAST ctxt, error, (xmlNodePtr) attr,
  2631. "%sThe attribute '%s' is not allowed.\n", BAD_CAST strA,
  2632. xmlSchemaFormatQNameNs(&strB, attr->ns, attr->name),
  2633. NULL, NULL);
  2634. FREE_AND_NULL(strA);
  2635. FREE_AND_NULL(strB);
  2636. }
  2637. /**
  2638. * xmlSchemaPCustomErr:
  2639. * @ctxt: the schema parser context
  2640. * @error: the error code
  2641. * @itemDes: the designation of the schema item
  2642. * @item: the schema item
  2643. * @itemElem: the node of the schema item
  2644. * @message: the error message
  2645. * @str1: an optional param for the error message
  2646. * @str2: an optional param for the error message
  2647. * @str3: an optional param for the error message
  2648. *
  2649. * Reports an error during parsing.
  2650. */
  2651. static void LIBXML_ATTR_FORMAT(5,0)
  2652. xmlSchemaPCustomErrExt(xmlSchemaParserCtxtPtr ctxt,
  2653. xmlParserErrors error,
  2654. xmlSchemaBasicItemPtr item,
  2655. xmlNodePtr itemElem,
  2656. const char *message,
  2657. const xmlChar *str1,
  2658. const xmlChar *str2,
  2659. const xmlChar *str3)
  2660. {
  2661. xmlChar *des = NULL, *msg = NULL;
  2662. xmlSchemaFormatItemForReport(&des, NULL, item, itemElem);
  2663. msg = xmlStrdup(BAD_CAST "%s: ");
  2664. msg = xmlStrcat(msg, (const xmlChar *) message);
  2665. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2666. if ((itemElem == NULL) && (item != NULL))
  2667. itemElem = WXS_ITEM_NODE(item);
  2668. xmlSchemaPErrExt(ctxt, itemElem, error, NULL, NULL, NULL,
  2669. (const char *) msg, BAD_CAST des, str1, str2, str3, NULL);
  2670. FREE_AND_NULL(des);
  2671. FREE_AND_NULL(msg);
  2672. }
  2673. /**
  2674. * xmlSchemaPCustomErr:
  2675. * @ctxt: the schema parser context
  2676. * @error: the error code
  2677. * @itemDes: the designation of the schema item
  2678. * @item: the schema item
  2679. * @itemElem: the node of the schema item
  2680. * @message: the error message
  2681. * @str1: the optional param for the error message
  2682. *
  2683. * Reports an error during parsing.
  2684. */
  2685. static void LIBXML_ATTR_FORMAT(5,0)
  2686. xmlSchemaPCustomErr(xmlSchemaParserCtxtPtr ctxt,
  2687. xmlParserErrors error,
  2688. xmlSchemaBasicItemPtr item,
  2689. xmlNodePtr itemElem,
  2690. const char *message,
  2691. const xmlChar *str1)
  2692. {
  2693. xmlSchemaPCustomErrExt(ctxt, error, item, itemElem, message,
  2694. str1, NULL, NULL);
  2695. }
  2696. /**
  2697. * xmlSchemaPAttrUseErr:
  2698. * @ctxt: the schema parser context
  2699. * @error: the error code
  2700. * @itemDes: the designation of the schema type
  2701. * @item: the schema type
  2702. * @itemElem: the node of the schema type
  2703. * @attr: the invalid schema attribute
  2704. * @message: the error message
  2705. * @str1: the optional param for the error message
  2706. *
  2707. * Reports an attribute use error during parsing.
  2708. */
  2709. static void LIBXML_ATTR_FORMAT(6,0)
  2710. xmlSchemaPAttrUseErr4(xmlSchemaParserCtxtPtr ctxt,
  2711. xmlParserErrors error,
  2712. xmlNodePtr node,
  2713. xmlSchemaBasicItemPtr ownerItem,
  2714. const xmlSchemaAttributeUsePtr attruse,
  2715. const char *message,
  2716. const xmlChar *str1, const xmlChar *str2,
  2717. const xmlChar *str3,const xmlChar *str4)
  2718. {
  2719. xmlChar *str = NULL, *msg = NULL;
  2720. xmlSchemaFormatItemForReport(&msg, NULL, ownerItem, NULL);
  2721. msg = xmlStrcat(msg, BAD_CAST ", ");
  2722. msg = xmlStrcat(msg,
  2723. BAD_CAST xmlSchemaFormatItemForReport(&str, NULL,
  2724. WXS_BASIC_CAST attruse, NULL));
  2725. FREE_AND_NULL(str);
  2726. msg = xmlStrcat(msg, BAD_CAST ": ");
  2727. msg = xmlStrcat(msg, (const xmlChar *) message);
  2728. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2729. xmlSchemaErr4(ACTXT_CAST ctxt, error, node,
  2730. (const char *) msg, str1, str2, str3, str4);
  2731. xmlFree(msg);
  2732. }
  2733. /**
  2734. * xmlSchemaPIllegalFacetAtomicErr:
  2735. * @ctxt: the schema parser context
  2736. * @error: the error code
  2737. * @type: the schema type
  2738. * @baseType: the base type of type
  2739. * @facet: the illegal facet
  2740. *
  2741. * Reports an illegal facet for atomic simple types.
  2742. */
  2743. static void
  2744. xmlSchemaPIllegalFacetAtomicErr(xmlSchemaParserCtxtPtr ctxt,
  2745. xmlParserErrors error,
  2746. xmlSchemaTypePtr type,
  2747. xmlSchemaTypePtr baseType,
  2748. xmlSchemaFacetPtr facet)
  2749. {
  2750. xmlChar *des = NULL, *strT = NULL;
  2751. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type, type->node);
  2752. xmlSchemaPErrExt(ctxt, type->node, error, NULL, NULL, NULL,
  2753. "%s: The facet '%s' is not allowed on types derived from the "
  2754. "type %s.\n",
  2755. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type),
  2756. xmlSchemaFormatItemForReport(&strT, NULL, WXS_BASIC_CAST baseType, NULL),
  2757. NULL, NULL);
  2758. FREE_AND_NULL(des);
  2759. FREE_AND_NULL(strT);
  2760. }
  2761. /**
  2762. * xmlSchemaPIllegalFacetListUnionErr:
  2763. * @ctxt: the schema parser context
  2764. * @error: the error code
  2765. * @itemDes: the designation of the schema item involved
  2766. * @item: the schema item involved
  2767. * @facet: the illegal facet
  2768. *
  2769. * Reports an illegal facet for <list> and <union>.
  2770. */
  2771. static void
  2772. xmlSchemaPIllegalFacetListUnionErr(xmlSchemaParserCtxtPtr ctxt,
  2773. xmlParserErrors error,
  2774. xmlSchemaTypePtr type,
  2775. xmlSchemaFacetPtr facet)
  2776. {
  2777. xmlChar *des = NULL;
  2778. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST type,
  2779. type->node);
  2780. xmlSchemaPErr(ctxt, type->node, error,
  2781. "%s: The facet '%s' is not allowed.\n",
  2782. BAD_CAST des, xmlSchemaFacetTypeToString(facet->type));
  2783. FREE_AND_NULL(des);
  2784. }
  2785. /**
  2786. * xmlSchemaPMutualExclAttrErr:
  2787. * @ctxt: the schema validation context
  2788. * @error: the error code
  2789. * @elemDes: the designation of the parent element node
  2790. * @attr: the bad attribute node
  2791. * @type: the corresponding type of the attribute node
  2792. *
  2793. * Reports an illegal attribute.
  2794. */
  2795. static void
  2796. xmlSchemaPMutualExclAttrErr(xmlSchemaParserCtxtPtr ctxt,
  2797. xmlParserErrors error,
  2798. xmlSchemaBasicItemPtr ownerItem,
  2799. xmlAttrPtr attr,
  2800. const char *name1,
  2801. const char *name2)
  2802. {
  2803. xmlChar *des = NULL;
  2804. xmlSchemaFormatItemForReport(&des, NULL, WXS_BASIC_CAST ownerItem, attr->parent);
  2805. xmlSchemaPErrExt(ctxt, (xmlNodePtr) attr, error, NULL, NULL, NULL,
  2806. "%s: The attributes '%s' and '%s' are mutually exclusive.\n",
  2807. BAD_CAST des, BAD_CAST name1, BAD_CAST name2, NULL, NULL);
  2808. FREE_AND_NULL(des);
  2809. }
  2810. /**
  2811. * xmlSchemaPSimpleTypeErr:
  2812. * @ctxt: the schema validation context
  2813. * @error: the error code
  2814. * @type: the type specifier
  2815. * @ownerItem: the schema object if existent
  2816. * @node: the validated node
  2817. * @value: the validated value
  2818. *
  2819. * Reports a simple type validation error.
  2820. * TODO: Should this report the value of an element as well?
  2821. */
  2822. static void LIBXML_ATTR_FORMAT(8,0)
  2823. xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
  2824. xmlParserErrors error,
  2825. xmlSchemaBasicItemPtr ownerItem ATTRIBUTE_UNUSED,
  2826. xmlNodePtr node,
  2827. xmlSchemaTypePtr type,
  2828. const char *expected,
  2829. const xmlChar *value,
  2830. const char *message,
  2831. const xmlChar *str1,
  2832. const xmlChar *str2)
  2833. {
  2834. xmlChar *msg = NULL;
  2835. xmlSchemaFormatNodeForError(&msg, ACTXT_CAST ctxt, node);
  2836. if (message == NULL) {
  2837. /*
  2838. * Use default messages.
  2839. */
  2840. if (type != NULL) {
  2841. if (node->type == XML_ATTRIBUTE_NODE)
  2842. msg = xmlStrcat(msg, BAD_CAST "'%s' is not a valid value of ");
  2843. else
  2844. msg = xmlStrcat(msg, BAD_CAST "The character content is not a "
  2845. "valid value of ");
  2846. if (! xmlSchemaIsGlobalItem(type))
  2847. msg = xmlStrcat(msg, BAD_CAST "the local ");
  2848. else
  2849. msg = xmlStrcat(msg, BAD_CAST "the ");
  2850. if (WXS_IS_ATOMIC(type))
  2851. msg = xmlStrcat(msg, BAD_CAST "atomic type");
  2852. else if (WXS_IS_LIST(type))
  2853. msg = xmlStrcat(msg, BAD_CAST "list type");
  2854. else if (WXS_IS_UNION(type))
  2855. msg = xmlStrcat(msg, BAD_CAST "union type");
  2856. if (xmlSchemaIsGlobalItem(type)) {
  2857. xmlChar *str = NULL;
  2858. msg = xmlStrcat(msg, BAD_CAST " '");
  2859. if (type->builtInType != 0) {
  2860. msg = xmlStrcat(msg, BAD_CAST "xs:");
  2861. str = xmlStrdup(type->name);
  2862. } else {
  2863. const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
  2864. if (!str)
  2865. str = xmlStrdup(qName);
  2866. }
  2867. msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
  2868. msg = xmlStrcat(msg, BAD_CAST "'.");
  2869. FREE_AND_NULL(str);
  2870. }
  2871. } else {
  2872. if (node->type == XML_ATTRIBUTE_NODE)
  2873. msg = xmlStrcat(msg, BAD_CAST "The value '%s' is not valid.");
  2874. else
  2875. msg = xmlStrcat(msg, BAD_CAST "The character content is not "
  2876. "valid.");
  2877. }
  2878. if (expected) {
  2879. xmlChar *expectedEscaped = xmlCharStrdup(expected);
  2880. msg = xmlStrcat(msg, BAD_CAST " Expected is '");
  2881. msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
  2882. FREE_AND_NULL(expectedEscaped);
  2883. msg = xmlStrcat(msg, BAD_CAST "'.\n");
  2884. } else
  2885. msg = xmlStrcat(msg, BAD_CAST "\n");
  2886. if (node->type == XML_ATTRIBUTE_NODE)
  2887. xmlSchemaPErr(ctxt, node, error, (const char *) msg, value, NULL);
  2888. else
  2889. xmlSchemaPErr(ctxt, node, error, (const char *) msg, NULL, NULL);
  2890. } else {
  2891. msg = xmlStrcat(msg, BAD_CAST message);
  2892. msg = xmlStrcat(msg, BAD_CAST ".\n");
  2893. xmlSchemaPErrExt(ctxt, node, error, NULL, NULL, NULL,
  2894. (const char*) msg, str1, str2, NULL, NULL, NULL);
  2895. }
  2896. /* Cleanup. */
  2897. FREE_AND_NULL(msg)
  2898. }
  2899. /**
  2900. * xmlSchemaPContentErr:
  2901. * @ctxt: the schema parser context
  2902. * @error: the error code
  2903. * @ownerItem: the owner item of the holder of the content
  2904. * @ownerElem: the node of the holder of the content
  2905. * @child: the invalid child node
  2906. * @message: the optional error message
  2907. * @content: the optional string describing the correct content
  2908. *
  2909. * Reports an error concerning the content of a schema element.
  2910. */
  2911. static void
  2912. xmlSchemaPContentErr(xmlSchemaParserCtxtPtr ctxt,
  2913. xmlParserErrors error,
  2914. xmlSchemaBasicItemPtr ownerItem,
  2915. xmlNodePtr ownerElem,
  2916. xmlNodePtr child,
  2917. const char *message,
  2918. const char *content)
  2919. {
  2920. xmlChar *des = NULL;
  2921. xmlSchemaFormatItemForReport(&des, NULL, ownerItem, ownerElem);
  2922. if (message != NULL)
  2923. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2924. "%s: %s.\n",
  2925. BAD_CAST des, BAD_CAST message);
  2926. else {
  2927. if (content != NULL) {
  2928. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2929. "%s: The content is not valid. Expected is %s.\n",
  2930. BAD_CAST des, BAD_CAST content);
  2931. } else {
  2932. xmlSchemaPErr2(ctxt, ownerElem, child, error,
  2933. "%s: The content is not valid.\n",
  2934. BAD_CAST des, NULL);
  2935. }
  2936. }
  2937. FREE_AND_NULL(des)
  2938. }
  2939. /************************************************************************
  2940. * *
  2941. * Streamable error functions *
  2942. * *
  2943. ************************************************************************/
  2944. /************************************************************************
  2945. * *
  2946. * Validation helper functions *
  2947. * *
  2948. ************************************************************************/
  2949. /************************************************************************
  2950. * *
  2951. * Allocation functions *
  2952. * *
  2953. ************************************************************************/
  2954. /**
  2955. * xmlSchemaNewSchemaForParserCtxt:
  2956. * @ctxt: a schema validation context
  2957. *
  2958. * Allocate a new Schema structure.
  2959. *
  2960. * Returns the newly allocated structure or NULL in case or error
  2961. */
  2962. static xmlSchemaPtr
  2963. xmlSchemaNewSchema(xmlSchemaParserCtxtPtr ctxt)
  2964. {
  2965. xmlSchemaPtr ret;
  2966. ret = (xmlSchemaPtr) xmlMalloc(sizeof(xmlSchema));
  2967. if (ret == NULL) {
  2968. xmlSchemaPErrMemory(ctxt, "allocating schema", NULL);
  2969. return (NULL);
  2970. }
  2971. memset(ret, 0, sizeof(xmlSchema));
  2972. ret->dict = ctxt->dict;
  2973. xmlDictReference(ret->dict);
  2974. return (ret);
  2975. }
  2976. /**
  2977. * xmlSchemaNewFacet:
  2978. *
  2979. * Allocate a new Facet structure.
  2980. *
  2981. * Returns the newly allocated structure or NULL in case or error
  2982. */
  2983. xmlSchemaFacetPtr
  2984. xmlSchemaNewFacet(void)
  2985. {
  2986. xmlSchemaFacetPtr ret;
  2987. ret = (xmlSchemaFacetPtr) xmlMalloc(sizeof(xmlSchemaFacet));
  2988. if (ret == NULL) {
  2989. return (NULL);
  2990. }
  2991. memset(ret, 0, sizeof(xmlSchemaFacet));
  2992. return (ret);
  2993. }
  2994. /**
  2995. * xmlSchemaNewAnnot:
  2996. * @ctxt: a schema validation context
  2997. * @node: a node
  2998. *
  2999. * Allocate a new annotation structure.
  3000. *
  3001. * Returns the newly allocated structure or NULL in case or error
  3002. */
  3003. static xmlSchemaAnnotPtr
  3004. xmlSchemaNewAnnot(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  3005. {
  3006. xmlSchemaAnnotPtr ret;
  3007. ret = (xmlSchemaAnnotPtr) xmlMalloc(sizeof(xmlSchemaAnnot));
  3008. if (ret == NULL) {
  3009. xmlSchemaPErrMemory(ctxt, "allocating annotation", node);
  3010. return (NULL);
  3011. }
  3012. memset(ret, 0, sizeof(xmlSchemaAnnot));
  3013. ret->content = node;
  3014. return (ret);
  3015. }
  3016. static xmlSchemaItemListPtr
  3017. xmlSchemaItemListCreate(void)
  3018. {
  3019. xmlSchemaItemListPtr ret;
  3020. ret = xmlMalloc(sizeof(xmlSchemaItemList));
  3021. if (ret == NULL) {
  3022. xmlSchemaPErrMemory(NULL,
  3023. "allocating an item list structure", NULL);
  3024. return (NULL);
  3025. }
  3026. memset(ret, 0, sizeof(xmlSchemaItemList));
  3027. return (ret);
  3028. }
  3029. static void
  3030. xmlSchemaItemListClear(xmlSchemaItemListPtr list)
  3031. {
  3032. if (list->items != NULL) {
  3033. xmlFree(list->items);
  3034. list->items = NULL;
  3035. }
  3036. list->nbItems = 0;
  3037. list->sizeItems = 0;
  3038. }
  3039. static int
  3040. xmlSchemaItemListAdd(xmlSchemaItemListPtr list, void *item)
  3041. {
  3042. if (list->items == NULL) {
  3043. list->items = (void **) xmlMalloc(
  3044. 20 * sizeof(void *));
  3045. if (list->items == NULL) {
  3046. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3047. return(-1);
  3048. }
  3049. list->sizeItems = 20;
  3050. } else if (list->sizeItems <= list->nbItems) {
  3051. list->sizeItems *= 2;
  3052. list->items = (void **) xmlRealloc(list->items,
  3053. list->sizeItems * sizeof(void *));
  3054. if (list->items == NULL) {
  3055. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3056. list->sizeItems = 0;
  3057. return(-1);
  3058. }
  3059. }
  3060. list->items[list->nbItems++] = item;
  3061. return(0);
  3062. }
  3063. static int
  3064. xmlSchemaItemListAddSize(xmlSchemaItemListPtr list,
  3065. int initialSize,
  3066. void *item)
  3067. {
  3068. if (list->items == NULL) {
  3069. if (initialSize <= 0)
  3070. initialSize = 1;
  3071. list->items = (void **) xmlMalloc(
  3072. initialSize * sizeof(void *));
  3073. if (list->items == NULL) {
  3074. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3075. return(-1);
  3076. }
  3077. list->sizeItems = initialSize;
  3078. } else if (list->sizeItems <= list->nbItems) {
  3079. list->sizeItems *= 2;
  3080. list->items = (void **) xmlRealloc(list->items,
  3081. list->sizeItems * sizeof(void *));
  3082. if (list->items == NULL) {
  3083. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3084. list->sizeItems = 0;
  3085. return(-1);
  3086. }
  3087. }
  3088. list->items[list->nbItems++] = item;
  3089. return(0);
  3090. }
  3091. static int
  3092. xmlSchemaItemListInsert(xmlSchemaItemListPtr list, void *item, int idx)
  3093. {
  3094. if (list->items == NULL) {
  3095. list->items = (void **) xmlMalloc(
  3096. 20 * sizeof(void *));
  3097. if (list->items == NULL) {
  3098. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3099. return(-1);
  3100. }
  3101. list->sizeItems = 20;
  3102. } else if (list->sizeItems <= list->nbItems) {
  3103. list->sizeItems *= 2;
  3104. list->items = (void **) xmlRealloc(list->items,
  3105. list->sizeItems * sizeof(void *));
  3106. if (list->items == NULL) {
  3107. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3108. list->sizeItems = 0;
  3109. return(-1);
  3110. }
  3111. }
  3112. /*
  3113. * Just append if the index is greater/equal than the item count.
  3114. */
  3115. if (idx >= list->nbItems) {
  3116. list->items[list->nbItems++] = item;
  3117. } else {
  3118. int i;
  3119. for (i = list->nbItems; i > idx; i--)
  3120. list->items[i] = list->items[i-1];
  3121. list->items[idx] = item;
  3122. list->nbItems++;
  3123. }
  3124. return(0);
  3125. }
  3126. #if 0 /* enable if ever needed */
  3127. static int
  3128. xmlSchemaItemListInsertSize(xmlSchemaItemListPtr list,
  3129. int initialSize,
  3130. void *item,
  3131. int idx)
  3132. {
  3133. if (list->items == NULL) {
  3134. if (initialSize <= 0)
  3135. initialSize = 1;
  3136. list->items = (void **) xmlMalloc(
  3137. initialSize * sizeof(void *));
  3138. if (list->items == NULL) {
  3139. xmlSchemaPErrMemory(NULL, "allocating new item list", NULL);
  3140. return(-1);
  3141. }
  3142. list->sizeItems = initialSize;
  3143. } else if (list->sizeItems <= list->nbItems) {
  3144. list->sizeItems *= 2;
  3145. list->items = (void **) xmlRealloc(list->items,
  3146. list->sizeItems * sizeof(void *));
  3147. if (list->items == NULL) {
  3148. xmlSchemaPErrMemory(NULL, "growing item list", NULL);
  3149. list->sizeItems = 0;
  3150. return(-1);
  3151. }
  3152. }
  3153. /*
  3154. * Just append if the index is greater/equal than the item count.
  3155. */
  3156. if (idx >= list->nbItems) {
  3157. list->items[list->nbItems++] = item;
  3158. } else {
  3159. int i;
  3160. for (i = list->nbItems; i > idx; i--)
  3161. list->items[i] = list->items[i-1];
  3162. list->items[idx] = item;
  3163. list->nbItems++;
  3164. }
  3165. return(0);
  3166. }
  3167. #endif
  3168. static int
  3169. xmlSchemaItemListRemove(xmlSchemaItemListPtr list, int idx)
  3170. {
  3171. int i;
  3172. if ((list->items == NULL) || (idx >= list->nbItems)) {
  3173. xmlSchemaPSimpleErr("Internal error: xmlSchemaItemListRemove, "
  3174. "index error.\n");
  3175. return(-1);
  3176. }
  3177. if (list->nbItems == 1) {
  3178. /* TODO: Really free the list? */
  3179. xmlFree(list->items);
  3180. list->items = NULL;
  3181. list->nbItems = 0;
  3182. list->sizeItems = 0;
  3183. } else if (list->nbItems -1 == idx) {
  3184. list->nbItems--;
  3185. } else {
  3186. for (i = idx; i < list->nbItems -1; i++)
  3187. list->items[i] = list->items[i+1];
  3188. list->nbItems--;
  3189. }
  3190. return(0);
  3191. }
  3192. /**
  3193. * xmlSchemaItemListFree:
  3194. * @annot: a schema type structure
  3195. *
  3196. * Deallocate a annotation structure
  3197. */
  3198. static void
  3199. xmlSchemaItemListFree(xmlSchemaItemListPtr list)
  3200. {
  3201. if (list == NULL)
  3202. return;
  3203. if (list->items != NULL)
  3204. xmlFree(list->items);
  3205. xmlFree(list);
  3206. }
  3207. static void
  3208. xmlSchemaBucketFree(xmlSchemaBucketPtr bucket)
  3209. {
  3210. if (bucket == NULL)
  3211. return;
  3212. if (bucket->globals != NULL) {
  3213. xmlSchemaComponentListFree(bucket->globals);
  3214. xmlSchemaItemListFree(bucket->globals);
  3215. }
  3216. if (bucket->locals != NULL) {
  3217. xmlSchemaComponentListFree(bucket->locals);
  3218. xmlSchemaItemListFree(bucket->locals);
  3219. }
  3220. if (bucket->relations != NULL) {
  3221. xmlSchemaSchemaRelationPtr prev, cur = bucket->relations;
  3222. do {
  3223. prev = cur;
  3224. cur = cur->next;
  3225. xmlFree(prev);
  3226. } while (cur != NULL);
  3227. }
  3228. if ((! bucket->preserveDoc) && (bucket->doc != NULL)) {
  3229. xmlFreeDoc(bucket->doc);
  3230. }
  3231. if (bucket->type == XML_SCHEMA_SCHEMA_IMPORT) {
  3232. if (WXS_IMPBUCKET(bucket)->schema != NULL)
  3233. xmlSchemaFree(WXS_IMPBUCKET(bucket)->schema);
  3234. }
  3235. xmlFree(bucket);
  3236. }
  3237. static void
  3238. xmlSchemaBucketFreeEntry(void *bucket, const xmlChar *name ATTRIBUTE_UNUSED)
  3239. {
  3240. xmlSchemaBucketFree((xmlSchemaBucketPtr) bucket);
  3241. }
  3242. static xmlSchemaBucketPtr
  3243. xmlSchemaBucketCreate(xmlSchemaParserCtxtPtr pctxt,
  3244. int type, const xmlChar *targetNamespace)
  3245. {
  3246. xmlSchemaBucketPtr ret;
  3247. int size;
  3248. xmlSchemaPtr mainSchema;
  3249. if (WXS_CONSTRUCTOR(pctxt)->mainSchema == NULL) {
  3250. PERROR_INT("xmlSchemaBucketCreate",
  3251. "no main schema on constructor");
  3252. return(NULL);
  3253. }
  3254. mainSchema = WXS_CONSTRUCTOR(pctxt)->mainSchema;
  3255. /* Create the schema bucket. */
  3256. if (WXS_IS_BUCKET_INCREDEF(type))
  3257. size = sizeof(xmlSchemaInclude);
  3258. else
  3259. size = sizeof(xmlSchemaImport);
  3260. ret = (xmlSchemaBucketPtr) xmlMalloc(size);
  3261. if (ret == NULL) {
  3262. xmlSchemaPErrMemory(NULL, "allocating schema bucket", NULL);
  3263. return(NULL);
  3264. }
  3265. memset(ret, 0, size);
  3266. ret->targetNamespace = targetNamespace;
  3267. ret->type = type;
  3268. ret->globals = xmlSchemaItemListCreate();
  3269. if (ret->globals == NULL) {
  3270. xmlFree(ret);
  3271. return(NULL);
  3272. }
  3273. ret->locals = xmlSchemaItemListCreate();
  3274. if (ret->locals == NULL) {
  3275. xmlFree(ret);
  3276. return(NULL);
  3277. }
  3278. /*
  3279. * The following will assure that only the first bucket is marked as
  3280. * XML_SCHEMA_SCHEMA_MAIN and it points to the *main* schema.
  3281. * For each following import buckets an xmlSchema will be created.
  3282. * An xmlSchema will be created for every distinct targetNamespace.
  3283. * We assign the targetNamespace to the schemata here.
  3284. */
  3285. if (! WXS_HAS_BUCKETS(pctxt)) {
  3286. if (WXS_IS_BUCKET_INCREDEF(type)) {
  3287. PERROR_INT("xmlSchemaBucketCreate",
  3288. "first bucket but it's an include or redefine");
  3289. xmlSchemaBucketFree(ret);
  3290. return(NULL);
  3291. }
  3292. /* Force the type to be XML_SCHEMA_SCHEMA_MAIN. */
  3293. ret->type = XML_SCHEMA_SCHEMA_MAIN;
  3294. /* Point to the *main* schema. */
  3295. WXS_CONSTRUCTOR(pctxt)->mainBucket = ret;
  3296. WXS_IMPBUCKET(ret)->schema = mainSchema;
  3297. /*
  3298. * Ensure that the main schema gets a targetNamespace.
  3299. */
  3300. mainSchema->targetNamespace = targetNamespace;
  3301. } else {
  3302. if (type == XML_SCHEMA_SCHEMA_MAIN) {
  3303. PERROR_INT("xmlSchemaBucketCreate",
  3304. "main bucket but it's not the first one");
  3305. xmlSchemaBucketFree(ret);
  3306. return(NULL);
  3307. } else if (type == XML_SCHEMA_SCHEMA_IMPORT) {
  3308. /*
  3309. * Create a schema for imports and assign the
  3310. * targetNamespace.
  3311. */
  3312. WXS_IMPBUCKET(ret)->schema = xmlSchemaNewSchema(pctxt);
  3313. if (WXS_IMPBUCKET(ret)->schema == NULL) {
  3314. xmlSchemaBucketFree(ret);
  3315. return(NULL);
  3316. }
  3317. WXS_IMPBUCKET(ret)->schema->targetNamespace = targetNamespace;
  3318. }
  3319. }
  3320. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  3321. int res;
  3322. /*
  3323. * Imports go into the "schemasImports" slot of the main *schema*.
  3324. * Note that we create an import entry for the main schema as well; i.e.,
  3325. * even if there's only one schema, we'll get an import.
  3326. */
  3327. if (mainSchema->schemasImports == NULL) {
  3328. mainSchema->schemasImports = xmlHashCreateDict(5,
  3329. WXS_CONSTRUCTOR(pctxt)->dict);
  3330. if (mainSchema->schemasImports == NULL) {
  3331. xmlSchemaBucketFree(ret);
  3332. return(NULL);
  3333. }
  3334. }
  3335. if (targetNamespace == NULL)
  3336. res = xmlHashAddEntry(mainSchema->schemasImports,
  3337. XML_SCHEMAS_NO_NAMESPACE, ret);
  3338. else
  3339. res = xmlHashAddEntry(mainSchema->schemasImports,
  3340. targetNamespace, ret);
  3341. if (res != 0) {
  3342. PERROR_INT("xmlSchemaBucketCreate",
  3343. "failed to add the schema bucket to the hash");
  3344. xmlSchemaBucketFree(ret);
  3345. return(NULL);
  3346. }
  3347. } else {
  3348. /* Set the @ownerImport of an include bucket. */
  3349. if (WXS_IS_BUCKET_IMPMAIN(WXS_CONSTRUCTOR(pctxt)->bucket->type))
  3350. WXS_INCBUCKET(ret)->ownerImport =
  3351. WXS_IMPBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket);
  3352. else
  3353. WXS_INCBUCKET(ret)->ownerImport =
  3354. WXS_INCBUCKET(WXS_CONSTRUCTOR(pctxt)->bucket)->ownerImport;
  3355. /* Includes got into the "includes" slot of the *main* schema. */
  3356. if (mainSchema->includes == NULL) {
  3357. mainSchema->includes = xmlSchemaItemListCreate();
  3358. if (mainSchema->includes == NULL) {
  3359. xmlSchemaBucketFree(ret);
  3360. return(NULL);
  3361. }
  3362. }
  3363. xmlSchemaItemListAdd(mainSchema->includes, ret);
  3364. }
  3365. /*
  3366. * Add to list of all buckets; this is used for lookup
  3367. * during schema construction time only.
  3368. */
  3369. if (xmlSchemaItemListAdd(WXS_CONSTRUCTOR(pctxt)->buckets, ret) == -1)
  3370. return(NULL);
  3371. return(ret);
  3372. }
  3373. static int
  3374. xmlSchemaAddItemSize(xmlSchemaItemListPtr *list, int initialSize, void *item)
  3375. {
  3376. if (*list == NULL) {
  3377. *list = xmlSchemaItemListCreate();
  3378. if (*list == NULL)
  3379. return(-1);
  3380. }
  3381. xmlSchemaItemListAddSize(*list, initialSize, item);
  3382. return(0);
  3383. }
  3384. /**
  3385. * xmlSchemaFreeAnnot:
  3386. * @annot: a schema type structure
  3387. *
  3388. * Deallocate a annotation structure
  3389. */
  3390. static void
  3391. xmlSchemaFreeAnnot(xmlSchemaAnnotPtr annot)
  3392. {
  3393. if (annot == NULL)
  3394. return;
  3395. if (annot->next == NULL) {
  3396. xmlFree(annot);
  3397. } else {
  3398. xmlSchemaAnnotPtr prev;
  3399. do {
  3400. prev = annot;
  3401. annot = annot->next;
  3402. xmlFree(prev);
  3403. } while (annot != NULL);
  3404. }
  3405. }
  3406. /**
  3407. * xmlSchemaFreeNotation:
  3408. * @schema: a schema notation structure
  3409. *
  3410. * Deallocate a Schema Notation structure.
  3411. */
  3412. static void
  3413. xmlSchemaFreeNotation(xmlSchemaNotationPtr nota)
  3414. {
  3415. if (nota == NULL)
  3416. return;
  3417. xmlFree(nota);
  3418. }
  3419. /**
  3420. * xmlSchemaFreeAttribute:
  3421. * @attr: an attribute declaration
  3422. *
  3423. * Deallocates an attribute declaration structure.
  3424. */
  3425. static void
  3426. xmlSchemaFreeAttribute(xmlSchemaAttributePtr attr)
  3427. {
  3428. if (attr == NULL)
  3429. return;
  3430. if (attr->annot != NULL)
  3431. xmlSchemaFreeAnnot(attr->annot);
  3432. if (attr->defVal != NULL)
  3433. xmlSchemaFreeValue(attr->defVal);
  3434. xmlFree(attr);
  3435. }
  3436. /**
  3437. * xmlSchemaFreeAttributeUse:
  3438. * @use: an attribute use
  3439. *
  3440. * Deallocates an attribute use structure.
  3441. */
  3442. static void
  3443. xmlSchemaFreeAttributeUse(xmlSchemaAttributeUsePtr use)
  3444. {
  3445. if (use == NULL)
  3446. return;
  3447. if (use->annot != NULL)
  3448. xmlSchemaFreeAnnot(use->annot);
  3449. if (use->defVal != NULL)
  3450. xmlSchemaFreeValue(use->defVal);
  3451. xmlFree(use);
  3452. }
  3453. /**
  3454. * xmlSchemaFreeAttributeUseProhib:
  3455. * @prohib: an attribute use prohibition
  3456. *
  3457. * Deallocates an attribute use structure.
  3458. */
  3459. static void
  3460. xmlSchemaFreeAttributeUseProhib(xmlSchemaAttributeUseProhibPtr prohib)
  3461. {
  3462. if (prohib == NULL)
  3463. return;
  3464. xmlFree(prohib);
  3465. }
  3466. /**
  3467. * xmlSchemaFreeWildcardNsSet:
  3468. * set: a schema wildcard namespace
  3469. *
  3470. * Deallocates a list of wildcard constraint structures.
  3471. */
  3472. static void
  3473. xmlSchemaFreeWildcardNsSet(xmlSchemaWildcardNsPtr set)
  3474. {
  3475. xmlSchemaWildcardNsPtr next;
  3476. while (set != NULL) {
  3477. next = set->next;
  3478. xmlFree(set);
  3479. set = next;
  3480. }
  3481. }
  3482. /**
  3483. * xmlSchemaFreeWildcard:
  3484. * @wildcard: a wildcard structure
  3485. *
  3486. * Deallocates a wildcard structure.
  3487. */
  3488. void
  3489. xmlSchemaFreeWildcard(xmlSchemaWildcardPtr wildcard)
  3490. {
  3491. if (wildcard == NULL)
  3492. return;
  3493. if (wildcard->annot != NULL)
  3494. xmlSchemaFreeAnnot(wildcard->annot);
  3495. if (wildcard->nsSet != NULL)
  3496. xmlSchemaFreeWildcardNsSet(wildcard->nsSet);
  3497. if (wildcard->negNsSet != NULL)
  3498. xmlFree(wildcard->negNsSet);
  3499. xmlFree(wildcard);
  3500. }
  3501. /**
  3502. * xmlSchemaFreeAttributeGroup:
  3503. * @schema: a schema attribute group structure
  3504. *
  3505. * Deallocate a Schema Attribute Group structure.
  3506. */
  3507. static void
  3508. xmlSchemaFreeAttributeGroup(xmlSchemaAttributeGroupPtr attrGr)
  3509. {
  3510. if (attrGr == NULL)
  3511. return;
  3512. if (attrGr->annot != NULL)
  3513. xmlSchemaFreeAnnot(attrGr->annot);
  3514. if (attrGr->attrUses != NULL)
  3515. xmlSchemaItemListFree(WXS_LIST_CAST attrGr->attrUses);
  3516. xmlFree(attrGr);
  3517. }
  3518. /**
  3519. * xmlSchemaFreeQNameRef:
  3520. * @item: a QName reference structure
  3521. *
  3522. * Deallocatea a QName reference structure.
  3523. */
  3524. static void
  3525. xmlSchemaFreeQNameRef(xmlSchemaQNameRefPtr item)
  3526. {
  3527. xmlFree(item);
  3528. }
  3529. /**
  3530. * xmlSchemaFreeTypeLinkList:
  3531. * @alink: a type link
  3532. *
  3533. * Deallocate a list of types.
  3534. */
  3535. static void
  3536. xmlSchemaFreeTypeLinkList(xmlSchemaTypeLinkPtr link)
  3537. {
  3538. xmlSchemaTypeLinkPtr next;
  3539. while (link != NULL) {
  3540. next = link->next;
  3541. xmlFree(link);
  3542. link = next;
  3543. }
  3544. }
  3545. static void
  3546. xmlSchemaFreeIDCStateObjList(xmlSchemaIDCStateObjPtr sto)
  3547. {
  3548. xmlSchemaIDCStateObjPtr next;
  3549. while (sto != NULL) {
  3550. next = sto->next;
  3551. if (sto->history != NULL)
  3552. xmlFree(sto->history);
  3553. if (sto->xpathCtxt != NULL)
  3554. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  3555. xmlFree(sto);
  3556. sto = next;
  3557. }
  3558. }
  3559. /**
  3560. * xmlSchemaFreeIDC:
  3561. * @idc: a identity-constraint definition
  3562. *
  3563. * Deallocates an identity-constraint definition.
  3564. */
  3565. static void
  3566. xmlSchemaFreeIDC(xmlSchemaIDCPtr idcDef)
  3567. {
  3568. xmlSchemaIDCSelectPtr cur, prev;
  3569. if (idcDef == NULL)
  3570. return;
  3571. if (idcDef->annot != NULL)
  3572. xmlSchemaFreeAnnot(idcDef->annot);
  3573. /* Selector */
  3574. if (idcDef->selector != NULL) {
  3575. if (idcDef->selector->xpathComp != NULL)
  3576. xmlFreePattern((xmlPatternPtr) idcDef->selector->xpathComp);
  3577. xmlFree(idcDef->selector);
  3578. }
  3579. /* Fields */
  3580. if (idcDef->fields != NULL) {
  3581. cur = idcDef->fields;
  3582. do {
  3583. prev = cur;
  3584. cur = cur->next;
  3585. if (prev->xpathComp != NULL)
  3586. xmlFreePattern((xmlPatternPtr) prev->xpathComp);
  3587. xmlFree(prev);
  3588. } while (cur != NULL);
  3589. }
  3590. xmlFree(idcDef);
  3591. }
  3592. /**
  3593. * xmlSchemaFreeElement:
  3594. * @schema: a schema element structure
  3595. *
  3596. * Deallocate a Schema Element structure.
  3597. */
  3598. static void
  3599. xmlSchemaFreeElement(xmlSchemaElementPtr elem)
  3600. {
  3601. if (elem == NULL)
  3602. return;
  3603. if (elem->annot != NULL)
  3604. xmlSchemaFreeAnnot(elem->annot);
  3605. if (elem->contModel != NULL)
  3606. xmlRegFreeRegexp(elem->contModel);
  3607. if (elem->defVal != NULL)
  3608. xmlSchemaFreeValue(elem->defVal);
  3609. xmlFree(elem);
  3610. }
  3611. /**
  3612. * xmlSchemaFreeFacet:
  3613. * @facet: a schema facet structure
  3614. *
  3615. * Deallocate a Schema Facet structure.
  3616. */
  3617. void
  3618. xmlSchemaFreeFacet(xmlSchemaFacetPtr facet)
  3619. {
  3620. if (facet == NULL)
  3621. return;
  3622. if (facet->val != NULL)
  3623. xmlSchemaFreeValue(facet->val);
  3624. if (facet->regexp != NULL)
  3625. xmlRegFreeRegexp(facet->regexp);
  3626. if (facet->annot != NULL)
  3627. xmlSchemaFreeAnnot(facet->annot);
  3628. xmlFree(facet);
  3629. }
  3630. /**
  3631. * xmlSchemaFreeType:
  3632. * @type: a schema type structure
  3633. *
  3634. * Deallocate a Schema Type structure.
  3635. */
  3636. void
  3637. xmlSchemaFreeType(xmlSchemaTypePtr type)
  3638. {
  3639. if (type == NULL)
  3640. return;
  3641. if (type->annot != NULL)
  3642. xmlSchemaFreeAnnot(type->annot);
  3643. if (type->facets != NULL) {
  3644. xmlSchemaFacetPtr facet, next;
  3645. facet = type->facets;
  3646. while (facet != NULL) {
  3647. next = facet->next;
  3648. xmlSchemaFreeFacet(facet);
  3649. facet = next;
  3650. }
  3651. }
  3652. if (type->attrUses != NULL)
  3653. xmlSchemaItemListFree((xmlSchemaItemListPtr) type->attrUses);
  3654. if (type->memberTypes != NULL)
  3655. xmlSchemaFreeTypeLinkList(type->memberTypes);
  3656. if (type->facetSet != NULL) {
  3657. xmlSchemaFacetLinkPtr next, link;
  3658. link = type->facetSet;
  3659. do {
  3660. next = link->next;
  3661. xmlFree(link);
  3662. link = next;
  3663. } while (link != NULL);
  3664. }
  3665. if (type->contModel != NULL)
  3666. xmlRegFreeRegexp(type->contModel);
  3667. xmlFree(type);
  3668. }
  3669. /**
  3670. * xmlSchemaFreeModelGroupDef:
  3671. * @item: a schema model group definition
  3672. *
  3673. * Deallocates a schema model group definition.
  3674. */
  3675. static void
  3676. xmlSchemaFreeModelGroupDef(xmlSchemaModelGroupDefPtr item)
  3677. {
  3678. if (item->annot != NULL)
  3679. xmlSchemaFreeAnnot(item->annot);
  3680. xmlFree(item);
  3681. }
  3682. /**
  3683. * xmlSchemaFreeModelGroup:
  3684. * @item: a schema model group
  3685. *
  3686. * Deallocates a schema model group structure.
  3687. */
  3688. static void
  3689. xmlSchemaFreeModelGroup(xmlSchemaModelGroupPtr item)
  3690. {
  3691. if (item->annot != NULL)
  3692. xmlSchemaFreeAnnot(item->annot);
  3693. xmlFree(item);
  3694. }
  3695. static void
  3696. xmlSchemaComponentListFree(xmlSchemaItemListPtr list)
  3697. {
  3698. if ((list == NULL) || (list->nbItems == 0))
  3699. return;
  3700. {
  3701. xmlSchemaTreeItemPtr item;
  3702. xmlSchemaTreeItemPtr *items = (xmlSchemaTreeItemPtr *) list->items;
  3703. int i;
  3704. for (i = 0; i < list->nbItems; i++) {
  3705. item = items[i];
  3706. if (item == NULL)
  3707. continue;
  3708. switch (item->type) {
  3709. case XML_SCHEMA_TYPE_SIMPLE:
  3710. case XML_SCHEMA_TYPE_COMPLEX:
  3711. xmlSchemaFreeType((xmlSchemaTypePtr) item);
  3712. break;
  3713. case XML_SCHEMA_TYPE_ATTRIBUTE:
  3714. xmlSchemaFreeAttribute((xmlSchemaAttributePtr) item);
  3715. break;
  3716. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  3717. xmlSchemaFreeAttributeUse((xmlSchemaAttributeUsePtr) item);
  3718. break;
  3719. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  3720. xmlSchemaFreeAttributeUseProhib(
  3721. (xmlSchemaAttributeUseProhibPtr) item);
  3722. break;
  3723. case XML_SCHEMA_TYPE_ELEMENT:
  3724. xmlSchemaFreeElement((xmlSchemaElementPtr) item);
  3725. break;
  3726. case XML_SCHEMA_TYPE_PARTICLE:
  3727. if (item->annot != NULL)
  3728. xmlSchemaFreeAnnot(item->annot);
  3729. xmlFree(item);
  3730. break;
  3731. case XML_SCHEMA_TYPE_SEQUENCE:
  3732. case XML_SCHEMA_TYPE_CHOICE:
  3733. case XML_SCHEMA_TYPE_ALL:
  3734. xmlSchemaFreeModelGroup((xmlSchemaModelGroupPtr) item);
  3735. break;
  3736. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  3737. xmlSchemaFreeAttributeGroup(
  3738. (xmlSchemaAttributeGroupPtr) item);
  3739. break;
  3740. case XML_SCHEMA_TYPE_GROUP:
  3741. xmlSchemaFreeModelGroupDef(
  3742. (xmlSchemaModelGroupDefPtr) item);
  3743. break;
  3744. case XML_SCHEMA_TYPE_ANY:
  3745. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  3746. xmlSchemaFreeWildcard((xmlSchemaWildcardPtr) item);
  3747. break;
  3748. case XML_SCHEMA_TYPE_IDC_KEY:
  3749. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  3750. case XML_SCHEMA_TYPE_IDC_KEYREF:
  3751. xmlSchemaFreeIDC((xmlSchemaIDCPtr) item);
  3752. break;
  3753. case XML_SCHEMA_TYPE_NOTATION:
  3754. xmlSchemaFreeNotation((xmlSchemaNotationPtr) item);
  3755. break;
  3756. case XML_SCHEMA_EXTRA_QNAMEREF:
  3757. xmlSchemaFreeQNameRef((xmlSchemaQNameRefPtr) item);
  3758. break;
  3759. default: {
  3760. /* TODO: This should never be hit. */
  3761. xmlSchemaPSimpleInternalErr(NULL,
  3762. "Internal error: xmlSchemaComponentListFree, "
  3763. "unexpected component type '%s'\n",
  3764. (const xmlChar *) WXS_ITEM_TYPE_NAME(item));
  3765. }
  3766. break;
  3767. }
  3768. }
  3769. list->nbItems = 0;
  3770. }
  3771. }
  3772. /**
  3773. * xmlSchemaFree:
  3774. * @schema: a schema structure
  3775. *
  3776. * Deallocate a Schema structure.
  3777. */
  3778. void
  3779. xmlSchemaFree(xmlSchemaPtr schema)
  3780. {
  3781. if (schema == NULL)
  3782. return;
  3783. /* @volatiles is not used anymore :-/ */
  3784. if (schema->volatiles != NULL)
  3785. TODO
  3786. /*
  3787. * Note that those slots are not responsible for freeing
  3788. * schema components anymore; this will now be done by
  3789. * the schema buckets.
  3790. */
  3791. if (schema->notaDecl != NULL)
  3792. xmlHashFree(schema->notaDecl, NULL);
  3793. if (schema->attrDecl != NULL)
  3794. xmlHashFree(schema->attrDecl, NULL);
  3795. if (schema->attrgrpDecl != NULL)
  3796. xmlHashFree(schema->attrgrpDecl, NULL);
  3797. if (schema->elemDecl != NULL)
  3798. xmlHashFree(schema->elemDecl, NULL);
  3799. if (schema->typeDecl != NULL)
  3800. xmlHashFree(schema->typeDecl, NULL);
  3801. if (schema->groupDecl != NULL)
  3802. xmlHashFree(schema->groupDecl, NULL);
  3803. if (schema->idcDef != NULL)
  3804. xmlHashFree(schema->idcDef, NULL);
  3805. if (schema->schemasImports != NULL)
  3806. xmlHashFree(schema->schemasImports, xmlSchemaBucketFreeEntry);
  3807. if (schema->includes != NULL) {
  3808. xmlSchemaItemListPtr list = (xmlSchemaItemListPtr) schema->includes;
  3809. int i;
  3810. for (i = 0; i < list->nbItems; i++) {
  3811. xmlSchemaBucketFree((xmlSchemaBucketPtr) list->items[i]);
  3812. }
  3813. xmlSchemaItemListFree(list);
  3814. }
  3815. if (schema->annot != NULL)
  3816. xmlSchemaFreeAnnot(schema->annot);
  3817. /* Never free the doc here, since this will be done by the buckets. */
  3818. xmlDictFree(schema->dict);
  3819. xmlFree(schema);
  3820. }
  3821. /************************************************************************
  3822. * *
  3823. * Debug functions *
  3824. * *
  3825. ************************************************************************/
  3826. #ifdef LIBXML_OUTPUT_ENABLED
  3827. static void
  3828. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output); /* forward */
  3829. /**
  3830. * xmlSchemaElementDump:
  3831. * @elem: an element
  3832. * @output: the file output
  3833. *
  3834. * Dump the element
  3835. */
  3836. static void
  3837. xmlSchemaElementDump(void *payload, void *data,
  3838. const xmlChar * name ATTRIBUTE_UNUSED,
  3839. const xmlChar * namespace ATTRIBUTE_UNUSED,
  3840. const xmlChar * context ATTRIBUTE_UNUSED)
  3841. {
  3842. xmlSchemaElementPtr elem = (xmlSchemaElementPtr) payload;
  3843. FILE *output = (FILE *) data;
  3844. if (elem == NULL)
  3845. return;
  3846. fprintf(output, "Element");
  3847. if (elem->flags & XML_SCHEMAS_ELEM_GLOBAL)
  3848. fprintf(output, " (global)");
  3849. fprintf(output, ": '%s' ", elem->name);
  3850. if (namespace != NULL)
  3851. fprintf(output, "ns '%s'", namespace);
  3852. fprintf(output, "\n");
  3853. #if 0
  3854. if ((elem->minOccurs != 1) || (elem->maxOccurs != 1)) {
  3855. fprintf(output, " min %d ", elem->minOccurs);
  3856. if (elem->maxOccurs >= UNBOUNDED)
  3857. fprintf(output, "max: unbounded\n");
  3858. else if (elem->maxOccurs != 1)
  3859. fprintf(output, "max: %d\n", elem->maxOccurs);
  3860. else
  3861. fprintf(output, "\n");
  3862. }
  3863. #endif
  3864. /*
  3865. * Misc other properties.
  3866. */
  3867. if ((elem->flags & XML_SCHEMAS_ELEM_NILLABLE) ||
  3868. (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT) ||
  3869. (elem->flags & XML_SCHEMAS_ELEM_FIXED) ||
  3870. (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)) {
  3871. fprintf(output, " props: ");
  3872. if (elem->flags & XML_SCHEMAS_ELEM_FIXED)
  3873. fprintf(output, "[fixed] ");
  3874. if (elem->flags & XML_SCHEMAS_ELEM_DEFAULT)
  3875. fprintf(output, "[default] ");
  3876. if (elem->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  3877. fprintf(output, "[abstract] ");
  3878. if (elem->flags & XML_SCHEMAS_ELEM_NILLABLE)
  3879. fprintf(output, "[nillable] ");
  3880. fprintf(output, "\n");
  3881. }
  3882. /*
  3883. * Default/fixed value.
  3884. */
  3885. if (elem->value != NULL)
  3886. fprintf(output, " value: '%s'\n", elem->value);
  3887. /*
  3888. * Type.
  3889. */
  3890. if (elem->namedType != NULL) {
  3891. fprintf(output, " type: '%s' ", elem->namedType);
  3892. if (elem->namedTypeNs != NULL)
  3893. fprintf(output, "ns '%s'\n", elem->namedTypeNs);
  3894. else
  3895. fprintf(output, "\n");
  3896. } else if (elem->subtypes != NULL) {
  3897. /*
  3898. * Dump local types.
  3899. */
  3900. xmlSchemaTypeDump(elem->subtypes, output);
  3901. }
  3902. /*
  3903. * Substitution group.
  3904. */
  3905. if (elem->substGroup != NULL) {
  3906. fprintf(output, " substitutionGroup: '%s' ", elem->substGroup);
  3907. if (elem->substGroupNs != NULL)
  3908. fprintf(output, "ns '%s'\n", elem->substGroupNs);
  3909. else
  3910. fprintf(output, "\n");
  3911. }
  3912. }
  3913. /**
  3914. * xmlSchemaAnnotDump:
  3915. * @output: the file output
  3916. * @annot: a annotation
  3917. *
  3918. * Dump the annotation
  3919. */
  3920. static void
  3921. xmlSchemaAnnotDump(FILE * output, xmlSchemaAnnotPtr annot)
  3922. {
  3923. xmlChar *content;
  3924. if (annot == NULL)
  3925. return;
  3926. content = xmlNodeGetContent(annot->content);
  3927. if (content != NULL) {
  3928. fprintf(output, " Annot: %s\n", content);
  3929. xmlFree(content);
  3930. } else
  3931. fprintf(output, " Annot: empty\n");
  3932. }
  3933. /**
  3934. * xmlSchemaContentModelDump:
  3935. * @particle: the schema particle
  3936. * @output: the file output
  3937. * @depth: the depth used for indentation
  3938. *
  3939. * Dump a SchemaType structure
  3940. */
  3941. static void
  3942. xmlSchemaContentModelDump(xmlSchemaParticlePtr particle, FILE * output, int depth)
  3943. {
  3944. xmlChar *str = NULL;
  3945. xmlSchemaTreeItemPtr term;
  3946. char shift[100];
  3947. int i;
  3948. if (particle == NULL)
  3949. return;
  3950. for (i = 0;((i < depth) && (i < 25));i++)
  3951. shift[2 * i] = shift[2 * i + 1] = ' ';
  3952. shift[2 * i] = shift[2 * i + 1] = 0;
  3953. fprintf(output, "%s", shift);
  3954. if (particle->children == NULL) {
  3955. fprintf(output, "MISSING particle term\n");
  3956. return;
  3957. }
  3958. term = particle->children;
  3959. if (term == NULL) {
  3960. fprintf(output, "(NULL)");
  3961. } else {
  3962. switch (term->type) {
  3963. case XML_SCHEMA_TYPE_ELEMENT:
  3964. fprintf(output, "ELEM '%s'", xmlSchemaFormatQName(&str,
  3965. ((xmlSchemaElementPtr)term)->targetNamespace,
  3966. ((xmlSchemaElementPtr)term)->name));
  3967. FREE_AND_NULL(str);
  3968. break;
  3969. case XML_SCHEMA_TYPE_SEQUENCE:
  3970. fprintf(output, "SEQUENCE");
  3971. break;
  3972. case XML_SCHEMA_TYPE_CHOICE:
  3973. fprintf(output, "CHOICE");
  3974. break;
  3975. case XML_SCHEMA_TYPE_ALL:
  3976. fprintf(output, "ALL");
  3977. break;
  3978. case XML_SCHEMA_TYPE_ANY:
  3979. fprintf(output, "ANY");
  3980. break;
  3981. default:
  3982. fprintf(output, "UNKNOWN\n");
  3983. return;
  3984. }
  3985. }
  3986. if (particle->minOccurs != 1)
  3987. fprintf(output, " min: %d", particle->minOccurs);
  3988. if (particle->maxOccurs >= UNBOUNDED)
  3989. fprintf(output, " max: unbounded");
  3990. else if (particle->maxOccurs != 1)
  3991. fprintf(output, " max: %d", particle->maxOccurs);
  3992. fprintf(output, "\n");
  3993. if (term &&
  3994. ((term->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  3995. (term->type == XML_SCHEMA_TYPE_CHOICE) ||
  3996. (term->type == XML_SCHEMA_TYPE_ALL)) &&
  3997. (term->children != NULL)) {
  3998. xmlSchemaContentModelDump((xmlSchemaParticlePtr) term->children,
  3999. output, depth +1);
  4000. }
  4001. if (particle->next != NULL)
  4002. xmlSchemaContentModelDump((xmlSchemaParticlePtr) particle->next,
  4003. output, depth);
  4004. }
  4005. /**
  4006. * xmlSchemaAttrUsesDump:
  4007. * @uses: attribute uses list
  4008. * @output: the file output
  4009. *
  4010. * Dumps a list of attribute use components.
  4011. */
  4012. static void
  4013. xmlSchemaAttrUsesDump(xmlSchemaItemListPtr uses, FILE * output)
  4014. {
  4015. xmlSchemaAttributeUsePtr use;
  4016. xmlSchemaAttributeUseProhibPtr prohib;
  4017. xmlSchemaQNameRefPtr ref;
  4018. const xmlChar *name, *tns;
  4019. xmlChar *str = NULL;
  4020. int i;
  4021. if ((uses == NULL) || (uses->nbItems == 0))
  4022. return;
  4023. fprintf(output, " attributes:\n");
  4024. for (i = 0; i < uses->nbItems; i++) {
  4025. use = uses->items[i];
  4026. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  4027. fprintf(output, " [prohibition] ");
  4028. prohib = (xmlSchemaAttributeUseProhibPtr) use;
  4029. name = prohib->name;
  4030. tns = prohib->targetNamespace;
  4031. } else if (use->type == XML_SCHEMA_EXTRA_QNAMEREF) {
  4032. fprintf(output, " [reference] ");
  4033. ref = (xmlSchemaQNameRefPtr) use;
  4034. name = ref->name;
  4035. tns = ref->targetNamespace;
  4036. } else {
  4037. fprintf(output, " [use] ");
  4038. name = WXS_ATTRUSE_DECL_NAME(use);
  4039. tns = WXS_ATTRUSE_DECL_TNS(use);
  4040. }
  4041. fprintf(output, "'%s'\n",
  4042. (const char *) xmlSchemaFormatQName(&str, tns, name));
  4043. FREE_AND_NULL(str);
  4044. }
  4045. }
  4046. /**
  4047. * xmlSchemaTypeDump:
  4048. * @output: the file output
  4049. * @type: a type structure
  4050. *
  4051. * Dump a SchemaType structure
  4052. */
  4053. static void
  4054. xmlSchemaTypeDump(xmlSchemaTypePtr type, FILE * output)
  4055. {
  4056. if (type == NULL) {
  4057. fprintf(output, "Type: NULL\n");
  4058. return;
  4059. }
  4060. fprintf(output, "Type: ");
  4061. if (type->name != NULL)
  4062. fprintf(output, "'%s' ", type->name);
  4063. else
  4064. fprintf(output, "(no name) ");
  4065. if (type->targetNamespace != NULL)
  4066. fprintf(output, "ns '%s' ", type->targetNamespace);
  4067. switch (type->type) {
  4068. case XML_SCHEMA_TYPE_BASIC:
  4069. fprintf(output, "[basic] ");
  4070. break;
  4071. case XML_SCHEMA_TYPE_SIMPLE:
  4072. fprintf(output, "[simple] ");
  4073. break;
  4074. case XML_SCHEMA_TYPE_COMPLEX:
  4075. fprintf(output, "[complex] ");
  4076. break;
  4077. case XML_SCHEMA_TYPE_SEQUENCE:
  4078. fprintf(output, "[sequence] ");
  4079. break;
  4080. case XML_SCHEMA_TYPE_CHOICE:
  4081. fprintf(output, "[choice] ");
  4082. break;
  4083. case XML_SCHEMA_TYPE_ALL:
  4084. fprintf(output, "[all] ");
  4085. break;
  4086. case XML_SCHEMA_TYPE_UR:
  4087. fprintf(output, "[ur] ");
  4088. break;
  4089. case XML_SCHEMA_TYPE_RESTRICTION:
  4090. fprintf(output, "[restriction] ");
  4091. break;
  4092. case XML_SCHEMA_TYPE_EXTENSION:
  4093. fprintf(output, "[extension] ");
  4094. break;
  4095. default:
  4096. fprintf(output, "[unknown type %d] ", type->type);
  4097. break;
  4098. }
  4099. fprintf(output, "content: ");
  4100. switch (type->contentType) {
  4101. case XML_SCHEMA_CONTENT_UNKNOWN:
  4102. fprintf(output, "[unknown] ");
  4103. break;
  4104. case XML_SCHEMA_CONTENT_EMPTY:
  4105. fprintf(output, "[empty] ");
  4106. break;
  4107. case XML_SCHEMA_CONTENT_ELEMENTS:
  4108. fprintf(output, "[element] ");
  4109. break;
  4110. case XML_SCHEMA_CONTENT_MIXED:
  4111. fprintf(output, "[mixed] ");
  4112. break;
  4113. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  4114. /* not used. */
  4115. break;
  4116. case XML_SCHEMA_CONTENT_BASIC:
  4117. fprintf(output, "[basic] ");
  4118. break;
  4119. case XML_SCHEMA_CONTENT_SIMPLE:
  4120. fprintf(output, "[simple] ");
  4121. break;
  4122. case XML_SCHEMA_CONTENT_ANY:
  4123. fprintf(output, "[any] ");
  4124. break;
  4125. }
  4126. fprintf(output, "\n");
  4127. if (type->base != NULL) {
  4128. fprintf(output, " base type: '%s'", type->base);
  4129. if (type->baseNs != NULL)
  4130. fprintf(output, " ns '%s'\n", type->baseNs);
  4131. else
  4132. fprintf(output, "\n");
  4133. }
  4134. if (type->attrUses != NULL)
  4135. xmlSchemaAttrUsesDump(type->attrUses, output);
  4136. if (type->annot != NULL)
  4137. xmlSchemaAnnotDump(output, type->annot);
  4138. #ifdef DUMP_CONTENT_MODEL
  4139. if ((type->type == XML_SCHEMA_TYPE_COMPLEX) &&
  4140. (type->subtypes != NULL)) {
  4141. xmlSchemaContentModelDump((xmlSchemaParticlePtr) type->subtypes,
  4142. output, 1);
  4143. }
  4144. #endif
  4145. }
  4146. static void
  4147. xmlSchemaTypeDumpEntry(void *type, void *output,
  4148. const xmlChar *name ATTRIBUTE_UNUSED)
  4149. {
  4150. xmlSchemaTypeDump((xmlSchemaTypePtr) type, (FILE *) output);
  4151. }
  4152. /**
  4153. * xmlSchemaDump:
  4154. * @output: the file output
  4155. * @schema: a schema structure
  4156. *
  4157. * Dump a Schema structure.
  4158. */
  4159. void
  4160. xmlSchemaDump(FILE * output, xmlSchemaPtr schema)
  4161. {
  4162. if (output == NULL)
  4163. return;
  4164. if (schema == NULL) {
  4165. fprintf(output, "Schemas: NULL\n");
  4166. return;
  4167. }
  4168. fprintf(output, "Schemas: ");
  4169. if (schema->name != NULL)
  4170. fprintf(output, "%s, ", schema->name);
  4171. else
  4172. fprintf(output, "no name, ");
  4173. if (schema->targetNamespace != NULL)
  4174. fprintf(output, "%s", (const char *) schema->targetNamespace);
  4175. else
  4176. fprintf(output, "no target namespace");
  4177. fprintf(output, "\n");
  4178. if (schema->annot != NULL)
  4179. xmlSchemaAnnotDump(output, schema->annot);
  4180. xmlHashScan(schema->typeDecl, xmlSchemaTypeDumpEntry, output);
  4181. xmlHashScanFull(schema->elemDecl, xmlSchemaElementDump, output);
  4182. }
  4183. #ifdef DEBUG_IDC_NODE_TABLE
  4184. /**
  4185. * xmlSchemaDebugDumpIDCTable:
  4186. * @vctxt: the WXS validation context
  4187. *
  4188. * Displays the current IDC table for debug purposes.
  4189. */
  4190. static void
  4191. xmlSchemaDebugDumpIDCTable(FILE * output,
  4192. const xmlChar *namespaceName,
  4193. const xmlChar *localName,
  4194. xmlSchemaPSVIIDCBindingPtr bind)
  4195. {
  4196. xmlChar *str = NULL;
  4197. const xmlChar *value;
  4198. xmlSchemaPSVIIDCNodePtr tab;
  4199. xmlSchemaPSVIIDCKeyPtr key;
  4200. int i, j, res;
  4201. fprintf(output, "IDC: TABLES on '%s'\n",
  4202. xmlSchemaFormatQName(&str, namespaceName, localName));
  4203. FREE_AND_NULL(str)
  4204. if (bind == NULL)
  4205. return;
  4206. do {
  4207. fprintf(output, "IDC: BINDING '%s' (%d)\n",
  4208. xmlSchemaGetComponentQName(&str,
  4209. bind->definition), bind->nbNodes);
  4210. FREE_AND_NULL(str)
  4211. for (i = 0; i < bind->nbNodes; i++) {
  4212. tab = bind->nodeTable[i];
  4213. fprintf(output, " ( ");
  4214. for (j = 0; j < bind->definition->nbFields; j++) {
  4215. key = tab->keys[j];
  4216. if ((key != NULL) && (key->val != NULL)) {
  4217. res = xmlSchemaGetCanonValue(key->val, &value);
  4218. if (res >= 0)
  4219. fprintf(output, "'%s' ", value);
  4220. else
  4221. fprintf(output, "CANON-VALUE-FAILED ");
  4222. if (res == 0)
  4223. FREE_AND_NULL(value)
  4224. } else if (key != NULL)
  4225. fprintf(output, "(no val), ");
  4226. else
  4227. fprintf(output, "(key missing), ");
  4228. }
  4229. fprintf(output, ")\n");
  4230. }
  4231. if (bind->dupls && bind->dupls->nbItems) {
  4232. fprintf(output, "IDC: dupls (%d):\n", bind->dupls->nbItems);
  4233. for (i = 0; i < bind->dupls->nbItems; i++) {
  4234. tab = bind->dupls->items[i];
  4235. fprintf(output, " ( ");
  4236. for (j = 0; j < bind->definition->nbFields; j++) {
  4237. key = tab->keys[j];
  4238. if ((key != NULL) && (key->val != NULL)) {
  4239. res = xmlSchemaGetCanonValue(key->val, &value);
  4240. if (res >= 0)
  4241. fprintf(output, "'%s' ", value);
  4242. else
  4243. fprintf(output, "CANON-VALUE-FAILED ");
  4244. if (res == 0)
  4245. FREE_AND_NULL(value)
  4246. } else if (key != NULL)
  4247. fprintf(output, "(no val), ");
  4248. else
  4249. fprintf(output, "(key missing), ");
  4250. }
  4251. fprintf(output, ")\n");
  4252. }
  4253. }
  4254. bind = bind->next;
  4255. } while (bind != NULL);
  4256. }
  4257. #endif /* DEBUG_IDC */
  4258. #endif /* LIBXML_OUTPUT_ENABLED */
  4259. /************************************************************************
  4260. * *
  4261. * Utilities *
  4262. * *
  4263. ************************************************************************/
  4264. /**
  4265. * xmlSchemaGetPropNode:
  4266. * @node: the element node
  4267. * @name: the name of the attribute
  4268. *
  4269. * Seeks an attribute with a name of @name in
  4270. * no namespace.
  4271. *
  4272. * Returns the attribute or NULL if not present.
  4273. */
  4274. static xmlAttrPtr
  4275. xmlSchemaGetPropNode(xmlNodePtr node, const char *name)
  4276. {
  4277. xmlAttrPtr prop;
  4278. if ((node == NULL) || (name == NULL))
  4279. return(NULL);
  4280. prop = node->properties;
  4281. while (prop != NULL) {
  4282. if ((prop->ns == NULL) && xmlStrEqual(prop->name, BAD_CAST name))
  4283. return(prop);
  4284. prop = prop->next;
  4285. }
  4286. return (NULL);
  4287. }
  4288. /**
  4289. * xmlSchemaGetPropNodeNs:
  4290. * @node: the element node
  4291. * @uri: the uri
  4292. * @name: the name of the attribute
  4293. *
  4294. * Seeks an attribute with a local name of @name and
  4295. * a namespace URI of @uri.
  4296. *
  4297. * Returns the attribute or NULL if not present.
  4298. */
  4299. static xmlAttrPtr
  4300. xmlSchemaGetPropNodeNs(xmlNodePtr node, const char *uri, const char *name)
  4301. {
  4302. xmlAttrPtr prop;
  4303. if ((node == NULL) || (name == NULL))
  4304. return(NULL);
  4305. prop = node->properties;
  4306. while (prop != NULL) {
  4307. if ((prop->ns != NULL) &&
  4308. xmlStrEqual(prop->name, BAD_CAST name) &&
  4309. xmlStrEqual(prop->ns->href, BAD_CAST uri))
  4310. return(prop);
  4311. prop = prop->next;
  4312. }
  4313. return (NULL);
  4314. }
  4315. static const xmlChar *
  4316. xmlSchemaGetNodeContent(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node)
  4317. {
  4318. xmlChar *val;
  4319. const xmlChar *ret;
  4320. val = xmlNodeGetContent(node);
  4321. if (val == NULL)
  4322. val = xmlStrdup((xmlChar *)"");
  4323. ret = xmlDictLookup(ctxt->dict, val, -1);
  4324. xmlFree(val);
  4325. return(ret);
  4326. }
  4327. static const xmlChar *
  4328. xmlSchemaGetNodeContentNoDict(xmlNodePtr node)
  4329. {
  4330. return((const xmlChar*) xmlNodeGetContent(node));
  4331. }
  4332. /**
  4333. * xmlSchemaGetProp:
  4334. * @ctxt: the parser context
  4335. * @node: the node
  4336. * @name: the property name
  4337. *
  4338. * Read a attribute value and internalize the string
  4339. *
  4340. * Returns the string or NULL if not present.
  4341. */
  4342. static const xmlChar *
  4343. xmlSchemaGetProp(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  4344. const char *name)
  4345. {
  4346. xmlChar *val;
  4347. const xmlChar *ret;
  4348. val = xmlGetNoNsProp(node, BAD_CAST name);
  4349. if (val == NULL)
  4350. return(NULL);
  4351. ret = xmlDictLookup(ctxt->dict, val, -1);
  4352. xmlFree(val);
  4353. return(ret);
  4354. }
  4355. /************************************************************************
  4356. * *
  4357. * Parsing functions *
  4358. * *
  4359. ************************************************************************/
  4360. #define WXS_FIND_GLOBAL_ITEM(slot) \
  4361. if (xmlStrEqual(nsName, schema->targetNamespace)) { \
  4362. ret = xmlHashLookup(schema->slot, name); \
  4363. if (ret != NULL) goto exit; \
  4364. } \
  4365. if (xmlHashSize(schema->schemasImports) > 1) { \
  4366. xmlSchemaImportPtr import; \
  4367. if (nsName == NULL) \
  4368. import = xmlHashLookup(schema->schemasImports, \
  4369. XML_SCHEMAS_NO_NAMESPACE); \
  4370. else \
  4371. import = xmlHashLookup(schema->schemasImports, nsName); \
  4372. if (import == NULL) \
  4373. goto exit; \
  4374. ret = xmlHashLookup(import->schema->slot, name); \
  4375. }
  4376. /**
  4377. * xmlSchemaGetElem:
  4378. * @schema: the schema context
  4379. * @name: the element name
  4380. * @ns: the element namespace
  4381. *
  4382. * Lookup a global element declaration in the schema.
  4383. *
  4384. * Returns the element declaration or NULL if not found.
  4385. */
  4386. static xmlSchemaElementPtr
  4387. xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
  4388. const xmlChar * nsName)
  4389. {
  4390. xmlSchemaElementPtr ret = NULL;
  4391. if ((name == NULL) || (schema == NULL))
  4392. return(NULL);
  4393. if (schema != NULL) {
  4394. WXS_FIND_GLOBAL_ITEM(elemDecl)
  4395. }
  4396. exit:
  4397. #ifdef DEBUG
  4398. if (ret == NULL) {
  4399. if (nsName == NULL)
  4400. fprintf(stderr, "Unable to lookup element decl. %s", name);
  4401. else
  4402. fprintf(stderr, "Unable to lookup element decl. %s:%s", name,
  4403. nsName);
  4404. }
  4405. #endif
  4406. return (ret);
  4407. }
  4408. /**
  4409. * xmlSchemaGetType:
  4410. * @schema: the main schema
  4411. * @name: the type's name
  4412. * nsName: the type's namespace
  4413. *
  4414. * Lookup a type in the schemas or the predefined types
  4415. *
  4416. * Returns the group definition or NULL if not found.
  4417. */
  4418. static xmlSchemaTypePtr
  4419. xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
  4420. const xmlChar * nsName)
  4421. {
  4422. xmlSchemaTypePtr ret = NULL;
  4423. if (name == NULL)
  4424. return (NULL);
  4425. /* First try the built-in types. */
  4426. if ((nsName != NULL) && xmlStrEqual(nsName, xmlSchemaNs)) {
  4427. ret = xmlSchemaGetPredefinedType(name, nsName);
  4428. if (ret != NULL)
  4429. goto exit;
  4430. /*
  4431. * Note that we try the parsed schemas as well here
  4432. * since one might have parsed the S4S, which contain more
  4433. * than the built-in types.
  4434. * TODO: Can we optimize this?
  4435. */
  4436. }
  4437. if (schema != NULL) {
  4438. WXS_FIND_GLOBAL_ITEM(typeDecl)
  4439. }
  4440. exit:
  4441. #ifdef DEBUG
  4442. if (ret == NULL) {
  4443. if (nsName == NULL)
  4444. fprintf(stderr, "Unable to lookup type %s", name);
  4445. else
  4446. fprintf(stderr, "Unable to lookup type %s:%s", name,
  4447. nsName);
  4448. }
  4449. #endif
  4450. return (ret);
  4451. }
  4452. /**
  4453. * xmlSchemaGetAttributeDecl:
  4454. * @schema: the context of the schema
  4455. * @name: the name of the attribute
  4456. * @ns: the target namespace of the attribute
  4457. *
  4458. * Lookup a an attribute in the schema or imported schemas
  4459. *
  4460. * Returns the attribute declaration or NULL if not found.
  4461. */
  4462. static xmlSchemaAttributePtr
  4463. xmlSchemaGetAttributeDecl(xmlSchemaPtr schema, const xmlChar * name,
  4464. const xmlChar * nsName)
  4465. {
  4466. xmlSchemaAttributePtr ret = NULL;
  4467. if ((name == NULL) || (schema == NULL))
  4468. return (NULL);
  4469. if (schema != NULL) {
  4470. WXS_FIND_GLOBAL_ITEM(attrDecl)
  4471. }
  4472. exit:
  4473. #ifdef DEBUG
  4474. if (ret == NULL) {
  4475. if (nsName == NULL)
  4476. fprintf(stderr, "Unable to lookup attribute %s", name);
  4477. else
  4478. fprintf(stderr, "Unable to lookup attribute %s:%s", name,
  4479. nsName);
  4480. }
  4481. #endif
  4482. return (ret);
  4483. }
  4484. /**
  4485. * xmlSchemaGetAttributeGroup:
  4486. * @schema: the context of the schema
  4487. * @name: the name of the attribute group
  4488. * @ns: the target namespace of the attribute group
  4489. *
  4490. * Lookup a an attribute group in the schema or imported schemas
  4491. *
  4492. * Returns the attribute group definition or NULL if not found.
  4493. */
  4494. static xmlSchemaAttributeGroupPtr
  4495. xmlSchemaGetAttributeGroup(xmlSchemaPtr schema, const xmlChar * name,
  4496. const xmlChar * nsName)
  4497. {
  4498. xmlSchemaAttributeGroupPtr ret = NULL;
  4499. if ((name == NULL) || (schema == NULL))
  4500. return (NULL);
  4501. if (schema != NULL) {
  4502. WXS_FIND_GLOBAL_ITEM(attrgrpDecl)
  4503. }
  4504. exit:
  4505. /* TODO:
  4506. if ((ret != NULL) && (ret->redef != NULL)) {
  4507. * Return the last redefinition. *
  4508. ret = ret->redef;
  4509. }
  4510. */
  4511. #ifdef DEBUG
  4512. if (ret == NULL) {
  4513. if (nsName == NULL)
  4514. fprintf(stderr, "Unable to lookup attribute group %s", name);
  4515. else
  4516. fprintf(stderr, "Unable to lookup attribute group %s:%s", name,
  4517. nsName);
  4518. }
  4519. #endif
  4520. return (ret);
  4521. }
  4522. /**
  4523. * xmlSchemaGetGroup:
  4524. * @schema: the context of the schema
  4525. * @name: the name of the group
  4526. * @ns: the target namespace of the group
  4527. *
  4528. * Lookup a group in the schema or imported schemas
  4529. *
  4530. * Returns the group definition or NULL if not found.
  4531. */
  4532. static xmlSchemaModelGroupDefPtr
  4533. xmlSchemaGetGroup(xmlSchemaPtr schema, const xmlChar * name,
  4534. const xmlChar * nsName)
  4535. {
  4536. xmlSchemaModelGroupDefPtr ret = NULL;
  4537. if ((name == NULL) || (schema == NULL))
  4538. return (NULL);
  4539. if (schema != NULL) {
  4540. WXS_FIND_GLOBAL_ITEM(groupDecl)
  4541. }
  4542. exit:
  4543. #ifdef DEBUG
  4544. if (ret == NULL) {
  4545. if (nsName == NULL)
  4546. fprintf(stderr, "Unable to lookup group %s", name);
  4547. else
  4548. fprintf(stderr, "Unable to lookup group %s:%s", name,
  4549. nsName);
  4550. }
  4551. #endif
  4552. return (ret);
  4553. }
  4554. static xmlSchemaNotationPtr
  4555. xmlSchemaGetNotation(xmlSchemaPtr schema,
  4556. const xmlChar *name,
  4557. const xmlChar *nsName)
  4558. {
  4559. xmlSchemaNotationPtr ret = NULL;
  4560. if ((name == NULL) || (schema == NULL))
  4561. return (NULL);
  4562. if (schema != NULL) {
  4563. WXS_FIND_GLOBAL_ITEM(notaDecl)
  4564. }
  4565. exit:
  4566. return (ret);
  4567. }
  4568. static xmlSchemaIDCPtr
  4569. xmlSchemaGetIDC(xmlSchemaPtr schema,
  4570. const xmlChar *name,
  4571. const xmlChar *nsName)
  4572. {
  4573. xmlSchemaIDCPtr ret = NULL;
  4574. if ((name == NULL) || (schema == NULL))
  4575. return (NULL);
  4576. if (schema != NULL) {
  4577. WXS_FIND_GLOBAL_ITEM(idcDef)
  4578. }
  4579. exit:
  4580. return (ret);
  4581. }
  4582. /**
  4583. * xmlSchemaGetNamedComponent:
  4584. * @schema: the schema
  4585. * @name: the name of the group
  4586. * @ns: the target namespace of the group
  4587. *
  4588. * Lookup a group in the schema or imported schemas
  4589. *
  4590. * Returns the group definition or NULL if not found.
  4591. */
  4592. static xmlSchemaBasicItemPtr
  4593. xmlSchemaGetNamedComponent(xmlSchemaPtr schema,
  4594. xmlSchemaTypeType itemType,
  4595. const xmlChar *name,
  4596. const xmlChar *targetNs)
  4597. {
  4598. switch (itemType) {
  4599. case XML_SCHEMA_TYPE_GROUP:
  4600. return ((xmlSchemaBasicItemPtr) xmlSchemaGetGroup(schema,
  4601. name, targetNs));
  4602. case XML_SCHEMA_TYPE_ELEMENT:
  4603. return ((xmlSchemaBasicItemPtr) xmlSchemaGetElem(schema,
  4604. name, targetNs));
  4605. default:
  4606. TODO
  4607. return (NULL);
  4608. }
  4609. }
  4610. /************************************************************************
  4611. * *
  4612. * Parsing functions *
  4613. * *
  4614. ************************************************************************/
  4615. #define IS_BLANK_NODE(n) \
  4616. (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content, -1)))
  4617. /**
  4618. * xmlSchemaIsBlank:
  4619. * @str: a string
  4620. * @len: the length of the string or -1
  4621. *
  4622. * Check if a string is ignorable
  4623. *
  4624. * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
  4625. */
  4626. static int
  4627. xmlSchemaIsBlank(xmlChar * str, int len)
  4628. {
  4629. if (str == NULL)
  4630. return (1);
  4631. if (len < 0) {
  4632. while (*str != 0) {
  4633. if (!(IS_BLANK_CH(*str)))
  4634. return (0);
  4635. str++;
  4636. }
  4637. } else while ((*str != 0) && (len != 0)) {
  4638. if (!(IS_BLANK_CH(*str)))
  4639. return (0);
  4640. str++;
  4641. len--;
  4642. }
  4643. return (1);
  4644. }
  4645. #define WXS_COMP_NAME(c, t) ((t) (c))->name
  4646. #define WXS_COMP_TNS(c, t) ((t) (c))->targetNamespace
  4647. /*
  4648. * xmlSchemaFindRedefCompInGraph:
  4649. * ATTENTION TODO: This uses pointer comp. for strings.
  4650. */
  4651. static xmlSchemaBasicItemPtr
  4652. xmlSchemaFindRedefCompInGraph(xmlSchemaBucketPtr bucket,
  4653. xmlSchemaTypeType type,
  4654. const xmlChar *name,
  4655. const xmlChar *nsName)
  4656. {
  4657. xmlSchemaBasicItemPtr ret;
  4658. int i;
  4659. if ((bucket == NULL) || (name == NULL))
  4660. return(NULL);
  4661. if ((bucket->globals == NULL) ||
  4662. (bucket->globals->nbItems == 0))
  4663. goto subschemas;
  4664. /*
  4665. * Search in global components.
  4666. */
  4667. for (i = 0; i < bucket->globals->nbItems; i++) {
  4668. ret = bucket->globals->items[i];
  4669. if (ret->type == type) {
  4670. switch (type) {
  4671. case XML_SCHEMA_TYPE_COMPLEX:
  4672. case XML_SCHEMA_TYPE_SIMPLE:
  4673. if ((WXS_COMP_NAME(ret, xmlSchemaTypePtr) == name) &&
  4674. (WXS_COMP_TNS(ret, xmlSchemaTypePtr) ==
  4675. nsName))
  4676. {
  4677. return(ret);
  4678. }
  4679. break;
  4680. case XML_SCHEMA_TYPE_GROUP:
  4681. if ((WXS_COMP_NAME(ret,
  4682. xmlSchemaModelGroupDefPtr) == name) &&
  4683. (WXS_COMP_TNS(ret,
  4684. xmlSchemaModelGroupDefPtr) == nsName))
  4685. {
  4686. return(ret);
  4687. }
  4688. break;
  4689. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  4690. if ((WXS_COMP_NAME(ret,
  4691. xmlSchemaAttributeGroupPtr) == name) &&
  4692. (WXS_COMP_TNS(ret,
  4693. xmlSchemaAttributeGroupPtr) == nsName))
  4694. {
  4695. return(ret);
  4696. }
  4697. break;
  4698. default:
  4699. /* Should not be hit. */
  4700. return(NULL);
  4701. }
  4702. }
  4703. }
  4704. subschemas:
  4705. /*
  4706. * Process imported/included schemas.
  4707. */
  4708. if (bucket->relations != NULL) {
  4709. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  4710. /*
  4711. * TODO: Marking the bucket will not avoid multiple searches
  4712. * in the same schema, but avoids at least circularity.
  4713. */
  4714. bucket->flags |= XML_SCHEMA_BUCKET_MARKED;
  4715. do {
  4716. if ((rel->bucket != NULL) &&
  4717. ((rel->bucket->flags & XML_SCHEMA_BUCKET_MARKED) == 0)) {
  4718. ret = xmlSchemaFindRedefCompInGraph(rel->bucket,
  4719. type, name, nsName);
  4720. if (ret != NULL)
  4721. return(ret);
  4722. }
  4723. rel = rel->next;
  4724. } while (rel != NULL);
  4725. bucket->flags ^= XML_SCHEMA_BUCKET_MARKED;
  4726. }
  4727. return(NULL);
  4728. }
  4729. /**
  4730. * xmlSchemaAddNotation:
  4731. * @ctxt: a schema parser context
  4732. * @schema: the schema being built
  4733. * @name: the item name
  4734. *
  4735. * Add an XML schema annotation declaration
  4736. * *WARNING* this interface is highly subject to change
  4737. *
  4738. * Returns the new structure or NULL in case of error
  4739. */
  4740. static xmlSchemaNotationPtr
  4741. xmlSchemaAddNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4742. const xmlChar *name, const xmlChar *nsName,
  4743. xmlNodePtr node ATTRIBUTE_UNUSED)
  4744. {
  4745. xmlSchemaNotationPtr ret = NULL;
  4746. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  4747. return (NULL);
  4748. ret = (xmlSchemaNotationPtr) xmlMalloc(sizeof(xmlSchemaNotation));
  4749. if (ret == NULL) {
  4750. xmlSchemaPErrMemory(ctxt, "add annotation", NULL);
  4751. return (NULL);
  4752. }
  4753. memset(ret, 0, sizeof(xmlSchemaNotation));
  4754. ret->type = XML_SCHEMA_TYPE_NOTATION;
  4755. ret->name = name;
  4756. ret->targetNamespace = nsName;
  4757. /* TODO: do we need the node to be set?
  4758. * ret->node = node;*/
  4759. WXS_ADD_GLOBAL(ctxt, ret);
  4760. return (ret);
  4761. }
  4762. /**
  4763. * xmlSchemaAddAttribute:
  4764. * @ctxt: a schema parser context
  4765. * @schema: the schema being built
  4766. * @name: the item name
  4767. * @namespace: the namespace
  4768. *
  4769. * Add an XML schema Attribute declaration
  4770. * *WARNING* this interface is highly subject to change
  4771. *
  4772. * Returns the new structure or NULL in case of error
  4773. */
  4774. static xmlSchemaAttributePtr
  4775. xmlSchemaAddAttribute(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4776. const xmlChar * name, const xmlChar * nsName,
  4777. xmlNodePtr node, int topLevel)
  4778. {
  4779. xmlSchemaAttributePtr ret = NULL;
  4780. if ((ctxt == NULL) || (schema == NULL))
  4781. return (NULL);
  4782. ret = (xmlSchemaAttributePtr) xmlMalloc(sizeof(xmlSchemaAttribute));
  4783. if (ret == NULL) {
  4784. xmlSchemaPErrMemory(ctxt, "allocating attribute", NULL);
  4785. return (NULL);
  4786. }
  4787. memset(ret, 0, sizeof(xmlSchemaAttribute));
  4788. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE;
  4789. ret->node = node;
  4790. ret->name = name;
  4791. ret->targetNamespace = nsName;
  4792. if (topLevel)
  4793. WXS_ADD_GLOBAL(ctxt, ret);
  4794. else
  4795. WXS_ADD_LOCAL(ctxt, ret);
  4796. WXS_ADD_PENDING(ctxt, ret);
  4797. return (ret);
  4798. }
  4799. /**
  4800. * xmlSchemaAddAttributeUse:
  4801. * @ctxt: a schema parser context
  4802. * @schema: the schema being built
  4803. * @name: the item name
  4804. * @namespace: the namespace
  4805. *
  4806. * Add an XML schema Attribute declaration
  4807. * *WARNING* this interface is highly subject to change
  4808. *
  4809. * Returns the new structure or NULL in case of error
  4810. */
  4811. static xmlSchemaAttributeUsePtr
  4812. xmlSchemaAddAttributeUse(xmlSchemaParserCtxtPtr pctxt,
  4813. xmlNodePtr node)
  4814. {
  4815. xmlSchemaAttributeUsePtr ret = NULL;
  4816. if (pctxt == NULL)
  4817. return (NULL);
  4818. ret = (xmlSchemaAttributeUsePtr) xmlMalloc(sizeof(xmlSchemaAttributeUse));
  4819. if (ret == NULL) {
  4820. xmlSchemaPErrMemory(pctxt, "allocating attribute", NULL);
  4821. return (NULL);
  4822. }
  4823. memset(ret, 0, sizeof(xmlSchemaAttributeUse));
  4824. ret->type = XML_SCHEMA_TYPE_ATTRIBUTE_USE;
  4825. ret->node = node;
  4826. WXS_ADD_LOCAL(pctxt, ret);
  4827. return (ret);
  4828. }
  4829. /*
  4830. * xmlSchemaAddRedef:
  4831. *
  4832. * Adds a redefinition information. This is used at a later stage to:
  4833. * resolve references to the redefined components and to check constraints.
  4834. */
  4835. static xmlSchemaRedefPtr
  4836. xmlSchemaAddRedef(xmlSchemaParserCtxtPtr pctxt,
  4837. xmlSchemaBucketPtr targetBucket,
  4838. void *item,
  4839. const xmlChar *refName,
  4840. const xmlChar *refTargetNs)
  4841. {
  4842. xmlSchemaRedefPtr ret;
  4843. ret = (xmlSchemaRedefPtr)
  4844. xmlMalloc(sizeof(xmlSchemaRedef));
  4845. if (ret == NULL) {
  4846. xmlSchemaPErrMemory(pctxt,
  4847. "allocating redefinition info", NULL);
  4848. return (NULL);
  4849. }
  4850. memset(ret, 0, sizeof(xmlSchemaRedef));
  4851. ret->item = item;
  4852. ret->targetBucket = targetBucket;
  4853. ret->refName = refName;
  4854. ret->refTargetNs = refTargetNs;
  4855. if (WXS_CONSTRUCTOR(pctxt)->redefs == NULL)
  4856. WXS_CONSTRUCTOR(pctxt)->redefs = ret;
  4857. else
  4858. WXS_CONSTRUCTOR(pctxt)->lastRedef->next = ret;
  4859. WXS_CONSTRUCTOR(pctxt)->lastRedef = ret;
  4860. return (ret);
  4861. }
  4862. /**
  4863. * xmlSchemaAddAttributeGroupDefinition:
  4864. * @ctxt: a schema parser context
  4865. * @schema: the schema being built
  4866. * @name: the item name
  4867. * @nsName: the target namespace
  4868. * @node: the corresponding node
  4869. *
  4870. * Add an XML schema Attribute Group definition.
  4871. *
  4872. * Returns the new structure or NULL in case of error
  4873. */
  4874. static xmlSchemaAttributeGroupPtr
  4875. xmlSchemaAddAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  4876. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  4877. const xmlChar *name,
  4878. const xmlChar *nsName,
  4879. xmlNodePtr node)
  4880. {
  4881. xmlSchemaAttributeGroupPtr ret = NULL;
  4882. if ((pctxt == NULL) || (name == NULL))
  4883. return (NULL);
  4884. ret = (xmlSchemaAttributeGroupPtr)
  4885. xmlMalloc(sizeof(xmlSchemaAttributeGroup));
  4886. if (ret == NULL) {
  4887. xmlSchemaPErrMemory(pctxt, "allocating attribute group", NULL);
  4888. return (NULL);
  4889. }
  4890. memset(ret, 0, sizeof(xmlSchemaAttributeGroup));
  4891. ret->type = XML_SCHEMA_TYPE_ATTRIBUTEGROUP;
  4892. ret->name = name;
  4893. ret->targetNamespace = nsName;
  4894. ret->node = node;
  4895. /* TODO: Remove the flag. */
  4896. ret->flags |= XML_SCHEMAS_ATTRGROUP_GLOBAL;
  4897. if (pctxt->isRedefine) {
  4898. pctxt->redef = xmlSchemaAddRedef(pctxt, pctxt->redefined,
  4899. ret, name, nsName);
  4900. if (pctxt->redef == NULL) {
  4901. xmlFree(ret);
  4902. return(NULL);
  4903. }
  4904. pctxt->redefCounter = 0;
  4905. }
  4906. WXS_ADD_GLOBAL(pctxt, ret);
  4907. WXS_ADD_PENDING(pctxt, ret);
  4908. return (ret);
  4909. }
  4910. /**
  4911. * xmlSchemaAddElement:
  4912. * @ctxt: a schema parser context
  4913. * @schema: the schema being built
  4914. * @name: the type name
  4915. * @namespace: the type namespace
  4916. *
  4917. * Add an XML schema Element declaration
  4918. * *WARNING* this interface is highly subject to change
  4919. *
  4920. * Returns the new structure or NULL in case of error
  4921. */
  4922. static xmlSchemaElementPtr
  4923. xmlSchemaAddElement(xmlSchemaParserCtxtPtr ctxt,
  4924. const xmlChar * name, const xmlChar * nsName,
  4925. xmlNodePtr node, int topLevel)
  4926. {
  4927. xmlSchemaElementPtr ret = NULL;
  4928. if ((ctxt == NULL) || (name == NULL))
  4929. return (NULL);
  4930. ret = (xmlSchemaElementPtr) xmlMalloc(sizeof(xmlSchemaElement));
  4931. if (ret == NULL) {
  4932. xmlSchemaPErrMemory(ctxt, "allocating element", NULL);
  4933. return (NULL);
  4934. }
  4935. memset(ret, 0, sizeof(xmlSchemaElement));
  4936. ret->type = XML_SCHEMA_TYPE_ELEMENT;
  4937. ret->name = name;
  4938. ret->targetNamespace = nsName;
  4939. ret->node = node;
  4940. if (topLevel)
  4941. WXS_ADD_GLOBAL(ctxt, ret);
  4942. else
  4943. WXS_ADD_LOCAL(ctxt, ret);
  4944. WXS_ADD_PENDING(ctxt, ret);
  4945. return (ret);
  4946. }
  4947. /**
  4948. * xmlSchemaAddType:
  4949. * @ctxt: a schema parser context
  4950. * @schema: the schema being built
  4951. * @name: the item name
  4952. * @namespace: the namespace
  4953. *
  4954. * Add an XML schema item
  4955. * *WARNING* this interface is highly subject to change
  4956. *
  4957. * Returns the new structure or NULL in case of error
  4958. */
  4959. static xmlSchemaTypePtr
  4960. xmlSchemaAddType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  4961. xmlSchemaTypeType type,
  4962. const xmlChar * name, const xmlChar * nsName,
  4963. xmlNodePtr node, int topLevel)
  4964. {
  4965. xmlSchemaTypePtr ret = NULL;
  4966. if ((ctxt == NULL) || (schema == NULL))
  4967. return (NULL);
  4968. ret = (xmlSchemaTypePtr) xmlMalloc(sizeof(xmlSchemaType));
  4969. if (ret == NULL) {
  4970. xmlSchemaPErrMemory(ctxt, "allocating type", NULL);
  4971. return (NULL);
  4972. }
  4973. memset(ret, 0, sizeof(xmlSchemaType));
  4974. ret->type = type;
  4975. ret->name = name;
  4976. ret->targetNamespace = nsName;
  4977. ret->node = node;
  4978. if (topLevel) {
  4979. if (ctxt->isRedefine) {
  4980. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  4981. ret, name, nsName);
  4982. if (ctxt->redef == NULL) {
  4983. xmlFree(ret);
  4984. return(NULL);
  4985. }
  4986. ctxt->redefCounter = 0;
  4987. }
  4988. WXS_ADD_GLOBAL(ctxt, ret);
  4989. } else
  4990. WXS_ADD_LOCAL(ctxt, ret);
  4991. WXS_ADD_PENDING(ctxt, ret);
  4992. return (ret);
  4993. }
  4994. static xmlSchemaQNameRefPtr
  4995. xmlSchemaNewQNameRef(xmlSchemaParserCtxtPtr pctxt,
  4996. xmlSchemaTypeType refType,
  4997. const xmlChar *refName,
  4998. const xmlChar *refNs)
  4999. {
  5000. xmlSchemaQNameRefPtr ret;
  5001. ret = (xmlSchemaQNameRefPtr)
  5002. xmlMalloc(sizeof(xmlSchemaQNameRef));
  5003. if (ret == NULL) {
  5004. xmlSchemaPErrMemory(pctxt,
  5005. "allocating QName reference item", NULL);
  5006. return (NULL);
  5007. }
  5008. ret->node = NULL;
  5009. ret->type = XML_SCHEMA_EXTRA_QNAMEREF;
  5010. ret->name = refName;
  5011. ret->targetNamespace = refNs;
  5012. ret->item = NULL;
  5013. ret->itemType = refType;
  5014. /*
  5015. * Store the reference item in the schema.
  5016. */
  5017. WXS_ADD_LOCAL(pctxt, ret);
  5018. return (ret);
  5019. }
  5020. static xmlSchemaAttributeUseProhibPtr
  5021. xmlSchemaAddAttributeUseProhib(xmlSchemaParserCtxtPtr pctxt)
  5022. {
  5023. xmlSchemaAttributeUseProhibPtr ret;
  5024. ret = (xmlSchemaAttributeUseProhibPtr)
  5025. xmlMalloc(sizeof(xmlSchemaAttributeUseProhib));
  5026. if (ret == NULL) {
  5027. xmlSchemaPErrMemory(pctxt,
  5028. "allocating attribute use prohibition", NULL);
  5029. return (NULL);
  5030. }
  5031. memset(ret, 0, sizeof(xmlSchemaAttributeUseProhib));
  5032. ret->type = XML_SCHEMA_EXTRA_ATTR_USE_PROHIB;
  5033. WXS_ADD_LOCAL(pctxt, ret);
  5034. return (ret);
  5035. }
  5036. /**
  5037. * xmlSchemaAddModelGroup:
  5038. * @ctxt: a schema parser context
  5039. * @schema: the schema being built
  5040. * @type: the "compositor" type of the model group
  5041. * @node: the node in the schema doc
  5042. *
  5043. * Adds a schema model group
  5044. * *WARNING* this interface is highly subject to change
  5045. *
  5046. * Returns the new structure or NULL in case of error
  5047. */
  5048. static xmlSchemaModelGroupPtr
  5049. xmlSchemaAddModelGroup(xmlSchemaParserCtxtPtr ctxt,
  5050. xmlSchemaPtr schema,
  5051. xmlSchemaTypeType type,
  5052. xmlNodePtr node)
  5053. {
  5054. xmlSchemaModelGroupPtr ret = NULL;
  5055. if ((ctxt == NULL) || (schema == NULL))
  5056. return (NULL);
  5057. ret = (xmlSchemaModelGroupPtr)
  5058. xmlMalloc(sizeof(xmlSchemaModelGroup));
  5059. if (ret == NULL) {
  5060. xmlSchemaPErrMemory(ctxt, "allocating model group component",
  5061. NULL);
  5062. return (NULL);
  5063. }
  5064. memset(ret, 0, sizeof(xmlSchemaModelGroup));
  5065. ret->type = type;
  5066. ret->node = node;
  5067. WXS_ADD_LOCAL(ctxt, ret);
  5068. if ((type == XML_SCHEMA_TYPE_SEQUENCE) ||
  5069. (type == XML_SCHEMA_TYPE_CHOICE))
  5070. WXS_ADD_PENDING(ctxt, ret);
  5071. return (ret);
  5072. }
  5073. /**
  5074. * xmlSchemaAddParticle:
  5075. * @ctxt: a schema parser context
  5076. * @schema: the schema being built
  5077. * @node: the corresponding node in the schema doc
  5078. * @min: the minOccurs
  5079. * @max: the maxOccurs
  5080. *
  5081. * Adds an XML schema particle component.
  5082. * *WARNING* this interface is highly subject to change
  5083. *
  5084. * Returns the new structure or NULL in case of error
  5085. */
  5086. static xmlSchemaParticlePtr
  5087. xmlSchemaAddParticle(xmlSchemaParserCtxtPtr ctxt,
  5088. xmlNodePtr node, int min, int max)
  5089. {
  5090. xmlSchemaParticlePtr ret = NULL;
  5091. if (ctxt == NULL)
  5092. return (NULL);
  5093. #ifdef DEBUG
  5094. fprintf(stderr, "Adding particle component\n");
  5095. #endif
  5096. ret = (xmlSchemaParticlePtr)
  5097. xmlMalloc(sizeof(xmlSchemaParticle));
  5098. if (ret == NULL) {
  5099. xmlSchemaPErrMemory(ctxt, "allocating particle component",
  5100. NULL);
  5101. return (NULL);
  5102. }
  5103. ret->type = XML_SCHEMA_TYPE_PARTICLE;
  5104. ret->annot = NULL;
  5105. ret->node = node;
  5106. ret->minOccurs = min;
  5107. ret->maxOccurs = max;
  5108. ret->next = NULL;
  5109. ret->children = NULL;
  5110. WXS_ADD_LOCAL(ctxt, ret);
  5111. /*
  5112. * Note that addition to pending components will be done locally
  5113. * to the specific parsing function, since the most particles
  5114. * need not to be fixed up (i.e. the reference to be resolved).
  5115. * REMOVED: WXS_ADD_PENDING(ctxt, ret);
  5116. */
  5117. return (ret);
  5118. }
  5119. /**
  5120. * xmlSchemaAddModelGroupDefinition:
  5121. * @ctxt: a schema validation context
  5122. * @schema: the schema being built
  5123. * @name: the group name
  5124. *
  5125. * Add an XML schema Group definition
  5126. *
  5127. * Returns the new structure or NULL in case of error
  5128. */
  5129. static xmlSchemaModelGroupDefPtr
  5130. xmlSchemaAddModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  5131. xmlSchemaPtr schema,
  5132. const xmlChar *name,
  5133. const xmlChar *nsName,
  5134. xmlNodePtr node)
  5135. {
  5136. xmlSchemaModelGroupDefPtr ret = NULL;
  5137. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5138. return (NULL);
  5139. ret = (xmlSchemaModelGroupDefPtr)
  5140. xmlMalloc(sizeof(xmlSchemaModelGroupDef));
  5141. if (ret == NULL) {
  5142. xmlSchemaPErrMemory(ctxt, "adding group", NULL);
  5143. return (NULL);
  5144. }
  5145. memset(ret, 0, sizeof(xmlSchemaModelGroupDef));
  5146. ret->name = name;
  5147. ret->type = XML_SCHEMA_TYPE_GROUP;
  5148. ret->node = node;
  5149. ret->targetNamespace = nsName;
  5150. if (ctxt->isRedefine) {
  5151. ctxt->redef = xmlSchemaAddRedef(ctxt, ctxt->redefined,
  5152. ret, name, nsName);
  5153. if (ctxt->redef == NULL) {
  5154. xmlFree(ret);
  5155. return(NULL);
  5156. }
  5157. ctxt->redefCounter = 0;
  5158. }
  5159. WXS_ADD_GLOBAL(ctxt, ret);
  5160. WXS_ADD_PENDING(ctxt, ret);
  5161. return (ret);
  5162. }
  5163. /**
  5164. * xmlSchemaNewWildcardNs:
  5165. * @ctxt: a schema validation context
  5166. *
  5167. * Creates a new wildcard namespace constraint.
  5168. *
  5169. * Returns the new structure or NULL in case of error
  5170. */
  5171. static xmlSchemaWildcardNsPtr
  5172. xmlSchemaNewWildcardNsConstraint(xmlSchemaParserCtxtPtr ctxt)
  5173. {
  5174. xmlSchemaWildcardNsPtr ret;
  5175. ret = (xmlSchemaWildcardNsPtr)
  5176. xmlMalloc(sizeof(xmlSchemaWildcardNs));
  5177. if (ret == NULL) {
  5178. xmlSchemaPErrMemory(ctxt, "creating wildcard namespace constraint", NULL);
  5179. return (NULL);
  5180. }
  5181. ret->value = NULL;
  5182. ret->next = NULL;
  5183. return (ret);
  5184. }
  5185. static xmlSchemaIDCPtr
  5186. xmlSchemaAddIDC(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5187. const xmlChar *name, const xmlChar *nsName,
  5188. int category, xmlNodePtr node)
  5189. {
  5190. xmlSchemaIDCPtr ret = NULL;
  5191. if ((ctxt == NULL) || (schema == NULL) || (name == NULL))
  5192. return (NULL);
  5193. ret = (xmlSchemaIDCPtr) xmlMalloc(sizeof(xmlSchemaIDC));
  5194. if (ret == NULL) {
  5195. xmlSchemaPErrMemory(ctxt,
  5196. "allocating an identity-constraint definition", NULL);
  5197. return (NULL);
  5198. }
  5199. memset(ret, 0, sizeof(xmlSchemaIDC));
  5200. /* The target namespace of the parent element declaration. */
  5201. ret->targetNamespace = nsName;
  5202. ret->name = name;
  5203. ret->type = category;
  5204. ret->node = node;
  5205. WXS_ADD_GLOBAL(ctxt, ret);
  5206. /*
  5207. * Only keyrefs need to be fixup up.
  5208. */
  5209. if (category == XML_SCHEMA_TYPE_IDC_KEYREF)
  5210. WXS_ADD_PENDING(ctxt, ret);
  5211. return (ret);
  5212. }
  5213. /**
  5214. * xmlSchemaAddWildcard:
  5215. * @ctxt: a schema validation context
  5216. * @schema: a schema
  5217. *
  5218. * Adds a wildcard.
  5219. * It corresponds to a xsd:anyAttribute and xsd:any.
  5220. *
  5221. * Returns the new structure or NULL in case of error
  5222. */
  5223. static xmlSchemaWildcardPtr
  5224. xmlSchemaAddWildcard(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5225. xmlSchemaTypeType type, xmlNodePtr node)
  5226. {
  5227. xmlSchemaWildcardPtr ret = NULL;
  5228. if ((ctxt == NULL) || (schema == NULL))
  5229. return (NULL);
  5230. ret = (xmlSchemaWildcardPtr) xmlMalloc(sizeof(xmlSchemaWildcard));
  5231. if (ret == NULL) {
  5232. xmlSchemaPErrMemory(ctxt, "adding wildcard", NULL);
  5233. return (NULL);
  5234. }
  5235. memset(ret, 0, sizeof(xmlSchemaWildcard));
  5236. ret->type = type;
  5237. ret->node = node;
  5238. WXS_ADD_LOCAL(ctxt, ret);
  5239. return (ret);
  5240. }
  5241. static void
  5242. xmlSchemaSubstGroupFree(xmlSchemaSubstGroupPtr group)
  5243. {
  5244. if (group == NULL)
  5245. return;
  5246. if (group->members != NULL)
  5247. xmlSchemaItemListFree(group->members);
  5248. xmlFree(group);
  5249. }
  5250. static void
  5251. xmlSchemaSubstGroupFreeEntry(void *group, const xmlChar *name ATTRIBUTE_UNUSED)
  5252. {
  5253. xmlSchemaSubstGroupFree((xmlSchemaSubstGroupPtr) group);
  5254. }
  5255. static xmlSchemaSubstGroupPtr
  5256. xmlSchemaSubstGroupAdd(xmlSchemaParserCtxtPtr pctxt,
  5257. xmlSchemaElementPtr head)
  5258. {
  5259. xmlSchemaSubstGroupPtr ret;
  5260. /* Init subst group hash. */
  5261. if (WXS_SUBST_GROUPS(pctxt) == NULL) {
  5262. WXS_SUBST_GROUPS(pctxt) = xmlHashCreateDict(10, pctxt->dict);
  5263. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5264. return(NULL);
  5265. }
  5266. /* Create a new substitution group. */
  5267. ret = (xmlSchemaSubstGroupPtr) xmlMalloc(sizeof(xmlSchemaSubstGroup));
  5268. if (ret == NULL) {
  5269. xmlSchemaPErrMemory(NULL,
  5270. "allocating a substitution group container", NULL);
  5271. return(NULL);
  5272. }
  5273. memset(ret, 0, sizeof(xmlSchemaSubstGroup));
  5274. ret->head = head;
  5275. /* Create list of members. */
  5276. ret->members = xmlSchemaItemListCreate();
  5277. if (ret->members == NULL) {
  5278. xmlSchemaSubstGroupFree(ret);
  5279. return(NULL);
  5280. }
  5281. /* Add subst group to hash. */
  5282. if (xmlHashAddEntry2(WXS_SUBST_GROUPS(pctxt),
  5283. head->name, head->targetNamespace, ret) != 0) {
  5284. PERROR_INT("xmlSchemaSubstGroupAdd",
  5285. "failed to add a new substitution container");
  5286. xmlSchemaSubstGroupFree(ret);
  5287. return(NULL);
  5288. }
  5289. return(ret);
  5290. }
  5291. static xmlSchemaSubstGroupPtr
  5292. xmlSchemaSubstGroupGet(xmlSchemaParserCtxtPtr pctxt,
  5293. xmlSchemaElementPtr head)
  5294. {
  5295. if (WXS_SUBST_GROUPS(pctxt) == NULL)
  5296. return(NULL);
  5297. return(xmlHashLookup2(WXS_SUBST_GROUPS(pctxt),
  5298. head->name, head->targetNamespace));
  5299. }
  5300. /**
  5301. * xmlSchemaAddElementSubstitutionMember:
  5302. * @pctxt: a schema parser context
  5303. * @head: the head of the substitution group
  5304. * @member: the new member of the substitution group
  5305. *
  5306. * Allocate a new annotation structure.
  5307. *
  5308. * Returns the newly allocated structure or NULL in case or error
  5309. */
  5310. static int
  5311. xmlSchemaAddElementSubstitutionMember(xmlSchemaParserCtxtPtr pctxt,
  5312. xmlSchemaElementPtr head,
  5313. xmlSchemaElementPtr member)
  5314. {
  5315. xmlSchemaSubstGroupPtr substGroup = NULL;
  5316. if ((pctxt == NULL) || (head == NULL) || (member == NULL))
  5317. return (-1);
  5318. substGroup = xmlSchemaSubstGroupGet(pctxt, head);
  5319. if (substGroup == NULL)
  5320. substGroup = xmlSchemaSubstGroupAdd(pctxt, head);
  5321. if (substGroup == NULL)
  5322. return(-1);
  5323. if (xmlSchemaItemListAdd(substGroup->members, member) == -1)
  5324. return(-1);
  5325. return(0);
  5326. }
  5327. /************************************************************************
  5328. * *
  5329. * Utilities for parsing *
  5330. * *
  5331. ************************************************************************/
  5332. /**
  5333. * xmlSchemaPValAttrNodeQNameValue:
  5334. * @ctxt: a schema parser context
  5335. * @schema: the schema context
  5336. * @ownerItem: the parent as a schema object
  5337. * @value: the QName value
  5338. * @uri: the resulting namespace URI if found
  5339. * @local: the resulting local part if found, the attribute value otherwise
  5340. *
  5341. * Extracts the local name and the URI of a QName value and validates it.
  5342. * This one is intended to be used on attribute values that
  5343. * should resolve to schema components.
  5344. *
  5345. * Returns 0, in case the QName is valid, a positive error code
  5346. * if not valid and -1 if an internal error occurs.
  5347. */
  5348. static int
  5349. xmlSchemaPValAttrNodeQNameValue(xmlSchemaParserCtxtPtr ctxt,
  5350. xmlSchemaPtr schema,
  5351. xmlSchemaBasicItemPtr ownerItem,
  5352. xmlAttrPtr attr,
  5353. const xmlChar *value,
  5354. const xmlChar **uri,
  5355. const xmlChar **local)
  5356. {
  5357. const xmlChar *pref;
  5358. xmlNsPtr ns;
  5359. int len, ret;
  5360. *uri = NULL;
  5361. *local = NULL;
  5362. ret = xmlValidateQName(value, 1);
  5363. if (ret > 0) {
  5364. xmlSchemaPSimpleTypeErr(ctxt,
  5365. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5366. ownerItem, (xmlNodePtr) attr,
  5367. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  5368. NULL, value, NULL, NULL, NULL);
  5369. *local = value;
  5370. return (ctxt->err);
  5371. } else if (ret < 0)
  5372. return (-1);
  5373. if (!strchr((char *) value, ':')) {
  5374. ns = xmlSearchNs(attr->doc, attr->parent, NULL);
  5375. if (ns)
  5376. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5377. else if (schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) {
  5378. /* TODO: move XML_SCHEMAS_INCLUDING_CONVERT_NS to the
  5379. * parser context. */
  5380. /*
  5381. * This one takes care of included schemas with no
  5382. * target namespace.
  5383. */
  5384. *uri = ctxt->targetNamespace;
  5385. }
  5386. *local = xmlDictLookup(ctxt->dict, value, -1);
  5387. return (0);
  5388. }
  5389. /*
  5390. * At this point xmlSplitQName3 has to return a local name.
  5391. */
  5392. *local = xmlSplitQName3(value, &len);
  5393. *local = xmlDictLookup(ctxt->dict, *local, -1);
  5394. pref = xmlDictLookup(ctxt->dict, value, len);
  5395. ns = xmlSearchNs(attr->doc, attr->parent, pref);
  5396. if (ns == NULL) {
  5397. xmlSchemaPSimpleTypeErr(ctxt,
  5398. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5399. ownerItem, (xmlNodePtr) attr,
  5400. xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), NULL, value,
  5401. "The value '%s' of simple type 'xs:QName' has no "
  5402. "corresponding namespace declaration in scope", value, NULL);
  5403. return (ctxt->err);
  5404. } else {
  5405. *uri = xmlDictLookup(ctxt->dict, ns->href, -1);
  5406. }
  5407. return (0);
  5408. }
  5409. /**
  5410. * xmlSchemaPValAttrNodeQName:
  5411. * @ctxt: a schema parser context
  5412. * @schema: the schema context
  5413. * @ownerItem: the owner as a schema object
  5414. * @attr: the attribute node
  5415. * @uri: the resulting namespace URI if found
  5416. * @local: the resulting local part if found, the attribute value otherwise
  5417. *
  5418. * Extracts and validates the QName of an attribute value.
  5419. * This one is intended to be used on attribute values that
  5420. * should resolve to schema components.
  5421. *
  5422. * Returns 0, in case the QName is valid, a positive error code
  5423. * if not valid and -1 if an internal error occurs.
  5424. */
  5425. static int
  5426. xmlSchemaPValAttrNodeQName(xmlSchemaParserCtxtPtr ctxt,
  5427. xmlSchemaPtr schema,
  5428. xmlSchemaBasicItemPtr ownerItem,
  5429. xmlAttrPtr attr,
  5430. const xmlChar **uri,
  5431. const xmlChar **local)
  5432. {
  5433. const xmlChar *value;
  5434. value = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5435. return (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  5436. ownerItem, attr, value, uri, local));
  5437. }
  5438. /**
  5439. * xmlSchemaPValAttrQName:
  5440. * @ctxt: a schema parser context
  5441. * @schema: the schema context
  5442. * @ownerItem: the owner as a schema object
  5443. * @ownerElem: the parent node of the attribute
  5444. * @name: the name of the attribute
  5445. * @uri: the resulting namespace URI if found
  5446. * @local: the resulting local part if found, the attribute value otherwise
  5447. *
  5448. * Extracts and validates the QName of an attribute value.
  5449. *
  5450. * Returns 0, in case the QName is valid, a positive error code
  5451. * if not valid and -1 if an internal error occurs.
  5452. */
  5453. static int
  5454. xmlSchemaPValAttrQName(xmlSchemaParserCtxtPtr ctxt,
  5455. xmlSchemaPtr schema,
  5456. xmlSchemaBasicItemPtr ownerItem,
  5457. xmlNodePtr ownerElem,
  5458. const char *name,
  5459. const xmlChar **uri,
  5460. const xmlChar **local)
  5461. {
  5462. xmlAttrPtr attr;
  5463. attr = xmlSchemaGetPropNode(ownerElem, name);
  5464. if (attr == NULL) {
  5465. *local = NULL;
  5466. *uri = NULL;
  5467. return (0);
  5468. }
  5469. return (xmlSchemaPValAttrNodeQName(ctxt, schema,
  5470. ownerItem, attr, uri, local));
  5471. }
  5472. /**
  5473. * xmlSchemaPValAttrID:
  5474. * @ctxt: a schema parser context
  5475. *
  5476. * Extracts and validates the ID of an attribute value.
  5477. *
  5478. * Returns 0, in case the ID is valid, a positive error code
  5479. * if not valid and -1 if an internal error occurs.
  5480. */
  5481. static int
  5482. xmlSchemaPValAttrNodeID(xmlSchemaParserCtxtPtr ctxt, xmlAttrPtr attr)
  5483. {
  5484. int ret;
  5485. const xmlChar *value;
  5486. if (attr == NULL)
  5487. return(0);
  5488. value = xmlSchemaGetNodeContentNoDict((xmlNodePtr) attr);
  5489. ret = xmlValidateNCName(value, 1);
  5490. if (ret == 0) {
  5491. /*
  5492. * NOTE: the IDness might have already be declared in the DTD
  5493. */
  5494. if (attr->atype != XML_ATTRIBUTE_ID) {
  5495. xmlIDPtr res;
  5496. xmlChar *strip;
  5497. /*
  5498. * TODO: Use xmlSchemaStrip here; it's not exported at this
  5499. * moment.
  5500. */
  5501. strip = xmlSchemaCollapseString(value);
  5502. if (strip != NULL) {
  5503. xmlFree((xmlChar *) value);
  5504. value = strip;
  5505. }
  5506. res = xmlAddID(NULL, attr->doc, value, attr);
  5507. if (res == NULL) {
  5508. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5509. xmlSchemaPSimpleTypeErr(ctxt,
  5510. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5511. NULL, (xmlNodePtr) attr,
  5512. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5513. NULL, NULL, "Duplicate value '%s' of simple "
  5514. "type 'xs:ID'", value, NULL);
  5515. } else
  5516. attr->atype = XML_ATTRIBUTE_ID;
  5517. }
  5518. } else if (ret > 0) {
  5519. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  5520. xmlSchemaPSimpleTypeErr(ctxt,
  5521. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5522. NULL, (xmlNodePtr) attr,
  5523. xmlSchemaGetBuiltInType(XML_SCHEMAS_ID),
  5524. NULL, NULL, "The value '%s' of simple type 'xs:ID' is "
  5525. "not a valid 'xs:NCName'",
  5526. value, NULL);
  5527. }
  5528. if (value != NULL)
  5529. xmlFree((xmlChar *)value);
  5530. return (ret);
  5531. }
  5532. static int
  5533. xmlSchemaPValAttrID(xmlSchemaParserCtxtPtr ctxt,
  5534. xmlNodePtr ownerElem,
  5535. const xmlChar *name)
  5536. {
  5537. xmlAttrPtr attr;
  5538. attr = xmlSchemaGetPropNode(ownerElem, (const char *) name);
  5539. if (attr == NULL)
  5540. return(0);
  5541. return(xmlSchemaPValAttrNodeID(ctxt, attr));
  5542. }
  5543. /**
  5544. * xmlGetMaxOccurs:
  5545. * @ctxt: a schema validation context
  5546. * @node: a subtree containing XML Schema informations
  5547. *
  5548. * Get the maxOccurs property
  5549. *
  5550. * Returns the default if not found, or the value
  5551. */
  5552. static int
  5553. xmlGetMaxOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5554. int min, int max, int def, const char *expected)
  5555. {
  5556. const xmlChar *val, *cur;
  5557. int ret = 0;
  5558. xmlAttrPtr attr;
  5559. attr = xmlSchemaGetPropNode(node, "maxOccurs");
  5560. if (attr == NULL)
  5561. return (def);
  5562. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5563. if (xmlStrEqual(val, (const xmlChar *) "unbounded")) {
  5564. if (max != UNBOUNDED) {
  5565. xmlSchemaPSimpleTypeErr(ctxt,
  5566. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5567. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5568. NULL, (xmlNodePtr) attr, NULL, expected,
  5569. val, NULL, NULL, NULL);
  5570. return (def);
  5571. } else
  5572. return (UNBOUNDED); /* encoding it with -1 might be another option */
  5573. }
  5574. cur = val;
  5575. while (IS_BLANK_CH(*cur))
  5576. cur++;
  5577. if (*cur == 0) {
  5578. xmlSchemaPSimpleTypeErr(ctxt,
  5579. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5580. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5581. NULL, (xmlNodePtr) attr, NULL, expected,
  5582. val, NULL, NULL, NULL);
  5583. return (def);
  5584. }
  5585. while ((*cur >= '0') && (*cur <= '9')) {
  5586. ret = ret * 10 + (*cur - '0');
  5587. cur++;
  5588. }
  5589. while (IS_BLANK_CH(*cur))
  5590. cur++;
  5591. /*
  5592. * TODO: Restrict the maximal value to Integer.
  5593. */
  5594. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5595. xmlSchemaPSimpleTypeErr(ctxt,
  5596. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5597. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5598. NULL, (xmlNodePtr) attr, NULL, expected,
  5599. val, NULL, NULL, NULL);
  5600. return (def);
  5601. }
  5602. return (ret);
  5603. }
  5604. /**
  5605. * xmlGetMinOccurs:
  5606. * @ctxt: a schema validation context
  5607. * @node: a subtree containing XML Schema informations
  5608. *
  5609. * Get the minOccurs property
  5610. *
  5611. * Returns the default if not found, or the value
  5612. */
  5613. static int
  5614. xmlGetMinOccurs(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node,
  5615. int min, int max, int def, const char *expected)
  5616. {
  5617. const xmlChar *val, *cur;
  5618. int ret = 0;
  5619. xmlAttrPtr attr;
  5620. attr = xmlSchemaGetPropNode(node, "minOccurs");
  5621. if (attr == NULL)
  5622. return (def);
  5623. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5624. cur = val;
  5625. while (IS_BLANK_CH(*cur))
  5626. cur++;
  5627. if (*cur == 0) {
  5628. xmlSchemaPSimpleTypeErr(ctxt,
  5629. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5630. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5631. NULL, (xmlNodePtr) attr, NULL, expected,
  5632. val, NULL, NULL, NULL);
  5633. return (def);
  5634. }
  5635. while ((*cur >= '0') && (*cur <= '9')) {
  5636. ret = ret * 10 + (*cur - '0');
  5637. cur++;
  5638. }
  5639. while (IS_BLANK_CH(*cur))
  5640. cur++;
  5641. /*
  5642. * TODO: Restrict the maximal value to Integer.
  5643. */
  5644. if ((*cur != 0) || (ret < min) || ((max != -1) && (ret > max))) {
  5645. xmlSchemaPSimpleTypeErr(ctxt,
  5646. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  5647. /* XML_SCHEMAP_INVALID_MINOCCURS, */
  5648. NULL, (xmlNodePtr) attr, NULL, expected,
  5649. val, NULL, NULL, NULL);
  5650. return (def);
  5651. }
  5652. return (ret);
  5653. }
  5654. /**
  5655. * xmlSchemaPGetBoolNodeValue:
  5656. * @ctxt: a schema validation context
  5657. * @ownerItem: the owner as a schema item
  5658. * @node: the node holding the value
  5659. *
  5660. * Converts a boolean string value into 1 or 0.
  5661. *
  5662. * Returns 0 or 1.
  5663. */
  5664. static int
  5665. xmlSchemaPGetBoolNodeValue(xmlSchemaParserCtxtPtr ctxt,
  5666. xmlSchemaBasicItemPtr ownerItem,
  5667. xmlNodePtr node)
  5668. {
  5669. xmlChar *value = NULL;
  5670. int res = 0;
  5671. value = xmlNodeGetContent(node);
  5672. /*
  5673. * 3.2.2.1 Lexical representation
  5674. * An instance of a datatype that is defined as `boolean`
  5675. * can have the following legal literals {true, false, 1, 0}.
  5676. */
  5677. if (xmlStrEqual(BAD_CAST value, BAD_CAST "true"))
  5678. res = 1;
  5679. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "false"))
  5680. res = 0;
  5681. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "1"))
  5682. res = 1;
  5683. else if (xmlStrEqual(BAD_CAST value, BAD_CAST "0"))
  5684. res = 0;
  5685. else {
  5686. xmlSchemaPSimpleTypeErr(ctxt,
  5687. XML_SCHEMAP_INVALID_BOOLEAN,
  5688. ownerItem, node,
  5689. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5690. NULL, BAD_CAST value,
  5691. NULL, NULL, NULL);
  5692. }
  5693. if (value != NULL)
  5694. xmlFree(value);
  5695. return (res);
  5696. }
  5697. /**
  5698. * xmlGetBooleanProp:
  5699. * @ctxt: a schema validation context
  5700. * @node: a subtree containing XML Schema informations
  5701. * @name: the attribute name
  5702. * @def: the default value
  5703. *
  5704. * Evaluate if a boolean property is set
  5705. *
  5706. * Returns the default if not found, 0 if found to be false,
  5707. * 1 if found to be true
  5708. */
  5709. static int
  5710. xmlGetBooleanProp(xmlSchemaParserCtxtPtr ctxt,
  5711. xmlNodePtr node,
  5712. const char *name, int def)
  5713. {
  5714. const xmlChar *val;
  5715. val = xmlSchemaGetProp(ctxt, node, name);
  5716. if (val == NULL)
  5717. return (def);
  5718. /*
  5719. * 3.2.2.1 Lexical representation
  5720. * An instance of a datatype that is defined as `boolean`
  5721. * can have the following legal literals {true, false, 1, 0}.
  5722. */
  5723. if (xmlStrEqual(val, BAD_CAST "true"))
  5724. def = 1;
  5725. else if (xmlStrEqual(val, BAD_CAST "false"))
  5726. def = 0;
  5727. else if (xmlStrEqual(val, BAD_CAST "1"))
  5728. def = 1;
  5729. else if (xmlStrEqual(val, BAD_CAST "0"))
  5730. def = 0;
  5731. else {
  5732. xmlSchemaPSimpleTypeErr(ctxt,
  5733. XML_SCHEMAP_INVALID_BOOLEAN,
  5734. NULL,
  5735. (xmlNodePtr) xmlSchemaGetPropNode(node, name),
  5736. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  5737. NULL, val, NULL, NULL, NULL);
  5738. }
  5739. return (def);
  5740. }
  5741. /************************************************************************
  5742. * *
  5743. * Schema extraction from an Infoset *
  5744. * *
  5745. ************************************************************************/
  5746. static xmlSchemaTypePtr xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr
  5747. ctxt, xmlSchemaPtr schema,
  5748. xmlNodePtr node,
  5749. int topLevel);
  5750. static xmlSchemaTypePtr xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr
  5751. ctxt,
  5752. xmlSchemaPtr schema,
  5753. xmlNodePtr node,
  5754. int topLevel);
  5755. static xmlSchemaTypePtr xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr
  5756. ctxt,
  5757. xmlSchemaPtr schema,
  5758. xmlNodePtr node,
  5759. xmlSchemaTypeType parentType);
  5760. static xmlSchemaBasicItemPtr
  5761. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  5762. xmlSchemaPtr schema,
  5763. xmlNodePtr node,
  5764. xmlSchemaItemListPtr uses,
  5765. int parentType);
  5766. static xmlSchemaTypePtr xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt,
  5767. xmlSchemaPtr schema,
  5768. xmlNodePtr node);
  5769. static xmlSchemaWildcardPtr
  5770. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  5771. xmlSchemaPtr schema, xmlNodePtr node);
  5772. /**
  5773. * xmlSchemaPValAttrNodeValue:
  5774. *
  5775. * @pctxt: a schema parser context
  5776. * @ownerItem: the schema object owner if existent
  5777. * @attr: the schema attribute node being validated
  5778. * @value: the value
  5779. * @type: the built-in type to be validated against
  5780. *
  5781. * Validates a value against the given built-in type.
  5782. * This one is intended to be used internally for validation
  5783. * of schema attribute values during parsing of the schema.
  5784. *
  5785. * Returns 0 if the value is valid, a positive error code
  5786. * number otherwise and -1 in case of an internal or API error.
  5787. */
  5788. static int
  5789. xmlSchemaPValAttrNodeValue(xmlSchemaParserCtxtPtr pctxt,
  5790. xmlSchemaBasicItemPtr ownerItem,
  5791. xmlAttrPtr attr,
  5792. const xmlChar *value,
  5793. xmlSchemaTypePtr type)
  5794. {
  5795. int ret = 0;
  5796. /*
  5797. * NOTE: Should we move this to xmlschematypes.c? Hmm, but this
  5798. * one is really meant to be used internally, so better not.
  5799. */
  5800. if ((pctxt == NULL) || (type == NULL) || (attr == NULL))
  5801. return (-1);
  5802. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5803. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5804. "the given type is not a built-in type");
  5805. return (-1);
  5806. }
  5807. switch (type->builtInType) {
  5808. case XML_SCHEMAS_NCNAME:
  5809. case XML_SCHEMAS_QNAME:
  5810. case XML_SCHEMAS_ANYURI:
  5811. case XML_SCHEMAS_TOKEN:
  5812. case XML_SCHEMAS_LANGUAGE:
  5813. ret = xmlSchemaValPredefTypeNode(type, value, NULL,
  5814. (xmlNodePtr) attr);
  5815. break;
  5816. default: {
  5817. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5818. "validation using the given type is not supported while "
  5819. "parsing a schema");
  5820. return (-1);
  5821. }
  5822. }
  5823. /*
  5824. * TODO: Should we use the S4S error codes instead?
  5825. */
  5826. if (ret < 0) {
  5827. PERROR_INT("xmlSchemaPValAttrNodeValue",
  5828. "failed to validate a schema attribute value");
  5829. return (-1);
  5830. } else if (ret > 0) {
  5831. if (WXS_IS_LIST(type))
  5832. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  5833. else
  5834. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  5835. xmlSchemaPSimpleTypeErr(pctxt,
  5836. ret, ownerItem, (xmlNodePtr) attr,
  5837. type, NULL, value, NULL, NULL, NULL);
  5838. }
  5839. return (ret);
  5840. }
  5841. /**
  5842. * xmlSchemaPValAttrNode:
  5843. *
  5844. * @ctxt: a schema parser context
  5845. * @ownerItem: the schema object owner if existent
  5846. * @attr: the schema attribute node being validated
  5847. * @type: the built-in type to be validated against
  5848. * @value: the resulting value if any
  5849. *
  5850. * Extracts and validates a value against the given built-in type.
  5851. * This one is intended to be used internally for validation
  5852. * of schema attribute values during parsing of the schema.
  5853. *
  5854. * Returns 0 if the value is valid, a positive error code
  5855. * number otherwise and -1 in case of an internal or API error.
  5856. */
  5857. static int
  5858. xmlSchemaPValAttrNode(xmlSchemaParserCtxtPtr ctxt,
  5859. xmlSchemaBasicItemPtr ownerItem,
  5860. xmlAttrPtr attr,
  5861. xmlSchemaTypePtr type,
  5862. const xmlChar **value)
  5863. {
  5864. const xmlChar *val;
  5865. if ((ctxt == NULL) || (type == NULL) || (attr == NULL))
  5866. return (-1);
  5867. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  5868. if (value != NULL)
  5869. *value = val;
  5870. return (xmlSchemaPValAttrNodeValue(ctxt, ownerItem, attr,
  5871. val, type));
  5872. }
  5873. /**
  5874. * xmlSchemaPValAttr:
  5875. *
  5876. * @ctxt: a schema parser context
  5877. * @node: the element node of the attribute
  5878. * @ownerItem: the schema object owner if existent
  5879. * @ownerElem: the owner element node
  5880. * @name: the name of the schema attribute node
  5881. * @type: the built-in type to be validated against
  5882. * @value: the resulting value if any
  5883. *
  5884. * Extracts and validates a value against the given built-in type.
  5885. * This one is intended to be used internally for validation
  5886. * of schema attribute values during parsing of the schema.
  5887. *
  5888. * Returns 0 if the value is valid, a positive error code
  5889. * number otherwise and -1 in case of an internal or API error.
  5890. */
  5891. static int
  5892. xmlSchemaPValAttr(xmlSchemaParserCtxtPtr ctxt,
  5893. xmlSchemaBasicItemPtr ownerItem,
  5894. xmlNodePtr ownerElem,
  5895. const char *name,
  5896. xmlSchemaTypePtr type,
  5897. const xmlChar **value)
  5898. {
  5899. xmlAttrPtr attr;
  5900. if ((ctxt == NULL) || (type == NULL)) {
  5901. if (value != NULL)
  5902. *value = NULL;
  5903. return (-1);
  5904. }
  5905. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  5906. if (value != NULL)
  5907. *value = NULL;
  5908. xmlSchemaPErr(ctxt, ownerElem,
  5909. XML_SCHEMAP_INTERNAL,
  5910. "Internal error: xmlSchemaPValAttr, the given "
  5911. "type '%s' is not a built-in type.\n",
  5912. type->name, NULL);
  5913. return (-1);
  5914. }
  5915. attr = xmlSchemaGetPropNode(ownerElem, name);
  5916. if (attr == NULL) {
  5917. if (value != NULL)
  5918. *value = NULL;
  5919. return (0);
  5920. }
  5921. return (xmlSchemaPValAttrNode(ctxt, ownerItem, attr,
  5922. type, value));
  5923. }
  5924. static int
  5925. xmlSchemaCheckReference(xmlSchemaParserCtxtPtr pctxt,
  5926. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  5927. xmlNodePtr node,
  5928. xmlAttrPtr attr,
  5929. const xmlChar *namespaceName)
  5930. {
  5931. /* TODO: Pointer comparison instead? */
  5932. if (xmlStrEqual(pctxt->targetNamespace, namespaceName))
  5933. return (0);
  5934. if (xmlStrEqual(xmlSchemaNs, namespaceName))
  5935. return (0);
  5936. /*
  5937. * Check if the referenced namespace was <import>ed.
  5938. */
  5939. if (WXS_BUCKET(pctxt)->relations != NULL) {
  5940. xmlSchemaSchemaRelationPtr rel;
  5941. rel = WXS_BUCKET(pctxt)->relations;
  5942. do {
  5943. if (WXS_IS_BUCKET_IMPMAIN(rel->type) &&
  5944. xmlStrEqual(namespaceName, rel->importNamespace))
  5945. return (0);
  5946. rel = rel->next;
  5947. } while (rel != NULL);
  5948. }
  5949. /*
  5950. * No matching <import>ed namespace found.
  5951. */
  5952. {
  5953. xmlNodePtr n = (attr != NULL) ? (xmlNodePtr) attr : node;
  5954. if (namespaceName == NULL)
  5955. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  5956. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  5957. "References from this schema to components in no "
  5958. "namespace are not allowed, since not indicated by an "
  5959. "import statement", NULL, NULL);
  5960. else
  5961. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  5962. XML_SCHEMAP_SRC_RESOLVE, n, NULL,
  5963. "References from this schema to components in the "
  5964. "namespace '%s' are not allowed, since not indicated by an "
  5965. "import statement", namespaceName, NULL);
  5966. }
  5967. return (XML_SCHEMAP_SRC_RESOLVE);
  5968. }
  5969. /**
  5970. * xmlSchemaParseLocalAttributes:
  5971. * @ctxt: a schema validation context
  5972. * @schema: the schema being built
  5973. * @node: a subtree containing XML Schema informations
  5974. * @type: the hosting type where the attributes will be anchored
  5975. *
  5976. * Parses attribute uses and attribute declarations and
  5977. * attribute group references.
  5978. */
  5979. static int
  5980. xmlSchemaParseLocalAttributes(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  5981. xmlNodePtr *child, xmlSchemaItemListPtr *list,
  5982. int parentType, int *hasRefs)
  5983. {
  5984. void *item;
  5985. while ((IS_SCHEMA((*child), "attribute")) ||
  5986. (IS_SCHEMA((*child), "attributeGroup"))) {
  5987. if (IS_SCHEMA((*child), "attribute")) {
  5988. item = xmlSchemaParseLocalAttribute(ctxt, schema, *child,
  5989. *list, parentType);
  5990. } else {
  5991. item = xmlSchemaParseAttributeGroupRef(ctxt, schema, *child);
  5992. if ((item != NULL) && (hasRefs != NULL))
  5993. *hasRefs = 1;
  5994. }
  5995. if (item != NULL) {
  5996. if (*list == NULL) {
  5997. /* TODO: Customize grow factor. */
  5998. *list = xmlSchemaItemListCreate();
  5999. if (*list == NULL)
  6000. return(-1);
  6001. }
  6002. if (xmlSchemaItemListAddSize(*list, 2, item) == -1)
  6003. return(-1);
  6004. }
  6005. *child = (*child)->next;
  6006. }
  6007. return (0);
  6008. }
  6009. /**
  6010. * xmlSchemaParseAnnotation:
  6011. * @ctxt: a schema validation context
  6012. * @schema: the schema being built
  6013. * @node: a subtree containing XML Schema informations
  6014. *
  6015. * parse a XML schema Attribute declaration
  6016. * *WARNING* this interface is highly subject to change
  6017. *
  6018. * Returns -1 in case of error, 0 if the declaration is improper and
  6019. * 1 in case of success.
  6020. */
  6021. static xmlSchemaAnnotPtr
  6022. xmlSchemaParseAnnotation(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr node, int needed)
  6023. {
  6024. xmlSchemaAnnotPtr ret;
  6025. xmlNodePtr child = NULL;
  6026. xmlAttrPtr attr;
  6027. int barked = 0;
  6028. /*
  6029. * INFO: S4S completed.
  6030. */
  6031. /*
  6032. * id = ID
  6033. * {any attributes with non-schema namespace . . .}>
  6034. * Content: (appinfo | documentation)*
  6035. */
  6036. if ((ctxt == NULL) || (node == NULL))
  6037. return (NULL);
  6038. if (needed)
  6039. ret = xmlSchemaNewAnnot(ctxt, node);
  6040. else
  6041. ret = NULL;
  6042. attr = node->properties;
  6043. while (attr != NULL) {
  6044. if (((attr->ns == NULL) &&
  6045. (!xmlStrEqual(attr->name, BAD_CAST "id"))) ||
  6046. ((attr->ns != NULL) &&
  6047. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6048. xmlSchemaPIllegalAttrErr(ctxt,
  6049. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6050. }
  6051. attr = attr->next;
  6052. }
  6053. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6054. /*
  6055. * And now for the children...
  6056. */
  6057. child = node->children;
  6058. while (child != NULL) {
  6059. if (IS_SCHEMA(child, "appinfo")) {
  6060. /* TODO: make available the content of "appinfo". */
  6061. /*
  6062. * source = anyURI
  6063. * {any attributes with non-schema namespace . . .}>
  6064. * Content: ({any})*
  6065. */
  6066. attr = child->properties;
  6067. while (attr != NULL) {
  6068. if (((attr->ns == NULL) &&
  6069. (!xmlStrEqual(attr->name, BAD_CAST "source"))) ||
  6070. ((attr->ns != NULL) &&
  6071. xmlStrEqual(attr->ns->href, xmlSchemaNs))) {
  6072. xmlSchemaPIllegalAttrErr(ctxt,
  6073. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6074. }
  6075. attr = attr->next;
  6076. }
  6077. xmlSchemaPValAttr(ctxt, NULL, child, "source",
  6078. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  6079. child = child->next;
  6080. } else if (IS_SCHEMA(child, "documentation")) {
  6081. /* TODO: make available the content of "documentation". */
  6082. /*
  6083. * source = anyURI
  6084. * {any attributes with non-schema namespace . . .}>
  6085. * Content: ({any})*
  6086. */
  6087. attr = child->properties;
  6088. while (attr != NULL) {
  6089. if (attr->ns == NULL) {
  6090. if (!xmlStrEqual(attr->name, BAD_CAST "source")) {
  6091. xmlSchemaPIllegalAttrErr(ctxt,
  6092. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6093. }
  6094. } else {
  6095. if (xmlStrEqual(attr->ns->href, xmlSchemaNs) ||
  6096. (xmlStrEqual(attr->name, BAD_CAST "lang") &&
  6097. (!xmlStrEqual(attr->ns->href, XML_XML_NAMESPACE)))) {
  6098. xmlSchemaPIllegalAttrErr(ctxt,
  6099. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6100. }
  6101. }
  6102. attr = attr->next;
  6103. }
  6104. /*
  6105. * Attribute "xml:lang".
  6106. */
  6107. attr = xmlSchemaGetPropNodeNs(child, (const char *) XML_XML_NAMESPACE, "lang");
  6108. if (attr != NULL)
  6109. xmlSchemaPValAttrNode(ctxt, NULL, attr,
  6110. xmlSchemaGetBuiltInType(XML_SCHEMAS_LANGUAGE), NULL);
  6111. child = child->next;
  6112. } else {
  6113. if (!barked)
  6114. xmlSchemaPContentErr(ctxt,
  6115. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6116. NULL, node, child, NULL, "(appinfo | documentation)*");
  6117. barked = 1;
  6118. child = child->next;
  6119. }
  6120. }
  6121. return (ret);
  6122. }
  6123. /**
  6124. * xmlSchemaParseFacet:
  6125. * @ctxt: a schema validation context
  6126. * @schema: the schema being built
  6127. * @node: a subtree containing XML Schema informations
  6128. *
  6129. * parse a XML schema Facet declaration
  6130. * *WARNING* this interface is highly subject to change
  6131. *
  6132. * Returns the new type structure or NULL in case of error
  6133. */
  6134. static xmlSchemaFacetPtr
  6135. xmlSchemaParseFacet(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6136. xmlNodePtr node)
  6137. {
  6138. xmlSchemaFacetPtr facet;
  6139. xmlNodePtr child = NULL;
  6140. const xmlChar *value;
  6141. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6142. return (NULL);
  6143. facet = xmlSchemaNewFacet();
  6144. if (facet == NULL) {
  6145. xmlSchemaPErrMemory(ctxt, "allocating facet", node);
  6146. return (NULL);
  6147. }
  6148. facet->node = node;
  6149. value = xmlSchemaGetProp(ctxt, node, "value");
  6150. if (value == NULL) {
  6151. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_FACET_NO_VALUE,
  6152. "Facet %s has no value\n", node->name, NULL);
  6153. xmlSchemaFreeFacet(facet);
  6154. return (NULL);
  6155. }
  6156. if (IS_SCHEMA(node, "minInclusive")) {
  6157. facet->type = XML_SCHEMA_FACET_MININCLUSIVE;
  6158. } else if (IS_SCHEMA(node, "minExclusive")) {
  6159. facet->type = XML_SCHEMA_FACET_MINEXCLUSIVE;
  6160. } else if (IS_SCHEMA(node, "maxInclusive")) {
  6161. facet->type = XML_SCHEMA_FACET_MAXINCLUSIVE;
  6162. } else if (IS_SCHEMA(node, "maxExclusive")) {
  6163. facet->type = XML_SCHEMA_FACET_MAXEXCLUSIVE;
  6164. } else if (IS_SCHEMA(node, "totalDigits")) {
  6165. facet->type = XML_SCHEMA_FACET_TOTALDIGITS;
  6166. } else if (IS_SCHEMA(node, "fractionDigits")) {
  6167. facet->type = XML_SCHEMA_FACET_FRACTIONDIGITS;
  6168. } else if (IS_SCHEMA(node, "pattern")) {
  6169. facet->type = XML_SCHEMA_FACET_PATTERN;
  6170. } else if (IS_SCHEMA(node, "enumeration")) {
  6171. facet->type = XML_SCHEMA_FACET_ENUMERATION;
  6172. } else if (IS_SCHEMA(node, "whiteSpace")) {
  6173. facet->type = XML_SCHEMA_FACET_WHITESPACE;
  6174. } else if (IS_SCHEMA(node, "length")) {
  6175. facet->type = XML_SCHEMA_FACET_LENGTH;
  6176. } else if (IS_SCHEMA(node, "maxLength")) {
  6177. facet->type = XML_SCHEMA_FACET_MAXLENGTH;
  6178. } else if (IS_SCHEMA(node, "minLength")) {
  6179. facet->type = XML_SCHEMA_FACET_MINLENGTH;
  6180. } else {
  6181. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_TYPE,
  6182. "Unknown facet type %s\n", node->name, NULL);
  6183. xmlSchemaFreeFacet(facet);
  6184. return (NULL);
  6185. }
  6186. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6187. facet->value = value;
  6188. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  6189. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  6190. const xmlChar *fixed;
  6191. fixed = xmlSchemaGetProp(ctxt, node, "fixed");
  6192. if (fixed != NULL) {
  6193. if (xmlStrEqual(fixed, BAD_CAST "true"))
  6194. facet->fixed = 1;
  6195. }
  6196. }
  6197. child = node->children;
  6198. if (IS_SCHEMA(child, "annotation")) {
  6199. facet->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6200. child = child->next;
  6201. }
  6202. if (child != NULL) {
  6203. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_UNKNOWN_FACET_CHILD,
  6204. "Facet %s has unexpected child content\n",
  6205. node->name, NULL);
  6206. }
  6207. return (facet);
  6208. }
  6209. /**
  6210. * xmlSchemaParseWildcardNs:
  6211. * @ctxt: a schema parser context
  6212. * @wildc: the wildcard, already created
  6213. * @node: a subtree containing XML Schema informations
  6214. *
  6215. * Parses the attribute "processContents" and "namespace"
  6216. * of a xsd:anyAttribute and xsd:any.
  6217. * *WARNING* this interface is highly subject to change
  6218. *
  6219. * Returns 0 if everything goes fine, a positive error code
  6220. * if something is not valid and -1 if an internal error occurs.
  6221. */
  6222. static int
  6223. xmlSchemaParseWildcardNs(xmlSchemaParserCtxtPtr ctxt,
  6224. xmlSchemaPtr schema ATTRIBUTE_UNUSED,
  6225. xmlSchemaWildcardPtr wildc,
  6226. xmlNodePtr node)
  6227. {
  6228. const xmlChar *pc, *ns, *dictnsItem;
  6229. int ret = 0;
  6230. xmlChar *nsItem;
  6231. xmlSchemaWildcardNsPtr tmp, lastNs = NULL;
  6232. xmlAttrPtr attr;
  6233. pc = xmlSchemaGetProp(ctxt, node, "processContents");
  6234. if ((pc == NULL)
  6235. || (xmlStrEqual(pc, (const xmlChar *) "strict"))) {
  6236. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6237. } else if (xmlStrEqual(pc, (const xmlChar *) "skip")) {
  6238. wildc->processContents = XML_SCHEMAS_ANY_SKIP;
  6239. } else if (xmlStrEqual(pc, (const xmlChar *) "lax")) {
  6240. wildc->processContents = XML_SCHEMAS_ANY_LAX;
  6241. } else {
  6242. xmlSchemaPSimpleTypeErr(ctxt,
  6243. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6244. NULL, node,
  6245. NULL, "(strict | skip | lax)", pc,
  6246. NULL, NULL, NULL);
  6247. wildc->processContents = XML_SCHEMAS_ANY_STRICT;
  6248. ret = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  6249. }
  6250. /*
  6251. * Build the namespace constraints.
  6252. */
  6253. attr = xmlSchemaGetPropNode(node, "namespace");
  6254. ns = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  6255. if ((attr == NULL) || (xmlStrEqual(ns, BAD_CAST "##any")))
  6256. wildc->any = 1;
  6257. else if (xmlStrEqual(ns, BAD_CAST "##other")) {
  6258. wildc->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  6259. if (wildc->negNsSet == NULL) {
  6260. return (-1);
  6261. }
  6262. wildc->negNsSet->value = ctxt->targetNamespace;
  6263. } else {
  6264. const xmlChar *end, *cur;
  6265. cur = ns;
  6266. do {
  6267. while (IS_BLANK_CH(*cur))
  6268. cur++;
  6269. end = cur;
  6270. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  6271. end++;
  6272. if (end == cur)
  6273. break;
  6274. nsItem = xmlStrndup(cur, end - cur);
  6275. if ((xmlStrEqual(nsItem, BAD_CAST "##other")) ||
  6276. (xmlStrEqual(nsItem, BAD_CAST "##any"))) {
  6277. xmlSchemaPSimpleTypeErr(ctxt,
  6278. XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER,
  6279. NULL, (xmlNodePtr) attr,
  6280. NULL,
  6281. "((##any | ##other) | List of (xs:anyURI | "
  6282. "(##targetNamespace | ##local)))",
  6283. nsItem, NULL, NULL, NULL);
  6284. ret = XML_SCHEMAP_WILDCARD_INVALID_NS_MEMBER;
  6285. } else {
  6286. if (xmlStrEqual(nsItem, BAD_CAST "##targetNamespace")) {
  6287. dictnsItem = ctxt->targetNamespace;
  6288. } else if (xmlStrEqual(nsItem, BAD_CAST "##local")) {
  6289. dictnsItem = NULL;
  6290. } else {
  6291. /*
  6292. * Validate the item (anyURI).
  6293. */
  6294. xmlSchemaPValAttrNodeValue(ctxt, NULL, attr,
  6295. nsItem, xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI));
  6296. dictnsItem = xmlDictLookup(ctxt->dict, nsItem, -1);
  6297. }
  6298. /*
  6299. * Avoid duplicate namespaces.
  6300. */
  6301. tmp = wildc->nsSet;
  6302. while (tmp != NULL) {
  6303. if (dictnsItem == tmp->value)
  6304. break;
  6305. tmp = tmp->next;
  6306. }
  6307. if (tmp == NULL) {
  6308. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  6309. if (tmp == NULL) {
  6310. xmlFree(nsItem);
  6311. return (-1);
  6312. }
  6313. tmp->value = dictnsItem;
  6314. tmp->next = NULL;
  6315. if (wildc->nsSet == NULL)
  6316. wildc->nsSet = tmp;
  6317. else if (lastNs != NULL)
  6318. lastNs->next = tmp;
  6319. lastNs = tmp;
  6320. }
  6321. }
  6322. xmlFree(nsItem);
  6323. cur = end;
  6324. } while (*cur != 0);
  6325. }
  6326. return (ret);
  6327. }
  6328. static int
  6329. xmlSchemaPCheckParticleCorrect_2(xmlSchemaParserCtxtPtr ctxt,
  6330. xmlSchemaParticlePtr item ATTRIBUTE_UNUSED,
  6331. xmlNodePtr node,
  6332. int minOccurs,
  6333. int maxOccurs) {
  6334. if ((maxOccurs == 0) && ( minOccurs == 0))
  6335. return (0);
  6336. if (maxOccurs != UNBOUNDED) {
  6337. /*
  6338. * TODO: Maybe we should better not create the particle,
  6339. * if min/max is invalid, since it could confuse the build of the
  6340. * content model.
  6341. */
  6342. /*
  6343. * 3.9.6 Schema Component Constraint: Particle Correct
  6344. *
  6345. */
  6346. if (maxOccurs < 1) {
  6347. /*
  6348. * 2.2 {max occurs} must be greater than or equal to 1.
  6349. */
  6350. xmlSchemaPCustomAttrErr(ctxt,
  6351. XML_SCHEMAP_P_PROPS_CORRECT_2_2,
  6352. NULL, NULL,
  6353. xmlSchemaGetPropNode(node, "maxOccurs"),
  6354. "The value must be greater than or equal to 1");
  6355. return (XML_SCHEMAP_P_PROPS_CORRECT_2_2);
  6356. } else if (minOccurs > maxOccurs) {
  6357. /*
  6358. * 2.1 {min occurs} must not be greater than {max occurs}.
  6359. */
  6360. xmlSchemaPCustomAttrErr(ctxt,
  6361. XML_SCHEMAP_P_PROPS_CORRECT_2_1,
  6362. NULL, NULL,
  6363. xmlSchemaGetPropNode(node, "minOccurs"),
  6364. "The value must not be greater than the value of 'maxOccurs'");
  6365. return (XML_SCHEMAP_P_PROPS_CORRECT_2_1);
  6366. }
  6367. }
  6368. return (0);
  6369. }
  6370. /**
  6371. * xmlSchemaParseAny:
  6372. * @ctxt: a schema validation context
  6373. * @schema: the schema being built
  6374. * @node: a subtree containing XML Schema informations
  6375. *
  6376. * Parsea a XML schema <any> element. A particle and wildcard
  6377. * will be created (except if minOccurs==maxOccurs==0, in this case
  6378. * nothing will be created).
  6379. * *WARNING* this interface is highly subject to change
  6380. *
  6381. * Returns the particle or NULL in case of error or if minOccurs==maxOccurs==0
  6382. */
  6383. static xmlSchemaParticlePtr
  6384. xmlSchemaParseAny(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6385. xmlNodePtr node)
  6386. {
  6387. xmlSchemaParticlePtr particle;
  6388. xmlNodePtr child = NULL;
  6389. xmlSchemaWildcardPtr wild;
  6390. int min, max;
  6391. xmlAttrPtr attr;
  6392. xmlSchemaAnnotPtr annot = NULL;
  6393. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6394. return (NULL);
  6395. /*
  6396. * Check for illegal attributes.
  6397. */
  6398. attr = node->properties;
  6399. while (attr != NULL) {
  6400. if (attr->ns == NULL) {
  6401. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6402. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  6403. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  6404. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6405. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6406. xmlSchemaPIllegalAttrErr(ctxt,
  6407. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6408. }
  6409. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6410. xmlSchemaPIllegalAttrErr(ctxt,
  6411. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6412. }
  6413. attr = attr->next;
  6414. }
  6415. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6416. /*
  6417. * minOccurs/maxOccurs.
  6418. */
  6419. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  6420. "(xs:nonNegativeInteger | unbounded)");
  6421. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1,
  6422. "xs:nonNegativeInteger");
  6423. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  6424. /*
  6425. * Create & parse the wildcard.
  6426. */
  6427. wild = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY, node);
  6428. if (wild == NULL)
  6429. return (NULL);
  6430. xmlSchemaParseWildcardNs(ctxt, schema, wild, node);
  6431. /*
  6432. * And now for the children...
  6433. */
  6434. child = node->children;
  6435. if (IS_SCHEMA(child, "annotation")) {
  6436. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6437. child = child->next;
  6438. }
  6439. if (child != NULL) {
  6440. xmlSchemaPContentErr(ctxt,
  6441. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6442. NULL, node, child,
  6443. NULL, "(annotation?)");
  6444. }
  6445. /*
  6446. * No component if minOccurs==maxOccurs==0.
  6447. */
  6448. if ((min == 0) && (max == 0)) {
  6449. /* Don't free the wildcard, since it's already on the list. */
  6450. return (NULL);
  6451. }
  6452. /*
  6453. * Create the particle.
  6454. */
  6455. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  6456. if (particle == NULL)
  6457. return (NULL);
  6458. particle->annot = annot;
  6459. particle->children = (xmlSchemaTreeItemPtr) wild;
  6460. return (particle);
  6461. }
  6462. /**
  6463. * xmlSchemaParseNotation:
  6464. * @ctxt: a schema validation context
  6465. * @schema: the schema being built
  6466. * @node: a subtree containing XML Schema informations
  6467. *
  6468. * parse a XML schema Notation declaration
  6469. *
  6470. * Returns the new structure or NULL in case of error
  6471. */
  6472. static xmlSchemaNotationPtr
  6473. xmlSchemaParseNotation(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  6474. xmlNodePtr node)
  6475. {
  6476. const xmlChar *name;
  6477. xmlSchemaNotationPtr ret;
  6478. xmlNodePtr child = NULL;
  6479. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6480. return (NULL);
  6481. name = xmlSchemaGetProp(ctxt, node, "name");
  6482. if (name == NULL) {
  6483. xmlSchemaPErr2(ctxt, node, child, XML_SCHEMAP_NOTATION_NO_NAME,
  6484. "Notation has no name\n", NULL, NULL);
  6485. return (NULL);
  6486. }
  6487. ret = xmlSchemaAddNotation(ctxt, schema, name,
  6488. ctxt->targetNamespace, node);
  6489. if (ret == NULL)
  6490. return (NULL);
  6491. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6492. child = node->children;
  6493. if (IS_SCHEMA(child, "annotation")) {
  6494. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6495. child = child->next;
  6496. }
  6497. if (child != NULL) {
  6498. xmlSchemaPContentErr(ctxt,
  6499. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6500. NULL, node, child,
  6501. NULL, "(annotation?)");
  6502. }
  6503. return (ret);
  6504. }
  6505. /**
  6506. * xmlSchemaParseAnyAttribute:
  6507. * @ctxt: a schema validation context
  6508. * @schema: the schema being built
  6509. * @node: a subtree containing XML Schema informations
  6510. *
  6511. * parse a XML schema AnyAttribute declaration
  6512. * *WARNING* this interface is highly subject to change
  6513. *
  6514. * Returns a wildcard or NULL.
  6515. */
  6516. static xmlSchemaWildcardPtr
  6517. xmlSchemaParseAnyAttribute(xmlSchemaParserCtxtPtr ctxt,
  6518. xmlSchemaPtr schema, xmlNodePtr node)
  6519. {
  6520. xmlSchemaWildcardPtr ret;
  6521. xmlNodePtr child = NULL;
  6522. xmlAttrPtr attr;
  6523. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  6524. return (NULL);
  6525. ret = xmlSchemaAddWildcard(ctxt, schema, XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  6526. node);
  6527. if (ret == NULL) {
  6528. return (NULL);
  6529. }
  6530. /*
  6531. * Check for illegal attributes.
  6532. */
  6533. attr = node->properties;
  6534. while (attr != NULL) {
  6535. if (attr->ns == NULL) {
  6536. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  6537. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  6538. (!xmlStrEqual(attr->name, BAD_CAST "processContents"))) {
  6539. xmlSchemaPIllegalAttrErr(ctxt,
  6540. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6541. }
  6542. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  6543. xmlSchemaPIllegalAttrErr(ctxt,
  6544. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6545. }
  6546. attr = attr->next;
  6547. }
  6548. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  6549. /*
  6550. * Parse the namespace list.
  6551. */
  6552. if (xmlSchemaParseWildcardNs(ctxt, schema, ret, node) != 0)
  6553. return (NULL);
  6554. /*
  6555. * And now for the children...
  6556. */
  6557. child = node->children;
  6558. if (IS_SCHEMA(child, "annotation")) {
  6559. ret->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  6560. child = child->next;
  6561. }
  6562. if (child != NULL) {
  6563. xmlSchemaPContentErr(ctxt,
  6564. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6565. NULL, node, child,
  6566. NULL, "(annotation?)");
  6567. }
  6568. return (ret);
  6569. }
  6570. /**
  6571. * xmlSchemaParseAttribute:
  6572. * @ctxt: a schema validation context
  6573. * @schema: the schema being built
  6574. * @node: a subtree containing XML Schema informations
  6575. *
  6576. * parse a XML schema Attribute declaration
  6577. * *WARNING* this interface is highly subject to change
  6578. *
  6579. * Returns the attribute declaration.
  6580. */
  6581. static xmlSchemaBasicItemPtr
  6582. xmlSchemaParseLocalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6583. xmlSchemaPtr schema,
  6584. xmlNodePtr node,
  6585. xmlSchemaItemListPtr uses,
  6586. int parentType)
  6587. {
  6588. const xmlChar *attrValue, *name = NULL, *ns = NULL;
  6589. xmlSchemaAttributeUsePtr use = NULL;
  6590. xmlNodePtr child = NULL;
  6591. xmlAttrPtr attr;
  6592. const xmlChar *tmpNs = NULL, *tmpName = NULL, *defValue = NULL;
  6593. int isRef = 0, occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6594. int nberrors, hasForm = 0, defValueType = 0;
  6595. #define WXS_ATTR_DEF_VAL_DEFAULT 1
  6596. #define WXS_ATTR_DEF_VAL_FIXED 2
  6597. /*
  6598. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6599. */
  6600. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6601. return (NULL);
  6602. attr = xmlSchemaGetPropNode(node, "ref");
  6603. if (attr != NULL) {
  6604. if (xmlSchemaPValAttrNodeQName(pctxt, schema,
  6605. NULL, attr, &tmpNs, &tmpName) != 0) {
  6606. return (NULL);
  6607. }
  6608. if (xmlSchemaCheckReference(pctxt, schema, node, attr, tmpNs) != 0)
  6609. return(NULL);
  6610. isRef = 1;
  6611. }
  6612. nberrors = pctxt->nberrors;
  6613. /*
  6614. * Check for illegal attributes.
  6615. */
  6616. attr = node->properties;
  6617. while (attr != NULL) {
  6618. if (attr->ns == NULL) {
  6619. if (isRef) {
  6620. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6621. xmlSchemaPValAttrNodeID(pctxt, attr);
  6622. goto attr_next;
  6623. } else if (xmlStrEqual(attr->name, BAD_CAST "ref")) {
  6624. goto attr_next;
  6625. }
  6626. } else {
  6627. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  6628. goto attr_next;
  6629. } else if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  6630. xmlSchemaPValAttrNodeID(pctxt, attr);
  6631. goto attr_next;
  6632. } else if (xmlStrEqual(attr->name, BAD_CAST "type")) {
  6633. xmlSchemaPValAttrNodeQName(pctxt, schema, NULL,
  6634. attr, &tmpNs, &tmpName);
  6635. goto attr_next;
  6636. } else if (xmlStrEqual(attr->name, BAD_CAST "form")) {
  6637. /*
  6638. * Evaluate the target namespace
  6639. */
  6640. hasForm = 1;
  6641. attrValue = xmlSchemaGetNodeContent(pctxt,
  6642. (xmlNodePtr) attr);
  6643. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  6644. ns = pctxt->targetNamespace;
  6645. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified"))
  6646. {
  6647. xmlSchemaPSimpleTypeErr(pctxt,
  6648. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  6649. NULL, (xmlNodePtr) attr,
  6650. NULL, "(qualified | unqualified)",
  6651. attrValue, NULL, NULL, NULL);
  6652. }
  6653. goto attr_next;
  6654. }
  6655. }
  6656. if (xmlStrEqual(attr->name, BAD_CAST "use")) {
  6657. attrValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6658. /* TODO: Maybe we need to normalize the value beforehand. */
  6659. if (xmlStrEqual(attrValue, BAD_CAST "optional"))
  6660. occurs = XML_SCHEMAS_ATTR_USE_OPTIONAL;
  6661. else if (xmlStrEqual(attrValue, BAD_CAST "prohibited"))
  6662. occurs = XML_SCHEMAS_ATTR_USE_PROHIBITED;
  6663. else if (xmlStrEqual(attrValue, BAD_CAST "required"))
  6664. occurs = XML_SCHEMAS_ATTR_USE_REQUIRED;
  6665. else {
  6666. xmlSchemaPSimpleTypeErr(pctxt,
  6667. XML_SCHEMAP_INVALID_ATTR_USE,
  6668. NULL, (xmlNodePtr) attr,
  6669. NULL, "(optional | prohibited | required)",
  6670. attrValue, NULL, NULL, NULL);
  6671. }
  6672. goto attr_next;
  6673. } else if (xmlStrEqual(attr->name, BAD_CAST "default")) {
  6674. /*
  6675. * 3.2.3 : 1
  6676. * default and fixed must not both be present.
  6677. */
  6678. if (defValue) {
  6679. xmlSchemaPMutualExclAttrErr(pctxt,
  6680. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6681. NULL, attr, "default", "fixed");
  6682. } else {
  6683. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6684. defValueType = WXS_ATTR_DEF_VAL_DEFAULT;
  6685. }
  6686. goto attr_next;
  6687. } else if (xmlStrEqual(attr->name, BAD_CAST "fixed")) {
  6688. /*
  6689. * 3.2.3 : 1
  6690. * default and fixed must not both be present.
  6691. */
  6692. if (defValue) {
  6693. xmlSchemaPMutualExclAttrErr(pctxt,
  6694. XML_SCHEMAP_SRC_ATTRIBUTE_1,
  6695. NULL, attr, "default", "fixed");
  6696. } else {
  6697. defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  6698. defValueType = WXS_ATTR_DEF_VAL_FIXED;
  6699. }
  6700. goto attr_next;
  6701. }
  6702. } else if (! xmlStrEqual(attr->ns->href, xmlSchemaNs))
  6703. goto attr_next;
  6704. xmlSchemaPIllegalAttrErr(pctxt,
  6705. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  6706. attr_next:
  6707. attr = attr->next;
  6708. }
  6709. /*
  6710. * 3.2.3 : 2
  6711. * If default and use are both present, use must have
  6712. * the actual value optional.
  6713. */
  6714. if ((defValueType == WXS_ATTR_DEF_VAL_DEFAULT) &&
  6715. (occurs != XML_SCHEMAS_ATTR_USE_OPTIONAL)) {
  6716. xmlSchemaPSimpleTypeErr(pctxt,
  6717. XML_SCHEMAP_SRC_ATTRIBUTE_2,
  6718. NULL, node, NULL,
  6719. "(optional | prohibited | required)", NULL,
  6720. "The value of the attribute 'use' must be 'optional' "
  6721. "if the attribute 'default' is present",
  6722. NULL, NULL);
  6723. }
  6724. /*
  6725. * We want correct attributes.
  6726. */
  6727. if (nberrors != pctxt->nberrors)
  6728. return(NULL);
  6729. if (! isRef) {
  6730. xmlSchemaAttributePtr attrDecl;
  6731. /* TODO: move XML_SCHEMAS_QUALIF_ATTR to the parser. */
  6732. if ((! hasForm) && (schema->flags & XML_SCHEMAS_QUALIF_ATTR))
  6733. ns = pctxt->targetNamespace;
  6734. /*
  6735. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  6736. * TODO: Move this to the component layer.
  6737. */
  6738. if (xmlStrEqual(ns, xmlSchemaInstanceNs)) {
  6739. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  6740. XML_SCHEMAP_NO_XSI,
  6741. node, NULL,
  6742. "The target namespace must not match '%s'",
  6743. xmlSchemaInstanceNs, NULL);
  6744. }
  6745. attr = xmlSchemaGetPropNode(node, "name");
  6746. if (attr == NULL) {
  6747. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6748. NULL, node, "name", NULL);
  6749. return (NULL);
  6750. }
  6751. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6752. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  6753. return (NULL);
  6754. }
  6755. /*
  6756. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6757. * TODO: Move this to the component layer.
  6758. */
  6759. if (xmlStrEqual(name, BAD_CAST "xmlns")) {
  6760. xmlSchemaPSimpleTypeErr(pctxt,
  6761. XML_SCHEMAP_NO_XMLNS,
  6762. NULL, (xmlNodePtr) attr,
  6763. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6764. "The value of the attribute must not match 'xmlns'",
  6765. NULL, NULL);
  6766. return (NULL);
  6767. }
  6768. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED)
  6769. goto check_children;
  6770. /*
  6771. * Create the attribute use component.
  6772. */
  6773. use = xmlSchemaAddAttributeUse(pctxt, node);
  6774. if (use == NULL)
  6775. return(NULL);
  6776. use->occurs = occurs;
  6777. /*
  6778. * Create the attribute declaration.
  6779. */
  6780. attrDecl = xmlSchemaAddAttribute(pctxt, schema, name, ns, node, 0);
  6781. if (attrDecl == NULL)
  6782. return (NULL);
  6783. if (tmpName != NULL) {
  6784. attrDecl->typeName = tmpName;
  6785. attrDecl->typeNs = tmpNs;
  6786. }
  6787. use->attrDecl = attrDecl;
  6788. /*
  6789. * Value constraint.
  6790. */
  6791. if (defValue != NULL) {
  6792. attrDecl->defValue = defValue;
  6793. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6794. attrDecl->flags |= XML_SCHEMAS_ATTR_FIXED;
  6795. }
  6796. } else if (occurs != XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6797. xmlSchemaQNameRefPtr ref;
  6798. /*
  6799. * Create the attribute use component.
  6800. */
  6801. use = xmlSchemaAddAttributeUse(pctxt, node);
  6802. if (use == NULL)
  6803. return(NULL);
  6804. /*
  6805. * We need to resolve the reference at later stage.
  6806. */
  6807. WXS_ADD_PENDING(pctxt, use);
  6808. use->occurs = occurs;
  6809. /*
  6810. * Create a QName reference to the attribute declaration.
  6811. */
  6812. ref = xmlSchemaNewQNameRef(pctxt, XML_SCHEMA_TYPE_ATTRIBUTE,
  6813. tmpName, tmpNs);
  6814. if (ref == NULL)
  6815. return(NULL);
  6816. /*
  6817. * Assign the reference. This will be substituted for the
  6818. * referenced attribute declaration when the QName is resolved.
  6819. */
  6820. use->attrDecl = WXS_ATTR_CAST ref;
  6821. /*
  6822. * Value constraint.
  6823. */
  6824. if (defValue != NULL)
  6825. use->defValue = defValue;
  6826. if (defValueType == WXS_ATTR_DEF_VAL_FIXED)
  6827. use->flags |= XML_SCHEMA_ATTR_USE_FIXED;
  6828. }
  6829. check_children:
  6830. /*
  6831. * And now for the children...
  6832. */
  6833. child = node->children;
  6834. if (occurs == XML_SCHEMAS_ATTR_USE_PROHIBITED) {
  6835. xmlSchemaAttributeUseProhibPtr prohib;
  6836. if (IS_SCHEMA(child, "annotation")) {
  6837. xmlSchemaParseAnnotation(pctxt, child, 0);
  6838. child = child->next;
  6839. }
  6840. if (child != NULL) {
  6841. xmlSchemaPContentErr(pctxt,
  6842. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6843. NULL, node, child, NULL,
  6844. "(annotation?)");
  6845. }
  6846. /*
  6847. * Check for pointlessness of attribute prohibitions.
  6848. */
  6849. if (parentType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) {
  6850. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6851. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6852. node, NULL,
  6853. "Skipping attribute use prohibition, since it is "
  6854. "pointless inside an <attributeGroup>",
  6855. NULL, NULL, NULL);
  6856. return(NULL);
  6857. } else if (parentType == XML_SCHEMA_TYPE_EXTENSION) {
  6858. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6859. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6860. node, NULL,
  6861. "Skipping attribute use prohibition, since it is "
  6862. "pointless when extending a type",
  6863. NULL, NULL, NULL);
  6864. return(NULL);
  6865. }
  6866. if (! isRef) {
  6867. tmpName = name;
  6868. tmpNs = ns;
  6869. }
  6870. /*
  6871. * Check for duplicate attribute prohibitions.
  6872. */
  6873. if (uses) {
  6874. int i;
  6875. for (i = 0; i < uses->nbItems; i++) {
  6876. use = uses->items[i];
  6877. if ((use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) &&
  6878. (tmpName == (WXS_ATTR_PROHIB_CAST use)->name) &&
  6879. (tmpNs == (WXS_ATTR_PROHIB_CAST use)->targetNamespace))
  6880. {
  6881. xmlChar *str = NULL;
  6882. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  6883. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  6884. node, NULL,
  6885. "Skipping duplicate attribute use prohibition '%s'",
  6886. xmlSchemaFormatQName(&str, tmpNs, tmpName),
  6887. NULL, NULL);
  6888. FREE_AND_NULL(str)
  6889. return(NULL);
  6890. }
  6891. }
  6892. }
  6893. /*
  6894. * Create the attribute prohibition helper component.
  6895. */
  6896. prohib = xmlSchemaAddAttributeUseProhib(pctxt);
  6897. if (prohib == NULL)
  6898. return(NULL);
  6899. prohib->node = node;
  6900. prohib->name = tmpName;
  6901. prohib->targetNamespace = tmpNs;
  6902. if (isRef) {
  6903. /*
  6904. * We need at least to resolve to the attribute declaration.
  6905. */
  6906. WXS_ADD_PENDING(pctxt, prohib);
  6907. }
  6908. return(WXS_BASIC_CAST prohib);
  6909. } else {
  6910. if (IS_SCHEMA(child, "annotation")) {
  6911. /*
  6912. * TODO: Should this go into the attr decl?
  6913. */
  6914. use->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  6915. child = child->next;
  6916. }
  6917. if (isRef) {
  6918. if (child != NULL) {
  6919. if (IS_SCHEMA(child, "simpleType"))
  6920. /*
  6921. * 3.2.3 : 3.2
  6922. * If ref is present, then all of <simpleType>,
  6923. * form and type must be absent.
  6924. */
  6925. xmlSchemaPContentErr(pctxt,
  6926. XML_SCHEMAP_SRC_ATTRIBUTE_3_2,
  6927. NULL, node, child, NULL,
  6928. "(annotation?)");
  6929. else
  6930. xmlSchemaPContentErr(pctxt,
  6931. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6932. NULL, node, child, NULL,
  6933. "(annotation?)");
  6934. }
  6935. } else {
  6936. if (IS_SCHEMA(child, "simpleType")) {
  6937. if (WXS_ATTRUSE_DECL(use)->typeName != NULL) {
  6938. /*
  6939. * 3.2.3 : 4
  6940. * type and <simpleType> must not both be present.
  6941. */
  6942. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  6943. NULL, node, child,
  6944. "The attribute 'type' and the <simpleType> child "
  6945. "are mutually exclusive", NULL);
  6946. } else
  6947. WXS_ATTRUSE_TYPEDEF(use) =
  6948. xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  6949. child = child->next;
  6950. }
  6951. if (child != NULL)
  6952. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  6953. NULL, node, child, NULL,
  6954. "(annotation?, simpleType?)");
  6955. }
  6956. }
  6957. return (WXS_BASIC_CAST use);
  6958. }
  6959. static xmlSchemaAttributePtr
  6960. xmlSchemaParseGlobalAttribute(xmlSchemaParserCtxtPtr pctxt,
  6961. xmlSchemaPtr schema,
  6962. xmlNodePtr node)
  6963. {
  6964. const xmlChar *attrValue;
  6965. xmlSchemaAttributePtr ret;
  6966. xmlNodePtr child = NULL;
  6967. xmlAttrPtr attr;
  6968. /*
  6969. * Note that the w3c spec assumes the schema to be validated with schema
  6970. * for schemas beforehand.
  6971. *
  6972. * 3.2.3 Constraints on XML Representations of Attribute Declarations
  6973. */
  6974. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  6975. return (NULL);
  6976. /*
  6977. * 3.2.3 : 3.1
  6978. * One of ref or name must be present, but not both
  6979. */
  6980. attr = xmlSchemaGetPropNode(node, "name");
  6981. if (attr == NULL) {
  6982. xmlSchemaPMissingAttrErr(pctxt, XML_SCHEMAP_S4S_ATTR_MISSING,
  6983. NULL, node, "name", NULL);
  6984. return (NULL);
  6985. }
  6986. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  6987. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0) {
  6988. return (NULL);
  6989. }
  6990. /*
  6991. * 3.2.6 Schema Component Constraint: xmlns Not Allowed
  6992. * TODO: Move this to the component layer.
  6993. */
  6994. if (xmlStrEqual(attrValue, BAD_CAST "xmlns")) {
  6995. xmlSchemaPSimpleTypeErr(pctxt,
  6996. XML_SCHEMAP_NO_XMLNS,
  6997. NULL, (xmlNodePtr) attr,
  6998. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), NULL, NULL,
  6999. "The value of the attribute must not match 'xmlns'",
  7000. NULL, NULL);
  7001. return (NULL);
  7002. }
  7003. /*
  7004. * 3.2.6 Schema Component Constraint: xsi: Not Allowed
  7005. * TODO: Move this to the component layer.
  7006. * Or better leave it here and add it to the component layer
  7007. * if we have a schema construction API.
  7008. */
  7009. if (xmlStrEqual(pctxt->targetNamespace, xmlSchemaInstanceNs)) {
  7010. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7011. XML_SCHEMAP_NO_XSI, node, NULL,
  7012. "The target namespace must not match '%s'",
  7013. xmlSchemaInstanceNs, NULL);
  7014. }
  7015. ret = xmlSchemaAddAttribute(pctxt, schema, attrValue,
  7016. pctxt->targetNamespace, node, 1);
  7017. if (ret == NULL)
  7018. return (NULL);
  7019. ret->flags |= XML_SCHEMAS_ATTR_GLOBAL;
  7020. /*
  7021. * Check for illegal attributes.
  7022. */
  7023. attr = node->properties;
  7024. while (attr != NULL) {
  7025. if (attr->ns == NULL) {
  7026. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7027. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  7028. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  7029. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7030. (!xmlStrEqual(attr->name, BAD_CAST "type")))
  7031. {
  7032. xmlSchemaPIllegalAttrErr(pctxt,
  7033. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7034. }
  7035. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7036. xmlSchemaPIllegalAttrErr(pctxt,
  7037. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7038. }
  7039. attr = attr->next;
  7040. }
  7041. xmlSchemaPValAttrQName(pctxt, schema, NULL,
  7042. node, "type", &ret->typeNs, &ret->typeName);
  7043. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7044. /*
  7045. * Attribute "fixed".
  7046. */
  7047. ret->defValue = xmlSchemaGetProp(pctxt, node, "fixed");
  7048. if (ret->defValue != NULL)
  7049. ret->flags |= XML_SCHEMAS_ATTR_FIXED;
  7050. /*
  7051. * Attribute "default".
  7052. */
  7053. attr = xmlSchemaGetPropNode(node, "default");
  7054. if (attr != NULL) {
  7055. /*
  7056. * 3.2.3 : 1
  7057. * default and fixed must not both be present.
  7058. */
  7059. if (ret->flags & XML_SCHEMAS_ATTR_FIXED) {
  7060. xmlSchemaPMutualExclAttrErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_1,
  7061. WXS_BASIC_CAST ret, attr, "default", "fixed");
  7062. } else
  7063. ret->defValue = xmlSchemaGetNodeContent(pctxt, (xmlNodePtr) attr);
  7064. }
  7065. /*
  7066. * And now for the children...
  7067. */
  7068. child = node->children;
  7069. if (IS_SCHEMA(child, "annotation")) {
  7070. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7071. child = child->next;
  7072. }
  7073. if (IS_SCHEMA(child, "simpleType")) {
  7074. if (ret->typeName != NULL) {
  7075. /*
  7076. * 3.2.3 : 4
  7077. * type and <simpleType> must not both be present.
  7078. */
  7079. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_SRC_ATTRIBUTE_4,
  7080. NULL, node, child,
  7081. "The attribute 'type' and the <simpleType> child "
  7082. "are mutually exclusive", NULL);
  7083. } else
  7084. ret->subtypes = xmlSchemaParseSimpleType(pctxt, schema, child, 0);
  7085. child = child->next;
  7086. }
  7087. if (child != NULL)
  7088. xmlSchemaPContentErr(pctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7089. NULL, node, child, NULL,
  7090. "(annotation?, simpleType?)");
  7091. return (ret);
  7092. }
  7093. /**
  7094. * xmlSchemaParseAttributeGroupRef:
  7095. * @ctxt: a schema validation context
  7096. * @schema: the schema being built
  7097. * @node: a subtree containing XML Schema informations
  7098. *
  7099. * Parse an attribute group definition reference.
  7100. * Note that a reference to an attribute group does not
  7101. * correspond to any component at all.
  7102. * *WARNING* this interface is highly subject to change
  7103. *
  7104. * Returns the attribute group or NULL in case of error.
  7105. */
  7106. static xmlSchemaQNameRefPtr
  7107. xmlSchemaParseAttributeGroupRef(xmlSchemaParserCtxtPtr pctxt,
  7108. xmlSchemaPtr schema,
  7109. xmlNodePtr node)
  7110. {
  7111. xmlSchemaQNameRefPtr ret;
  7112. xmlNodePtr child = NULL;
  7113. xmlAttrPtr attr;
  7114. const xmlChar *refNs = NULL, *ref = NULL;
  7115. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7116. return (NULL);
  7117. attr = xmlSchemaGetPropNode(node, "ref");
  7118. if (attr == NULL) {
  7119. xmlSchemaPMissingAttrErr(pctxt,
  7120. XML_SCHEMAP_S4S_ATTR_MISSING,
  7121. NULL, node, "ref", NULL);
  7122. return (NULL);
  7123. }
  7124. xmlSchemaPValAttrNodeQName(pctxt, schema,
  7125. NULL, attr, &refNs, &ref);
  7126. if (xmlSchemaCheckReference(pctxt, schema, node, attr, refNs) != 0)
  7127. return(NULL);
  7128. /*
  7129. * Check for illegal attributes.
  7130. */
  7131. attr = node->properties;
  7132. while (attr != NULL) {
  7133. if (attr->ns == NULL) {
  7134. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  7135. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7136. {
  7137. xmlSchemaPIllegalAttrErr(pctxt,
  7138. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7139. }
  7140. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7141. xmlSchemaPIllegalAttrErr(pctxt,
  7142. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7143. }
  7144. attr = attr->next;
  7145. }
  7146. /* Attribute ID */
  7147. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7148. /*
  7149. * And now for the children...
  7150. */
  7151. child = node->children;
  7152. if (IS_SCHEMA(child, "annotation")) {
  7153. /*
  7154. * TODO: We do not have a place to store the annotation, do we?
  7155. */
  7156. xmlSchemaParseAnnotation(pctxt, child, 0);
  7157. child = child->next;
  7158. }
  7159. if (child != NULL) {
  7160. xmlSchemaPContentErr(pctxt,
  7161. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7162. NULL, node, child, NULL,
  7163. "(annotation?)");
  7164. }
  7165. /*
  7166. * Handle attribute group redefinitions.
  7167. */
  7168. if (pctxt->isRedefine && pctxt->redef &&
  7169. (pctxt->redef->item->type ==
  7170. XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  7171. (ref == pctxt->redef->refName) &&
  7172. (refNs == pctxt->redef->refTargetNs))
  7173. {
  7174. /*
  7175. * SPEC src-redefine:
  7176. * (7.1) "If it has an <attributeGroup> among its contents
  7177. * the `actual value` of whose ref [attribute] is the same
  7178. * as the `actual value` of its own name attribute plus
  7179. * target namespace, then it must have exactly one such group."
  7180. */
  7181. if (pctxt->redefCounter != 0) {
  7182. xmlChar *str = NULL;
  7183. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  7184. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  7185. "The redefining attribute group definition "
  7186. "'%s' must not contain more than one "
  7187. "reference to the redefined definition",
  7188. xmlSchemaFormatQName(&str, refNs, ref), NULL);
  7189. FREE_AND_NULL(str);
  7190. return(NULL);
  7191. }
  7192. pctxt->redefCounter++;
  7193. /*
  7194. * URGENT TODO: How to ensure that the reference will not be
  7195. * handled by the normal component resolution mechanism?
  7196. */
  7197. ret = xmlSchemaNewQNameRef(pctxt,
  7198. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7199. if (ret == NULL)
  7200. return(NULL);
  7201. ret->node = node;
  7202. pctxt->redef->reference = WXS_BASIC_CAST ret;
  7203. } else {
  7204. /*
  7205. * Create a QName-reference helper component. We will substitute this
  7206. * component for the attribute uses of the referenced attribute group
  7207. * definition.
  7208. */
  7209. ret = xmlSchemaNewQNameRef(pctxt,
  7210. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, ref, refNs);
  7211. if (ret == NULL)
  7212. return(NULL);
  7213. ret->node = node;
  7214. /* Add to pending items, to be able to resolve the reference. */
  7215. WXS_ADD_PENDING(pctxt, ret);
  7216. }
  7217. return (ret);
  7218. }
  7219. /**
  7220. * xmlSchemaParseAttributeGroupDefinition:
  7221. * @pctxt: a schema validation context
  7222. * @schema: the schema being built
  7223. * @node: a subtree containing XML Schema informations
  7224. *
  7225. * parse a XML schema Attribute Group declaration
  7226. * *WARNING* this interface is highly subject to change
  7227. *
  7228. * Returns the attribute group definition or NULL in case of error.
  7229. */
  7230. static xmlSchemaAttributeGroupPtr
  7231. xmlSchemaParseAttributeGroupDefinition(xmlSchemaParserCtxtPtr pctxt,
  7232. xmlSchemaPtr schema,
  7233. xmlNodePtr node)
  7234. {
  7235. const xmlChar *name;
  7236. xmlSchemaAttributeGroupPtr ret;
  7237. xmlNodePtr child = NULL;
  7238. xmlAttrPtr attr;
  7239. int hasRefs = 0;
  7240. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  7241. return (NULL);
  7242. attr = xmlSchemaGetPropNode(node, "name");
  7243. if (attr == NULL) {
  7244. xmlSchemaPMissingAttrErr(pctxt,
  7245. XML_SCHEMAP_S4S_ATTR_MISSING,
  7246. NULL, node, "name", NULL);
  7247. return (NULL);
  7248. }
  7249. /*
  7250. * The name is crucial, exit if invalid.
  7251. */
  7252. if (xmlSchemaPValAttrNode(pctxt,
  7253. NULL, attr,
  7254. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7255. return (NULL);
  7256. }
  7257. ret = xmlSchemaAddAttributeGroupDefinition(pctxt, schema,
  7258. name, pctxt->targetNamespace, node);
  7259. if (ret == NULL)
  7260. return (NULL);
  7261. /*
  7262. * Check for illegal attributes.
  7263. */
  7264. attr = node->properties;
  7265. while (attr != NULL) {
  7266. if (attr->ns == NULL) {
  7267. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7268. (!xmlStrEqual(attr->name, BAD_CAST "id")))
  7269. {
  7270. xmlSchemaPIllegalAttrErr(pctxt,
  7271. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7272. }
  7273. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7274. xmlSchemaPIllegalAttrErr(pctxt,
  7275. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7276. }
  7277. attr = attr->next;
  7278. }
  7279. /* Attribute ID */
  7280. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  7281. /*
  7282. * And now for the children...
  7283. */
  7284. child = node->children;
  7285. if (IS_SCHEMA(child, "annotation")) {
  7286. ret->annot = xmlSchemaParseAnnotation(pctxt, child, 1);
  7287. child = child->next;
  7288. }
  7289. /*
  7290. * Parse contained attribute decls/refs.
  7291. */
  7292. if (xmlSchemaParseLocalAttributes(pctxt, schema, &child,
  7293. (xmlSchemaItemListPtr *) &(ret->attrUses),
  7294. XML_SCHEMA_TYPE_ATTRIBUTEGROUP, &hasRefs) == -1)
  7295. return(NULL);
  7296. if (hasRefs)
  7297. ret->flags |= XML_SCHEMAS_ATTRGROUP_HAS_REFS;
  7298. /*
  7299. * Parse the attribute wildcard.
  7300. */
  7301. if (IS_SCHEMA(child, "anyAttribute")) {
  7302. ret->attributeWildcard = xmlSchemaParseAnyAttribute(pctxt,
  7303. schema, child);
  7304. child = child->next;
  7305. }
  7306. if (child != NULL) {
  7307. xmlSchemaPContentErr(pctxt,
  7308. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7309. NULL, node, child, NULL,
  7310. "(annotation?, ((attribute | attributeGroup)*, anyAttribute?))");
  7311. }
  7312. return (ret);
  7313. }
  7314. /**
  7315. * xmlSchemaPValAttrFormDefault:
  7316. * @value: the value
  7317. * @flags: the flags to be modified
  7318. * @flagQualified: the specific flag for "qualified"
  7319. *
  7320. * Returns 0 if the value is valid, 1 otherwise.
  7321. */
  7322. static int
  7323. xmlSchemaPValAttrFormDefault(const xmlChar *value,
  7324. int *flags,
  7325. int flagQualified)
  7326. {
  7327. if (xmlStrEqual(value, BAD_CAST "qualified")) {
  7328. if ((*flags & flagQualified) == 0)
  7329. *flags |= flagQualified;
  7330. } else if (!xmlStrEqual(value, BAD_CAST "unqualified"))
  7331. return (1);
  7332. return (0);
  7333. }
  7334. /**
  7335. * xmlSchemaPValAttrBlockFinal:
  7336. * @value: the value
  7337. * @flags: the flags to be modified
  7338. * @flagAll: the specific flag for "#all"
  7339. * @flagExtension: the specific flag for "extension"
  7340. * @flagRestriction: the specific flag for "restriction"
  7341. * @flagSubstitution: the specific flag for "substitution"
  7342. * @flagList: the specific flag for "list"
  7343. * @flagUnion: the specific flag for "union"
  7344. *
  7345. * Validates the value of the attribute "final" and "block". The value
  7346. * is converted into the specified flag values and returned in @flags.
  7347. *
  7348. * Returns 0 if the value is valid, 1 otherwise.
  7349. */
  7350. static int
  7351. xmlSchemaPValAttrBlockFinal(const xmlChar *value,
  7352. int *flags,
  7353. int flagAll,
  7354. int flagExtension,
  7355. int flagRestriction,
  7356. int flagSubstitution,
  7357. int flagList,
  7358. int flagUnion)
  7359. {
  7360. int ret = 0;
  7361. /*
  7362. * TODO: This does not check for duplicate entries.
  7363. */
  7364. if ((flags == NULL) || (value == NULL))
  7365. return (-1);
  7366. if (value[0] == 0)
  7367. return (0);
  7368. if (xmlStrEqual(value, BAD_CAST "#all")) {
  7369. if (flagAll != -1)
  7370. *flags |= flagAll;
  7371. else {
  7372. if (flagExtension != -1)
  7373. *flags |= flagExtension;
  7374. if (flagRestriction != -1)
  7375. *flags |= flagRestriction;
  7376. if (flagSubstitution != -1)
  7377. *flags |= flagSubstitution;
  7378. if (flagList != -1)
  7379. *flags |= flagList;
  7380. if (flagUnion != -1)
  7381. *flags |= flagUnion;
  7382. }
  7383. } else {
  7384. const xmlChar *end, *cur = value;
  7385. xmlChar *item;
  7386. do {
  7387. while (IS_BLANK_CH(*cur))
  7388. cur++;
  7389. end = cur;
  7390. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  7391. end++;
  7392. if (end == cur)
  7393. break;
  7394. item = xmlStrndup(cur, end - cur);
  7395. if (xmlStrEqual(item, BAD_CAST "extension")) {
  7396. if (flagExtension != -1) {
  7397. if ((*flags & flagExtension) == 0)
  7398. *flags |= flagExtension;
  7399. } else
  7400. ret = 1;
  7401. } else if (xmlStrEqual(item, BAD_CAST "restriction")) {
  7402. if (flagRestriction != -1) {
  7403. if ((*flags & flagRestriction) == 0)
  7404. *flags |= flagRestriction;
  7405. } else
  7406. ret = 1;
  7407. } else if (xmlStrEqual(item, BAD_CAST "substitution")) {
  7408. if (flagSubstitution != -1) {
  7409. if ((*flags & flagSubstitution) == 0)
  7410. *flags |= flagSubstitution;
  7411. } else
  7412. ret = 1;
  7413. } else if (xmlStrEqual(item, BAD_CAST "list")) {
  7414. if (flagList != -1) {
  7415. if ((*flags & flagList) == 0)
  7416. *flags |= flagList;
  7417. } else
  7418. ret = 1;
  7419. } else if (xmlStrEqual(item, BAD_CAST "union")) {
  7420. if (flagUnion != -1) {
  7421. if ((*flags & flagUnion) == 0)
  7422. *flags |= flagUnion;
  7423. } else
  7424. ret = 1;
  7425. } else
  7426. ret = 1;
  7427. if (item != NULL)
  7428. xmlFree(item);
  7429. cur = end;
  7430. } while ((ret == 0) && (*cur != 0));
  7431. }
  7432. return (ret);
  7433. }
  7434. static int
  7435. xmlSchemaCheckCSelectorXPath(xmlSchemaParserCtxtPtr ctxt,
  7436. xmlSchemaIDCPtr idc,
  7437. xmlSchemaIDCSelectPtr selector,
  7438. xmlAttrPtr attr,
  7439. int isField)
  7440. {
  7441. xmlNodePtr node;
  7442. /*
  7443. * c-selector-xpath:
  7444. * Schema Component Constraint: Selector Value OK
  7445. *
  7446. * TODO: 1 The {selector} must be a valid XPath expression, as defined
  7447. * in [XPath].
  7448. */
  7449. if (selector == NULL) {
  7450. xmlSchemaPErr(ctxt, idc->node,
  7451. XML_SCHEMAP_INTERNAL,
  7452. "Internal error: xmlSchemaCheckCSelectorXPath, "
  7453. "the selector is not specified.\n", NULL, NULL);
  7454. return (-1);
  7455. }
  7456. if (attr == NULL)
  7457. node = idc->node;
  7458. else
  7459. node = (xmlNodePtr) attr;
  7460. if (selector->xpath == NULL) {
  7461. xmlSchemaPCustomErr(ctxt,
  7462. /* TODO: Adjust error code. */
  7463. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7464. NULL, node,
  7465. "The XPath expression of the selector is not valid", NULL);
  7466. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7467. } else {
  7468. const xmlChar **nsArray = NULL;
  7469. xmlNsPtr *nsList = NULL;
  7470. /*
  7471. * Compile the XPath expression.
  7472. */
  7473. /*
  7474. * TODO: We need the array of in-scope namespaces for compilation.
  7475. * TODO: Call xmlPatterncompile with different options for selector/
  7476. * field.
  7477. */
  7478. if (attr == NULL)
  7479. nsList = NULL;
  7480. else
  7481. nsList = xmlGetNsList(attr->doc, attr->parent);
  7482. /*
  7483. * Build an array of prefixes and namespaces.
  7484. */
  7485. if (nsList != NULL) {
  7486. int i, count = 0;
  7487. for (i = 0; nsList[i] != NULL; i++)
  7488. count++;
  7489. nsArray = (const xmlChar **) xmlMalloc(
  7490. (count * 2 + 1) * sizeof(const xmlChar *));
  7491. if (nsArray == NULL) {
  7492. xmlSchemaPErrMemory(ctxt, "allocating a namespace array",
  7493. NULL);
  7494. xmlFree(nsList);
  7495. return (-1);
  7496. }
  7497. for (i = 0; i < count; i++) {
  7498. nsArray[2 * i] = nsList[i]->href;
  7499. nsArray[2 * i + 1] = nsList[i]->prefix;
  7500. }
  7501. nsArray[count * 2] = NULL;
  7502. xmlFree(nsList);
  7503. }
  7504. /*
  7505. * TODO: Differentiate between "selector" and "field".
  7506. */
  7507. if (isField)
  7508. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7509. NULL, XML_PATTERN_XSFIELD, nsArray);
  7510. else
  7511. selector->xpathComp = (void *) xmlPatterncompile(selector->xpath,
  7512. NULL, XML_PATTERN_XSSEL, nsArray);
  7513. if (nsArray != NULL)
  7514. xmlFree((xmlChar **) nsArray);
  7515. if (selector->xpathComp == NULL) {
  7516. xmlSchemaPCustomErr(ctxt,
  7517. /* TODO: Adjust error code? */
  7518. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  7519. NULL, node,
  7520. "The XPath expression '%s' could not be "
  7521. "compiled", selector->xpath);
  7522. return (XML_SCHEMAP_S4S_ATTR_INVALID_VALUE);
  7523. }
  7524. }
  7525. return (0);
  7526. }
  7527. #define ADD_ANNOTATION(annot) \
  7528. xmlSchemaAnnotPtr cur = item->annot; \
  7529. if (item->annot == NULL) { \
  7530. item->annot = annot; \
  7531. return (annot); \
  7532. } \
  7533. cur = item->annot; \
  7534. if (cur->next != NULL) { \
  7535. cur = cur->next; \
  7536. } \
  7537. cur->next = annot;
  7538. /**
  7539. * xmlSchemaAssignAnnotation:
  7540. * @item: the schema component
  7541. * @annot: the annotation
  7542. *
  7543. * Adds the annotation to the given schema component.
  7544. *
  7545. * Returns the given annotation.
  7546. */
  7547. static xmlSchemaAnnotPtr
  7548. xmlSchemaAddAnnotation(xmlSchemaAnnotItemPtr annItem,
  7549. xmlSchemaAnnotPtr annot)
  7550. {
  7551. if ((annItem == NULL) || (annot == NULL))
  7552. return (NULL);
  7553. switch (annItem->type) {
  7554. case XML_SCHEMA_TYPE_ELEMENT: {
  7555. xmlSchemaElementPtr item = (xmlSchemaElementPtr) annItem;
  7556. ADD_ANNOTATION(annot)
  7557. }
  7558. break;
  7559. case XML_SCHEMA_TYPE_ATTRIBUTE: {
  7560. xmlSchemaAttributePtr item = (xmlSchemaAttributePtr) annItem;
  7561. ADD_ANNOTATION(annot)
  7562. }
  7563. break;
  7564. case XML_SCHEMA_TYPE_ANY_ATTRIBUTE:
  7565. case XML_SCHEMA_TYPE_ANY: {
  7566. xmlSchemaWildcardPtr item = (xmlSchemaWildcardPtr) annItem;
  7567. ADD_ANNOTATION(annot)
  7568. }
  7569. break;
  7570. case XML_SCHEMA_TYPE_PARTICLE:
  7571. case XML_SCHEMA_TYPE_IDC_KEY:
  7572. case XML_SCHEMA_TYPE_IDC_KEYREF:
  7573. case XML_SCHEMA_TYPE_IDC_UNIQUE: {
  7574. xmlSchemaAnnotItemPtr item = (xmlSchemaAnnotItemPtr) annItem;
  7575. ADD_ANNOTATION(annot)
  7576. }
  7577. break;
  7578. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP: {
  7579. xmlSchemaAttributeGroupPtr item =
  7580. (xmlSchemaAttributeGroupPtr) annItem;
  7581. ADD_ANNOTATION(annot)
  7582. }
  7583. break;
  7584. case XML_SCHEMA_TYPE_NOTATION: {
  7585. xmlSchemaNotationPtr item = (xmlSchemaNotationPtr) annItem;
  7586. ADD_ANNOTATION(annot)
  7587. }
  7588. break;
  7589. case XML_SCHEMA_FACET_MININCLUSIVE:
  7590. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  7591. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  7592. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  7593. case XML_SCHEMA_FACET_TOTALDIGITS:
  7594. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  7595. case XML_SCHEMA_FACET_PATTERN:
  7596. case XML_SCHEMA_FACET_ENUMERATION:
  7597. case XML_SCHEMA_FACET_WHITESPACE:
  7598. case XML_SCHEMA_FACET_LENGTH:
  7599. case XML_SCHEMA_FACET_MAXLENGTH:
  7600. case XML_SCHEMA_FACET_MINLENGTH: {
  7601. xmlSchemaFacetPtr item = (xmlSchemaFacetPtr) annItem;
  7602. ADD_ANNOTATION(annot)
  7603. }
  7604. break;
  7605. case XML_SCHEMA_TYPE_SIMPLE:
  7606. case XML_SCHEMA_TYPE_COMPLEX: {
  7607. xmlSchemaTypePtr item = (xmlSchemaTypePtr) annItem;
  7608. ADD_ANNOTATION(annot)
  7609. }
  7610. break;
  7611. case XML_SCHEMA_TYPE_GROUP: {
  7612. xmlSchemaModelGroupDefPtr item = (xmlSchemaModelGroupDefPtr) annItem;
  7613. ADD_ANNOTATION(annot)
  7614. }
  7615. break;
  7616. case XML_SCHEMA_TYPE_SEQUENCE:
  7617. case XML_SCHEMA_TYPE_CHOICE:
  7618. case XML_SCHEMA_TYPE_ALL: {
  7619. xmlSchemaModelGroupPtr item = (xmlSchemaModelGroupPtr) annItem;
  7620. ADD_ANNOTATION(annot)
  7621. }
  7622. break;
  7623. default:
  7624. xmlSchemaPCustomErr(NULL,
  7625. XML_SCHEMAP_INTERNAL,
  7626. NULL, NULL,
  7627. "Internal error: xmlSchemaAddAnnotation, "
  7628. "The item is not a annotated schema component", NULL);
  7629. break;
  7630. }
  7631. return (annot);
  7632. }
  7633. /**
  7634. * xmlSchemaParseIDCSelectorAndField:
  7635. * @ctxt: a schema validation context
  7636. * @schema: the schema being built
  7637. * @node: a subtree containing XML Schema informations
  7638. *
  7639. * Parses a XML Schema identity-constraint definition's
  7640. * <selector> and <field> elements.
  7641. *
  7642. * Returns the parsed identity-constraint definition.
  7643. */
  7644. static xmlSchemaIDCSelectPtr
  7645. xmlSchemaParseIDCSelectorAndField(xmlSchemaParserCtxtPtr ctxt,
  7646. xmlSchemaIDCPtr idc,
  7647. xmlNodePtr node,
  7648. int isField)
  7649. {
  7650. xmlSchemaIDCSelectPtr item;
  7651. xmlNodePtr child = NULL;
  7652. xmlAttrPtr attr;
  7653. /*
  7654. * Check for illegal attributes.
  7655. */
  7656. attr = node->properties;
  7657. while (attr != NULL) {
  7658. if (attr->ns == NULL) {
  7659. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7660. (!xmlStrEqual(attr->name, BAD_CAST "xpath"))) {
  7661. xmlSchemaPIllegalAttrErr(ctxt,
  7662. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7663. }
  7664. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7665. xmlSchemaPIllegalAttrErr(ctxt,
  7666. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7667. }
  7668. attr = attr->next;
  7669. }
  7670. /*
  7671. * Create the item.
  7672. */
  7673. item = (xmlSchemaIDCSelectPtr) xmlMalloc(sizeof(xmlSchemaIDCSelect));
  7674. if (item == NULL) {
  7675. xmlSchemaPErrMemory(ctxt,
  7676. "allocating a 'selector' of an identity-constraint definition",
  7677. NULL);
  7678. return (NULL);
  7679. }
  7680. memset(item, 0, sizeof(xmlSchemaIDCSelect));
  7681. /*
  7682. * Attribute "xpath" (mandatory).
  7683. */
  7684. attr = xmlSchemaGetPropNode(node, "xpath");
  7685. if (attr == NULL) {
  7686. xmlSchemaPMissingAttrErr(ctxt,
  7687. XML_SCHEMAP_S4S_ATTR_MISSING,
  7688. NULL, node,
  7689. "name", NULL);
  7690. } else {
  7691. item->xpath = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  7692. /*
  7693. * URGENT TODO: "field"s have an other syntax than "selector"s.
  7694. */
  7695. if (xmlSchemaCheckCSelectorXPath(ctxt, idc, item, attr,
  7696. isField) == -1) {
  7697. xmlSchemaPErr(ctxt,
  7698. (xmlNodePtr) attr,
  7699. XML_SCHEMAP_INTERNAL,
  7700. "Internal error: xmlSchemaParseIDCSelectorAndField, "
  7701. "validating the XPath expression of a IDC selector.\n",
  7702. NULL, NULL);
  7703. }
  7704. }
  7705. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7706. /*
  7707. * And now for the children...
  7708. */
  7709. child = node->children;
  7710. if (IS_SCHEMA(child, "annotation")) {
  7711. /*
  7712. * Add the annotation to the parent IDC.
  7713. */
  7714. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) idc,
  7715. xmlSchemaParseAnnotation(ctxt, child, 1));
  7716. child = child->next;
  7717. }
  7718. if (child != NULL) {
  7719. xmlSchemaPContentErr(ctxt,
  7720. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7721. NULL, node, child,
  7722. NULL, "(annotation?)");
  7723. }
  7724. return (item);
  7725. }
  7726. /**
  7727. * xmlSchemaParseIDC:
  7728. * @ctxt: a schema validation context
  7729. * @schema: the schema being built
  7730. * @node: a subtree containing XML Schema informations
  7731. *
  7732. * Parses a XML Schema identity-constraint definition.
  7733. *
  7734. * Returns the parsed identity-constraint definition.
  7735. */
  7736. static xmlSchemaIDCPtr
  7737. xmlSchemaParseIDC(xmlSchemaParserCtxtPtr ctxt,
  7738. xmlSchemaPtr schema,
  7739. xmlNodePtr node,
  7740. xmlSchemaTypeType idcCategory,
  7741. const xmlChar *targetNamespace)
  7742. {
  7743. xmlSchemaIDCPtr item = NULL;
  7744. xmlNodePtr child = NULL;
  7745. xmlAttrPtr attr;
  7746. const xmlChar *name = NULL;
  7747. xmlSchemaIDCSelectPtr field = NULL, lastField = NULL;
  7748. /*
  7749. * Check for illegal attributes.
  7750. */
  7751. attr = node->properties;
  7752. while (attr != NULL) {
  7753. if (attr->ns == NULL) {
  7754. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  7755. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  7756. ((idcCategory != XML_SCHEMA_TYPE_IDC_KEYREF) ||
  7757. (!xmlStrEqual(attr->name, BAD_CAST "refer")))) {
  7758. xmlSchemaPIllegalAttrErr(ctxt,
  7759. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7760. }
  7761. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7762. xmlSchemaPIllegalAttrErr(ctxt,
  7763. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7764. }
  7765. attr = attr->next;
  7766. }
  7767. /*
  7768. * Attribute "name" (mandatory).
  7769. */
  7770. attr = xmlSchemaGetPropNode(node, "name");
  7771. if (attr == NULL) {
  7772. xmlSchemaPMissingAttrErr(ctxt,
  7773. XML_SCHEMAP_S4S_ATTR_MISSING,
  7774. NULL, node,
  7775. "name", NULL);
  7776. return (NULL);
  7777. } else if (xmlSchemaPValAttrNode(ctxt,
  7778. NULL, attr,
  7779. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  7780. return (NULL);
  7781. }
  7782. /* Create the component. */
  7783. item = xmlSchemaAddIDC(ctxt, schema, name, targetNamespace,
  7784. idcCategory, node);
  7785. if (item == NULL)
  7786. return(NULL);
  7787. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7788. if (idcCategory == XML_SCHEMA_TYPE_IDC_KEYREF) {
  7789. /*
  7790. * Attribute "refer" (mandatory).
  7791. */
  7792. attr = xmlSchemaGetPropNode(node, "refer");
  7793. if (attr == NULL) {
  7794. xmlSchemaPMissingAttrErr(ctxt,
  7795. XML_SCHEMAP_S4S_ATTR_MISSING,
  7796. NULL, node,
  7797. "refer", NULL);
  7798. } else {
  7799. /*
  7800. * Create a reference item.
  7801. */
  7802. item->ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_IDC_KEY,
  7803. NULL, NULL);
  7804. if (item->ref == NULL)
  7805. return (NULL);
  7806. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7807. NULL, attr,
  7808. &(item->ref->targetNamespace),
  7809. &(item->ref->name));
  7810. xmlSchemaCheckReference(ctxt, schema, node, attr,
  7811. item->ref->targetNamespace);
  7812. }
  7813. }
  7814. /*
  7815. * And now for the children...
  7816. */
  7817. child = node->children;
  7818. if (IS_SCHEMA(child, "annotation")) {
  7819. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7820. child = child->next;
  7821. }
  7822. if (child == NULL) {
  7823. xmlSchemaPContentErr(ctxt,
  7824. XML_SCHEMAP_S4S_ELEM_MISSING,
  7825. NULL, node, child,
  7826. "A child element is missing",
  7827. "(annotation?, (selector, field+))");
  7828. }
  7829. /*
  7830. * Child element <selector>.
  7831. */
  7832. if (IS_SCHEMA(child, "selector")) {
  7833. item->selector = xmlSchemaParseIDCSelectorAndField(ctxt,
  7834. item, child, 0);
  7835. child = child->next;
  7836. /*
  7837. * Child elements <field>.
  7838. */
  7839. if (IS_SCHEMA(child, "field")) {
  7840. do {
  7841. field = xmlSchemaParseIDCSelectorAndField(ctxt,
  7842. item, child, 1);
  7843. if (field != NULL) {
  7844. field->index = item->nbFields;
  7845. item->nbFields++;
  7846. if (lastField != NULL)
  7847. lastField->next = field;
  7848. else
  7849. item->fields = field;
  7850. lastField = field;
  7851. }
  7852. child = child->next;
  7853. } while (IS_SCHEMA(child, "field"));
  7854. } else {
  7855. xmlSchemaPContentErr(ctxt,
  7856. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7857. NULL, node, child,
  7858. NULL, "(annotation?, (selector, field+))");
  7859. }
  7860. }
  7861. if (child != NULL) {
  7862. xmlSchemaPContentErr(ctxt,
  7863. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7864. NULL, node, child,
  7865. NULL, "(annotation?, (selector, field+))");
  7866. }
  7867. return (item);
  7868. }
  7869. /**
  7870. * xmlSchemaParseElement:
  7871. * @ctxt: a schema validation context
  7872. * @schema: the schema being built
  7873. * @node: a subtree containing XML Schema informations
  7874. * @topLevel: indicates if this is global declaration
  7875. *
  7876. * Parses a XML schema element declaration.
  7877. * *WARNING* this interface is highly subject to change
  7878. *
  7879. * Returns the element declaration or a particle; NULL in case
  7880. * of an error or if the particle has minOccurs==maxOccurs==0.
  7881. */
  7882. static xmlSchemaBasicItemPtr
  7883. xmlSchemaParseElement(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  7884. xmlNodePtr node, int *isElemRef, int topLevel)
  7885. {
  7886. xmlSchemaElementPtr decl = NULL;
  7887. xmlSchemaParticlePtr particle = NULL;
  7888. xmlSchemaAnnotPtr annot = NULL;
  7889. xmlNodePtr child = NULL;
  7890. xmlAttrPtr attr, nameAttr;
  7891. int min, max, isRef = 0;
  7892. xmlChar *des = NULL;
  7893. /* 3.3.3 Constraints on XML Representations of Element Declarations */
  7894. /* TODO: Complete implementation of 3.3.6 */
  7895. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  7896. return (NULL);
  7897. if (isElemRef != NULL)
  7898. *isElemRef = 0;
  7899. /*
  7900. * If we get a "ref" attribute on a local <element> we will assume it's
  7901. * a reference - even if there's a "name" attribute; this seems to be more
  7902. * robust.
  7903. */
  7904. nameAttr = xmlSchemaGetPropNode(node, "name");
  7905. attr = xmlSchemaGetPropNode(node, "ref");
  7906. if ((topLevel) || (attr == NULL)) {
  7907. if (nameAttr == NULL) {
  7908. xmlSchemaPMissingAttrErr(ctxt,
  7909. XML_SCHEMAP_S4S_ATTR_MISSING,
  7910. NULL, node, "name", NULL);
  7911. return (NULL);
  7912. }
  7913. } else
  7914. isRef = 1;
  7915. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  7916. child = node->children;
  7917. if (IS_SCHEMA(child, "annotation")) {
  7918. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  7919. child = child->next;
  7920. }
  7921. /*
  7922. * Skip particle part if a global declaration.
  7923. */
  7924. if (topLevel)
  7925. goto declaration_part;
  7926. /*
  7927. * The particle part ==================================================
  7928. */
  7929. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  7930. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1, "(xs:nonNegativeInteger | unbounded)");
  7931. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  7932. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  7933. if (particle == NULL)
  7934. goto return_null;
  7935. /* ret->flags |= XML_SCHEMAS_ELEM_REF; */
  7936. if (isRef) {
  7937. const xmlChar *refNs = NULL, *ref = NULL;
  7938. xmlSchemaQNameRefPtr refer = NULL;
  7939. /*
  7940. * The reference part =============================================
  7941. */
  7942. if (isElemRef != NULL)
  7943. *isElemRef = 1;
  7944. xmlSchemaPValAttrNodeQName(ctxt, schema,
  7945. NULL, attr, &refNs, &ref);
  7946. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  7947. /*
  7948. * SPEC (3.3.3 : 2.1) "One of ref or name must be present, but not both"
  7949. */
  7950. if (nameAttr != NULL) {
  7951. xmlSchemaPMutualExclAttrErr(ctxt,
  7952. XML_SCHEMAP_SRC_ELEMENT_2_1, NULL, nameAttr, "ref", "name");
  7953. }
  7954. /*
  7955. * Check for illegal attributes.
  7956. */
  7957. attr = node->properties;
  7958. while (attr != NULL) {
  7959. if (attr->ns == NULL) {
  7960. if (xmlStrEqual(attr->name, BAD_CAST "ref") ||
  7961. xmlStrEqual(attr->name, BAD_CAST "name") ||
  7962. xmlStrEqual(attr->name, BAD_CAST "id") ||
  7963. xmlStrEqual(attr->name, BAD_CAST "maxOccurs") ||
  7964. xmlStrEqual(attr->name, BAD_CAST "minOccurs"))
  7965. {
  7966. attr = attr->next;
  7967. continue;
  7968. } else {
  7969. /* SPEC (3.3.3 : 2.2) */
  7970. xmlSchemaPCustomAttrErr(ctxt,
  7971. XML_SCHEMAP_SRC_ELEMENT_2_2,
  7972. NULL, NULL, attr,
  7973. "Only the attributes 'minOccurs', 'maxOccurs' and "
  7974. "'id' are allowed in addition to 'ref'");
  7975. break;
  7976. }
  7977. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  7978. xmlSchemaPIllegalAttrErr(ctxt,
  7979. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  7980. }
  7981. attr = attr->next;
  7982. }
  7983. /*
  7984. * No children except <annotation> expected.
  7985. */
  7986. if (child != NULL) {
  7987. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  7988. NULL, node, child, NULL, "(annotation?)");
  7989. }
  7990. if ((min == 0) && (max == 0))
  7991. goto return_null;
  7992. /*
  7993. * Create the reference item and attach it to the particle.
  7994. */
  7995. refer = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_ELEMENT,
  7996. ref, refNs);
  7997. if (refer == NULL)
  7998. goto return_null;
  7999. particle->children = (xmlSchemaTreeItemPtr) refer;
  8000. particle->annot = annot;
  8001. /*
  8002. * Add the particle to pending components, since the reference
  8003. * need to be resolved.
  8004. */
  8005. WXS_ADD_PENDING(ctxt, particle);
  8006. return ((xmlSchemaBasicItemPtr) particle);
  8007. }
  8008. /*
  8009. * The declaration part ===============================================
  8010. */
  8011. declaration_part:
  8012. {
  8013. const xmlChar *ns = NULL, *fixed, *name, *attrValue;
  8014. xmlSchemaIDCPtr curIDC = NULL, lastIDC = NULL;
  8015. if (xmlSchemaPValAttrNode(ctxt, NULL, nameAttr,
  8016. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0)
  8017. goto return_null;
  8018. /*
  8019. * Evaluate the target namespace.
  8020. */
  8021. if (topLevel) {
  8022. ns = ctxt->targetNamespace;
  8023. } else {
  8024. attr = xmlSchemaGetPropNode(node, "form");
  8025. if (attr != NULL) {
  8026. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8027. if (xmlStrEqual(attrValue, BAD_CAST "qualified")) {
  8028. ns = ctxt->targetNamespace;
  8029. } else if (!xmlStrEqual(attrValue, BAD_CAST "unqualified")) {
  8030. xmlSchemaPSimpleTypeErr(ctxt,
  8031. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8032. NULL, (xmlNodePtr) attr,
  8033. NULL, "(qualified | unqualified)",
  8034. attrValue, NULL, NULL, NULL);
  8035. }
  8036. } else if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  8037. ns = ctxt->targetNamespace;
  8038. }
  8039. decl = xmlSchemaAddElement(ctxt, name, ns, node, topLevel);
  8040. if (decl == NULL) {
  8041. goto return_null;
  8042. }
  8043. /*
  8044. * Check for illegal attributes.
  8045. */
  8046. attr = node->properties;
  8047. while (attr != NULL) {
  8048. if (attr->ns == NULL) {
  8049. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8050. (!xmlStrEqual(attr->name, BAD_CAST "type")) &&
  8051. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8052. (!xmlStrEqual(attr->name, BAD_CAST "default")) &&
  8053. (!xmlStrEqual(attr->name, BAD_CAST "fixed")) &&
  8054. (!xmlStrEqual(attr->name, BAD_CAST "block")) &&
  8055. (!xmlStrEqual(attr->name, BAD_CAST "nillable")))
  8056. {
  8057. if (topLevel == 0) {
  8058. if ((!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  8059. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8060. (!xmlStrEqual(attr->name, BAD_CAST "form")))
  8061. {
  8062. xmlSchemaPIllegalAttrErr(ctxt,
  8063. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8064. }
  8065. } else if ((!xmlStrEqual(attr->name, BAD_CAST "final")) &&
  8066. (!xmlStrEqual(attr->name, BAD_CAST "abstract")) &&
  8067. (!xmlStrEqual(attr->name, BAD_CAST "substitutionGroup"))) {
  8068. xmlSchemaPIllegalAttrErr(ctxt,
  8069. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8070. }
  8071. }
  8072. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8073. xmlSchemaPIllegalAttrErr(ctxt,
  8074. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8075. }
  8076. attr = attr->next;
  8077. }
  8078. /*
  8079. * Extract/validate attributes.
  8080. */
  8081. if (topLevel) {
  8082. /*
  8083. * Process top attributes of global element declarations here.
  8084. */
  8085. decl->flags |= XML_SCHEMAS_ELEM_GLOBAL;
  8086. decl->flags |= XML_SCHEMAS_ELEM_TOPLEVEL;
  8087. xmlSchemaPValAttrQName(ctxt, schema,
  8088. NULL, node, "substitutionGroup",
  8089. &(decl->substGroupNs), &(decl->substGroup));
  8090. if (xmlGetBooleanProp(ctxt, node, "abstract", 0))
  8091. decl->flags |= XML_SCHEMAS_ELEM_ABSTRACT;
  8092. /*
  8093. * Attribute "final".
  8094. */
  8095. attr = xmlSchemaGetPropNode(node, "final");
  8096. if (attr == NULL) {
  8097. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8098. decl->flags |= XML_SCHEMAS_ELEM_FINAL_EXTENSION;
  8099. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8100. decl->flags |= XML_SCHEMAS_ELEM_FINAL_RESTRICTION;
  8101. } else {
  8102. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8103. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8104. -1,
  8105. XML_SCHEMAS_ELEM_FINAL_EXTENSION,
  8106. XML_SCHEMAS_ELEM_FINAL_RESTRICTION, -1, -1, -1) != 0) {
  8107. xmlSchemaPSimpleTypeErr(ctxt,
  8108. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8109. NULL, (xmlNodePtr) attr,
  8110. NULL, "(#all | List of (extension | restriction))",
  8111. attrValue, NULL, NULL, NULL);
  8112. }
  8113. }
  8114. }
  8115. /*
  8116. * Attribute "block".
  8117. */
  8118. attr = xmlSchemaGetPropNode(node, "block");
  8119. if (attr == NULL) {
  8120. /*
  8121. * Apply default "block" values.
  8122. */
  8123. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  8124. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_RESTRICTION;
  8125. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  8126. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_EXTENSION;
  8127. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  8128. decl->flags |= XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION;
  8129. } else {
  8130. attrValue = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8131. if (xmlSchemaPValAttrBlockFinal(attrValue, &(decl->flags),
  8132. -1,
  8133. XML_SCHEMAS_ELEM_BLOCK_EXTENSION,
  8134. XML_SCHEMAS_ELEM_BLOCK_RESTRICTION,
  8135. XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION, -1, -1) != 0) {
  8136. xmlSchemaPSimpleTypeErr(ctxt,
  8137. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8138. NULL, (xmlNodePtr) attr,
  8139. NULL, "(#all | List of (extension | "
  8140. "restriction | substitution))", attrValue,
  8141. NULL, NULL, NULL);
  8142. }
  8143. }
  8144. if (xmlGetBooleanProp(ctxt, node, "nillable", 0))
  8145. decl->flags |= XML_SCHEMAS_ELEM_NILLABLE;
  8146. attr = xmlSchemaGetPropNode(node, "type");
  8147. if (attr != NULL) {
  8148. xmlSchemaPValAttrNodeQName(ctxt, schema,
  8149. NULL, attr,
  8150. &(decl->namedTypeNs), &(decl->namedType));
  8151. xmlSchemaCheckReference(ctxt, schema, node,
  8152. attr, decl->namedTypeNs);
  8153. }
  8154. decl->value = xmlSchemaGetProp(ctxt, node, "default");
  8155. attr = xmlSchemaGetPropNode(node, "fixed");
  8156. if (attr != NULL) {
  8157. fixed = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8158. if (decl->value != NULL) {
  8159. /*
  8160. * 3.3.3 : 1
  8161. * default and fixed must not both be present.
  8162. */
  8163. xmlSchemaPMutualExclAttrErr(ctxt,
  8164. XML_SCHEMAP_SRC_ELEMENT_1,
  8165. NULL, attr, "default", "fixed");
  8166. } else {
  8167. decl->flags |= XML_SCHEMAS_ELEM_FIXED;
  8168. decl->value = fixed;
  8169. }
  8170. }
  8171. /*
  8172. * And now for the children...
  8173. */
  8174. if (IS_SCHEMA(child, "complexType")) {
  8175. /*
  8176. * 3.3.3 : 3
  8177. * "type" and either <simpleType> or <complexType> are mutually
  8178. * exclusive
  8179. */
  8180. if (decl->namedType != NULL) {
  8181. xmlSchemaPContentErr(ctxt,
  8182. XML_SCHEMAP_SRC_ELEMENT_3,
  8183. NULL, node, child,
  8184. "The attribute 'type' and the <complexType> child are "
  8185. "mutually exclusive", NULL);
  8186. } else
  8187. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseComplexType(ctxt, schema, child, 0);
  8188. child = child->next;
  8189. } else if (IS_SCHEMA(child, "simpleType")) {
  8190. /*
  8191. * 3.3.3 : 3
  8192. * "type" and either <simpleType> or <complexType> are
  8193. * mutually exclusive
  8194. */
  8195. if (decl->namedType != NULL) {
  8196. xmlSchemaPContentErr(ctxt,
  8197. XML_SCHEMAP_SRC_ELEMENT_3,
  8198. NULL, node, child,
  8199. "The attribute 'type' and the <simpleType> child are "
  8200. "mutually exclusive", NULL);
  8201. } else
  8202. WXS_ELEM_TYPEDEF(decl) = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8203. child = child->next;
  8204. }
  8205. while ((IS_SCHEMA(child, "unique")) ||
  8206. (IS_SCHEMA(child, "key")) || (IS_SCHEMA(child, "keyref"))) {
  8207. if (IS_SCHEMA(child, "unique")) {
  8208. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8209. XML_SCHEMA_TYPE_IDC_UNIQUE, decl->targetNamespace);
  8210. } else if (IS_SCHEMA(child, "key")) {
  8211. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8212. XML_SCHEMA_TYPE_IDC_KEY, decl->targetNamespace);
  8213. } else if (IS_SCHEMA(child, "keyref")) {
  8214. curIDC = xmlSchemaParseIDC(ctxt, schema, child,
  8215. XML_SCHEMA_TYPE_IDC_KEYREF, decl->targetNamespace);
  8216. }
  8217. if (lastIDC != NULL)
  8218. lastIDC->next = curIDC;
  8219. else
  8220. decl->idcs = (void *) curIDC;
  8221. lastIDC = curIDC;
  8222. child = child->next;
  8223. }
  8224. if (child != NULL) {
  8225. xmlSchemaPContentErr(ctxt,
  8226. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8227. NULL, node, child,
  8228. NULL, "(annotation?, ((simpleType | complexType)?, "
  8229. "(unique | key | keyref)*))");
  8230. }
  8231. decl->annot = annot;
  8232. }
  8233. /*
  8234. * NOTE: Element Declaration Representation OK 4. will be checked at a
  8235. * different layer.
  8236. */
  8237. FREE_AND_NULL(des)
  8238. if (topLevel)
  8239. return ((xmlSchemaBasicItemPtr) decl);
  8240. else {
  8241. particle->children = (xmlSchemaTreeItemPtr) decl;
  8242. return ((xmlSchemaBasicItemPtr) particle);
  8243. }
  8244. return_null:
  8245. FREE_AND_NULL(des);
  8246. if (annot != NULL) {
  8247. if (particle != NULL)
  8248. particle->annot = NULL;
  8249. if (decl != NULL)
  8250. decl->annot = NULL;
  8251. xmlSchemaFreeAnnot(annot);
  8252. }
  8253. return (NULL);
  8254. }
  8255. /**
  8256. * xmlSchemaParseUnion:
  8257. * @ctxt: a schema validation context
  8258. * @schema: the schema being built
  8259. * @node: a subtree containing XML Schema informations
  8260. *
  8261. * parse a XML schema Union definition
  8262. * *WARNING* this interface is highly subject to change
  8263. *
  8264. * Returns -1 in case of internal error, 0 in case of success and a positive
  8265. * error code otherwise.
  8266. */
  8267. static int
  8268. xmlSchemaParseUnion(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8269. xmlNodePtr node)
  8270. {
  8271. xmlSchemaTypePtr type;
  8272. xmlNodePtr child = NULL;
  8273. xmlAttrPtr attr;
  8274. const xmlChar *cur = NULL;
  8275. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8276. return (-1);
  8277. /* Not a component, don't create it. */
  8278. type = ctxt->ctxtType;
  8279. /*
  8280. * Mark the simple type as being of variety "union".
  8281. */
  8282. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  8283. /*
  8284. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8285. * then the `simple ur-type definition`."
  8286. */
  8287. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8288. /*
  8289. * Check for illegal attributes.
  8290. */
  8291. attr = node->properties;
  8292. while (attr != NULL) {
  8293. if (attr->ns == NULL) {
  8294. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8295. (!xmlStrEqual(attr->name, BAD_CAST "memberTypes"))) {
  8296. xmlSchemaPIllegalAttrErr(ctxt,
  8297. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8298. }
  8299. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8300. xmlSchemaPIllegalAttrErr(ctxt,
  8301. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8302. }
  8303. attr = attr->next;
  8304. }
  8305. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8306. /*
  8307. * Attribute "memberTypes". This is a list of QNames.
  8308. * TODO: Check the value to contain anything.
  8309. */
  8310. attr = xmlSchemaGetPropNode(node, "memberTypes");
  8311. if (attr != NULL) {
  8312. const xmlChar *end;
  8313. xmlChar *tmp;
  8314. const xmlChar *localName, *nsName;
  8315. xmlSchemaTypeLinkPtr link, lastLink = NULL;
  8316. xmlSchemaQNameRefPtr ref;
  8317. cur = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  8318. type->base = cur;
  8319. do {
  8320. while (IS_BLANK_CH(*cur))
  8321. cur++;
  8322. end = cur;
  8323. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  8324. end++;
  8325. if (end == cur)
  8326. break;
  8327. tmp = xmlStrndup(cur, end - cur);
  8328. if (xmlSchemaPValAttrNodeQNameValue(ctxt, schema,
  8329. NULL, attr, BAD_CAST tmp, &nsName, &localName) == 0) {
  8330. /*
  8331. * Create the member type link.
  8332. */
  8333. link = (xmlSchemaTypeLinkPtr)
  8334. xmlMalloc(sizeof(xmlSchemaTypeLink));
  8335. if (link == NULL) {
  8336. xmlSchemaPErrMemory(ctxt, "xmlSchemaParseUnion, "
  8337. "allocating a type link", NULL);
  8338. return (-1);
  8339. }
  8340. link->type = NULL;
  8341. link->next = NULL;
  8342. if (lastLink == NULL)
  8343. type->memberTypes = link;
  8344. else
  8345. lastLink->next = link;
  8346. lastLink = link;
  8347. /*
  8348. * Create a reference item.
  8349. */
  8350. ref = xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_SIMPLE,
  8351. localName, nsName);
  8352. if (ref == NULL) {
  8353. FREE_AND_NULL(tmp)
  8354. return (-1);
  8355. }
  8356. /*
  8357. * Assign the reference to the link, it will be resolved
  8358. * later during fixup of the union simple type.
  8359. */
  8360. link->type = (xmlSchemaTypePtr) ref;
  8361. }
  8362. FREE_AND_NULL(tmp)
  8363. cur = end;
  8364. } while (*cur != 0);
  8365. }
  8366. /*
  8367. * And now for the children...
  8368. */
  8369. child = node->children;
  8370. if (IS_SCHEMA(child, "annotation")) {
  8371. /*
  8372. * Add the annotation to the simple type ancestor.
  8373. */
  8374. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8375. xmlSchemaParseAnnotation(ctxt, child, 1));
  8376. child = child->next;
  8377. }
  8378. if (IS_SCHEMA(child, "simpleType")) {
  8379. xmlSchemaTypePtr subtype, last = NULL;
  8380. /*
  8381. * Anchor the member types in the "subtypes" field of the
  8382. * simple type.
  8383. */
  8384. while (IS_SCHEMA(child, "simpleType")) {
  8385. subtype = (xmlSchemaTypePtr)
  8386. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8387. if (subtype != NULL) {
  8388. if (last == NULL) {
  8389. type->subtypes = subtype;
  8390. last = subtype;
  8391. } else {
  8392. last->next = subtype;
  8393. last = subtype;
  8394. }
  8395. last->next = NULL;
  8396. }
  8397. child = child->next;
  8398. }
  8399. }
  8400. if (child != NULL) {
  8401. xmlSchemaPContentErr(ctxt,
  8402. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8403. NULL, node, child, NULL, "(annotation?, simpleType*)");
  8404. }
  8405. if ((attr == NULL) && (type->subtypes == NULL)) {
  8406. /*
  8407. * src-union-memberTypes-or-simpleTypes
  8408. * Either the memberTypes [attribute] of the <union> element must
  8409. * be non-empty or there must be at least one simpleType [child].
  8410. */
  8411. xmlSchemaPCustomErr(ctxt,
  8412. XML_SCHEMAP_SRC_UNION_MEMBERTYPES_OR_SIMPLETYPES,
  8413. NULL, node,
  8414. "Either the attribute 'memberTypes' or "
  8415. "at least one <simpleType> child must be present", NULL);
  8416. }
  8417. return (0);
  8418. }
  8419. /**
  8420. * xmlSchemaParseList:
  8421. * @ctxt: a schema validation context
  8422. * @schema: the schema being built
  8423. * @node: a subtree containing XML Schema informations
  8424. *
  8425. * parse a XML schema List definition
  8426. * *WARNING* this interface is highly subject to change
  8427. *
  8428. * Returns -1 in case of error, 0 if the declaration is improper and
  8429. * 1 in case of success.
  8430. */
  8431. static xmlSchemaTypePtr
  8432. xmlSchemaParseList(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8433. xmlNodePtr node)
  8434. {
  8435. xmlSchemaTypePtr type;
  8436. xmlNodePtr child = NULL;
  8437. xmlAttrPtr attr;
  8438. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8439. return (NULL);
  8440. /* Not a component, don't create it. */
  8441. type = ctxt->ctxtType;
  8442. /*
  8443. * Mark the type as being of variety "list".
  8444. */
  8445. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  8446. /*
  8447. * SPEC (Base type) (2) "If the <list> or <union> alternative is chosen,
  8448. * then the `simple ur-type definition`."
  8449. */
  8450. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  8451. /*
  8452. * Check for illegal attributes.
  8453. */
  8454. attr = node->properties;
  8455. while (attr != NULL) {
  8456. if (attr->ns == NULL) {
  8457. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8458. (!xmlStrEqual(attr->name, BAD_CAST "itemType"))) {
  8459. xmlSchemaPIllegalAttrErr(ctxt,
  8460. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8461. }
  8462. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8463. xmlSchemaPIllegalAttrErr(ctxt,
  8464. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8465. }
  8466. attr = attr->next;
  8467. }
  8468. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8469. /*
  8470. * Attribute "itemType". NOTE that we will use the "ref" and "refNs"
  8471. * fields for holding the reference to the itemType.
  8472. *
  8473. * REVAMP TODO: Use the "base" and "baseNs" fields, since we will remove
  8474. * the "ref" fields.
  8475. */
  8476. xmlSchemaPValAttrQName(ctxt, schema, NULL,
  8477. node, "itemType", &(type->baseNs), &(type->base));
  8478. /*
  8479. * And now for the children...
  8480. */
  8481. child = node->children;
  8482. if (IS_SCHEMA(child, "annotation")) {
  8483. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  8484. xmlSchemaParseAnnotation(ctxt, child, 1));
  8485. child = child->next;
  8486. }
  8487. if (IS_SCHEMA(child, "simpleType")) {
  8488. /*
  8489. * src-list-itemType-or-simpleType
  8490. * Either the itemType [attribute] or the <simpleType> [child] of
  8491. * the <list> element must be present, but not both.
  8492. */
  8493. if (type->base != NULL) {
  8494. xmlSchemaPCustomErr(ctxt,
  8495. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8496. NULL, node,
  8497. "The attribute 'itemType' and the <simpleType> child "
  8498. "are mutually exclusive", NULL);
  8499. } else {
  8500. type->subtypes = xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  8501. }
  8502. child = child->next;
  8503. } else if (type->base == NULL) {
  8504. xmlSchemaPCustomErr(ctxt,
  8505. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8506. NULL, node,
  8507. "Either the attribute 'itemType' or the <simpleType> child "
  8508. "must be present", NULL);
  8509. }
  8510. if (child != NULL) {
  8511. xmlSchemaPContentErr(ctxt,
  8512. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8513. NULL, node, child, NULL, "(annotation?, simpleType?)");
  8514. }
  8515. if ((type->base == NULL) &&
  8516. (type->subtypes == NULL) &&
  8517. (xmlSchemaGetPropNode(node, "itemType") == NULL)) {
  8518. xmlSchemaPCustomErr(ctxt,
  8519. XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  8520. NULL, node,
  8521. "Either the attribute 'itemType' or the <simpleType> child "
  8522. "must be present", NULL);
  8523. }
  8524. return (NULL);
  8525. }
  8526. /**
  8527. * xmlSchemaParseSimpleType:
  8528. * @ctxt: a schema validation context
  8529. * @schema: the schema being built
  8530. * @node: a subtree containing XML Schema informations
  8531. *
  8532. * parse a XML schema Simple Type definition
  8533. * *WARNING* this interface is highly subject to change
  8534. *
  8535. * Returns -1 in case of error, 0 if the declaration is improper and
  8536. * 1 in case of success.
  8537. */
  8538. static xmlSchemaTypePtr
  8539. xmlSchemaParseSimpleType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  8540. xmlNodePtr node, int topLevel)
  8541. {
  8542. xmlSchemaTypePtr type, oldCtxtType;
  8543. xmlNodePtr child = NULL;
  8544. const xmlChar *attrValue = NULL;
  8545. xmlAttrPtr attr;
  8546. int hasRestriction = 0;
  8547. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8548. return (NULL);
  8549. if (topLevel) {
  8550. attr = xmlSchemaGetPropNode(node, "name");
  8551. if (attr == NULL) {
  8552. xmlSchemaPMissingAttrErr(ctxt,
  8553. XML_SCHEMAP_S4S_ATTR_MISSING,
  8554. NULL, node,
  8555. "name", NULL);
  8556. return (NULL);
  8557. } else {
  8558. if (xmlSchemaPValAttrNode(ctxt,
  8559. NULL, attr,
  8560. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &attrValue) != 0)
  8561. return (NULL);
  8562. /*
  8563. * Skip built-in types.
  8564. */
  8565. if (ctxt->isS4S) {
  8566. xmlSchemaTypePtr biType;
  8567. if (ctxt->isRedefine) {
  8568. /*
  8569. * REDEFINE: Disallow redefinition of built-in-types.
  8570. * TODO: It seems that the spec does not say anything
  8571. * about this case.
  8572. */
  8573. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8574. NULL, node,
  8575. "Redefinition of built-in simple types is not "
  8576. "supported", NULL);
  8577. return(NULL);
  8578. }
  8579. biType = xmlSchemaGetPredefinedType(attrValue, xmlSchemaNs);
  8580. if (biType != NULL)
  8581. return (biType);
  8582. }
  8583. }
  8584. }
  8585. /*
  8586. * TargetNamespace:
  8587. * SPEC "The `actual value` of the targetNamespace [attribute]
  8588. * of the <schema> ancestor element information item if present,
  8589. * otherwise `absent`.
  8590. */
  8591. if (topLevel == 0) {
  8592. #ifdef ENABLE_NAMED_LOCALS
  8593. char buf[40];
  8594. #endif
  8595. /*
  8596. * Parse as local simple type definition.
  8597. */
  8598. #ifdef ENABLE_NAMED_LOCALS
  8599. snprintf(buf, 39, "#ST%d", ctxt->counter++ + 1);
  8600. type = xmlSchemaAddType(ctxt, schema,
  8601. XML_SCHEMA_TYPE_SIMPLE,
  8602. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  8603. ctxt->targetNamespace, node, 0);
  8604. #else
  8605. type = xmlSchemaAddType(ctxt, schema,
  8606. XML_SCHEMA_TYPE_SIMPLE,
  8607. NULL, ctxt->targetNamespace, node, 0);
  8608. #endif
  8609. if (type == NULL)
  8610. return (NULL);
  8611. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8612. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8613. /*
  8614. * Check for illegal attributes.
  8615. */
  8616. attr = node->properties;
  8617. while (attr != NULL) {
  8618. if (attr->ns == NULL) {
  8619. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  8620. xmlSchemaPIllegalAttrErr(ctxt,
  8621. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8622. }
  8623. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8624. xmlSchemaPIllegalAttrErr(ctxt,
  8625. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8626. }
  8627. attr = attr->next;
  8628. }
  8629. } else {
  8630. /*
  8631. * Parse as global simple type definition.
  8632. *
  8633. * Note that attrValue is the value of the attribute "name" here.
  8634. */
  8635. type = xmlSchemaAddType(ctxt, schema, XML_SCHEMA_TYPE_SIMPLE,
  8636. attrValue, ctxt->targetNamespace, node, 1);
  8637. if (type == NULL)
  8638. return (NULL);
  8639. type->type = XML_SCHEMA_TYPE_SIMPLE;
  8640. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  8641. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  8642. /*
  8643. * Check for illegal attributes.
  8644. */
  8645. attr = node->properties;
  8646. while (attr != NULL) {
  8647. if (attr->ns == NULL) {
  8648. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8649. (!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8650. (!xmlStrEqual(attr->name, BAD_CAST "final"))) {
  8651. xmlSchemaPIllegalAttrErr(ctxt,
  8652. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8653. }
  8654. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8655. xmlSchemaPIllegalAttrErr(ctxt,
  8656. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8657. }
  8658. attr = attr->next;
  8659. }
  8660. /*
  8661. * Attribute "final".
  8662. */
  8663. attr = xmlSchemaGetPropNode(node, "final");
  8664. if (attr == NULL) {
  8665. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8666. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  8667. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8668. type->flags |= XML_SCHEMAS_TYPE_FINAL_LIST;
  8669. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8670. type->flags |= XML_SCHEMAS_TYPE_FINAL_UNION;
  8671. } else {
  8672. attrValue = xmlSchemaGetProp(ctxt, node, "final");
  8673. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  8674. -1, -1, XML_SCHEMAS_TYPE_FINAL_RESTRICTION, -1,
  8675. XML_SCHEMAS_TYPE_FINAL_LIST,
  8676. XML_SCHEMAS_TYPE_FINAL_UNION) != 0) {
  8677. xmlSchemaPSimpleTypeErr(ctxt,
  8678. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  8679. WXS_BASIC_CAST type, (xmlNodePtr) attr,
  8680. NULL, "(#all | List of (list | union | restriction)",
  8681. attrValue, NULL, NULL, NULL);
  8682. }
  8683. }
  8684. }
  8685. type->targetNamespace = ctxt->targetNamespace;
  8686. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8687. /*
  8688. * And now for the children...
  8689. */
  8690. oldCtxtType = ctxt->ctxtType;
  8691. ctxt->ctxtType = type;
  8692. child = node->children;
  8693. if (IS_SCHEMA(child, "annotation")) {
  8694. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8695. child = child->next;
  8696. }
  8697. if (child == NULL) {
  8698. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_MISSING,
  8699. NULL, node, child, NULL,
  8700. "(annotation?, (restriction | list | union))");
  8701. } else if (IS_SCHEMA(child, "restriction")) {
  8702. xmlSchemaParseRestriction(ctxt, schema, child,
  8703. XML_SCHEMA_TYPE_SIMPLE);
  8704. hasRestriction = 1;
  8705. child = child->next;
  8706. } else if (IS_SCHEMA(child, "list")) {
  8707. xmlSchemaParseList(ctxt, schema, child);
  8708. child = child->next;
  8709. } else if (IS_SCHEMA(child, "union")) {
  8710. xmlSchemaParseUnion(ctxt, schema, child);
  8711. child = child->next;
  8712. }
  8713. if (child != NULL) {
  8714. xmlSchemaPContentErr(ctxt, XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8715. NULL, node, child, NULL,
  8716. "(annotation?, (restriction | list | union))");
  8717. }
  8718. /*
  8719. * REDEFINE: SPEC src-redefine (5)
  8720. * "Within the [children], each <simpleType> must have a
  8721. * <restriction> among its [children] ... the `actual value` of whose
  8722. * base [attribute] must be the same as the `actual value` of its own
  8723. * name attribute plus target namespace;"
  8724. */
  8725. if (topLevel && ctxt->isRedefine && (! hasRestriction)) {
  8726. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  8727. NULL, node, "This is a redefinition, thus the "
  8728. "<simpleType> must have a <restriction> child", NULL);
  8729. }
  8730. ctxt->ctxtType = oldCtxtType;
  8731. return (type);
  8732. }
  8733. /**
  8734. * xmlSchemaParseModelGroupDefRef:
  8735. * @ctxt: the parser context
  8736. * @schema: the schema being built
  8737. * @node: the node
  8738. *
  8739. * Parses a reference to a model group definition.
  8740. *
  8741. * We will return a particle component with a qname-component or
  8742. * NULL in case of an error.
  8743. */
  8744. static xmlSchemaTreeItemPtr
  8745. xmlSchemaParseModelGroupDefRef(xmlSchemaParserCtxtPtr ctxt,
  8746. xmlSchemaPtr schema,
  8747. xmlNodePtr node)
  8748. {
  8749. xmlSchemaParticlePtr item;
  8750. xmlNodePtr child = NULL;
  8751. xmlAttrPtr attr;
  8752. const xmlChar *ref = NULL, *refNs = NULL;
  8753. int min, max;
  8754. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8755. return (NULL);
  8756. attr = xmlSchemaGetPropNode(node, "ref");
  8757. if (attr == NULL) {
  8758. xmlSchemaPMissingAttrErr(ctxt,
  8759. XML_SCHEMAP_S4S_ATTR_MISSING,
  8760. NULL, node, "ref", NULL);
  8761. return (NULL);
  8762. } else if (xmlSchemaPValAttrNodeQName(ctxt, schema, NULL,
  8763. attr, &refNs, &ref) != 0) {
  8764. return (NULL);
  8765. }
  8766. xmlSchemaCheckReference(ctxt, schema, node, attr, refNs);
  8767. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  8768. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  8769. "(xs:nonNegativeInteger | unbounded)");
  8770. /*
  8771. * Check for illegal attributes.
  8772. */
  8773. attr = node->properties;
  8774. while (attr != NULL) {
  8775. if (attr->ns == NULL) {
  8776. if ((!xmlStrEqual(attr->name, BAD_CAST "ref")) &&
  8777. (!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  8778. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs")) &&
  8779. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs"))) {
  8780. xmlSchemaPIllegalAttrErr(ctxt,
  8781. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8782. }
  8783. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8784. xmlSchemaPIllegalAttrErr(ctxt,
  8785. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8786. }
  8787. attr = attr->next;
  8788. }
  8789. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8790. item = xmlSchemaAddParticle(ctxt, node, min, max);
  8791. if (item == NULL)
  8792. return (NULL);
  8793. /*
  8794. * Create a qname-reference and set as the term; it will be substituted
  8795. * for the model group after the reference has been resolved.
  8796. */
  8797. item->children = (xmlSchemaTreeItemPtr)
  8798. xmlSchemaNewQNameRef(ctxt, XML_SCHEMA_TYPE_GROUP, ref, refNs);
  8799. xmlSchemaPCheckParticleCorrect_2(ctxt, item, node, min, max);
  8800. /*
  8801. * And now for the children...
  8802. */
  8803. child = node->children;
  8804. /* TODO: Is annotation even allowed for a model group reference? */
  8805. if (IS_SCHEMA(child, "annotation")) {
  8806. /*
  8807. * TODO: What to do exactly with the annotation?
  8808. */
  8809. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8810. child = child->next;
  8811. }
  8812. if (child != NULL) {
  8813. xmlSchemaPContentErr(ctxt,
  8814. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8815. NULL, node, child, NULL,
  8816. "(annotation?)");
  8817. }
  8818. /*
  8819. * Corresponds to no component at all if minOccurs==maxOccurs==0.
  8820. */
  8821. if ((min == 0) && (max == 0))
  8822. return (NULL);
  8823. return ((xmlSchemaTreeItemPtr) item);
  8824. }
  8825. /**
  8826. * xmlSchemaParseModelGroupDefinition:
  8827. * @ctxt: a schema validation context
  8828. * @schema: the schema being built
  8829. * @node: a subtree containing XML Schema informations
  8830. *
  8831. * Parses a XML schema model group definition.
  8832. *
  8833. * Note that the constraint src-redefine (6.2) can't be applied until
  8834. * references have been resolved. So we will do this at the
  8835. * component fixup level.
  8836. *
  8837. * *WARNING* this interface is highly subject to change
  8838. *
  8839. * Returns -1 in case of error, 0 if the declaration is improper and
  8840. * 1 in case of success.
  8841. */
  8842. static xmlSchemaModelGroupDefPtr
  8843. xmlSchemaParseModelGroupDefinition(xmlSchemaParserCtxtPtr ctxt,
  8844. xmlSchemaPtr schema,
  8845. xmlNodePtr node)
  8846. {
  8847. xmlSchemaModelGroupDefPtr item;
  8848. xmlNodePtr child = NULL;
  8849. xmlAttrPtr attr;
  8850. const xmlChar *name;
  8851. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  8852. return (NULL);
  8853. attr = xmlSchemaGetPropNode(node, "name");
  8854. if (attr == NULL) {
  8855. xmlSchemaPMissingAttrErr(ctxt,
  8856. XML_SCHEMAP_S4S_ATTR_MISSING,
  8857. NULL, node,
  8858. "name", NULL);
  8859. return (NULL);
  8860. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  8861. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  8862. return (NULL);
  8863. }
  8864. item = xmlSchemaAddModelGroupDefinition(ctxt, schema, name,
  8865. ctxt->targetNamespace, node);
  8866. if (item == NULL)
  8867. return (NULL);
  8868. /*
  8869. * Check for illegal attributes.
  8870. */
  8871. attr = node->properties;
  8872. while (attr != NULL) {
  8873. if (attr->ns == NULL) {
  8874. if ((!xmlStrEqual(attr->name, BAD_CAST "name")) &&
  8875. (!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  8876. xmlSchemaPIllegalAttrErr(ctxt,
  8877. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8878. }
  8879. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  8880. xmlSchemaPIllegalAttrErr(ctxt,
  8881. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  8882. }
  8883. attr = attr->next;
  8884. }
  8885. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  8886. /*
  8887. * And now for the children...
  8888. */
  8889. child = node->children;
  8890. if (IS_SCHEMA(child, "annotation")) {
  8891. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  8892. child = child->next;
  8893. }
  8894. if (IS_SCHEMA(child, "all")) {
  8895. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8896. XML_SCHEMA_TYPE_ALL, 0);
  8897. child = child->next;
  8898. } else if (IS_SCHEMA(child, "choice")) {
  8899. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8900. XML_SCHEMA_TYPE_CHOICE, 0);
  8901. child = child->next;
  8902. } else if (IS_SCHEMA(child, "sequence")) {
  8903. item->children = xmlSchemaParseModelGroup(ctxt, schema, child,
  8904. XML_SCHEMA_TYPE_SEQUENCE, 0);
  8905. child = child->next;
  8906. }
  8907. if (child != NULL) {
  8908. xmlSchemaPContentErr(ctxt,
  8909. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  8910. NULL, node, child, NULL,
  8911. "(annotation?, (all | choice | sequence)?)");
  8912. }
  8913. return (item);
  8914. }
  8915. /**
  8916. * xmlSchemaCleanupDoc:
  8917. * @ctxt: a schema validation context
  8918. * @node: the root of the document.
  8919. *
  8920. * removes unwanted nodes in a schemas document tree
  8921. */
  8922. static void
  8923. xmlSchemaCleanupDoc(xmlSchemaParserCtxtPtr ctxt, xmlNodePtr root)
  8924. {
  8925. xmlNodePtr delete, cur;
  8926. if ((ctxt == NULL) || (root == NULL)) return;
  8927. /*
  8928. * Remove all the blank text nodes
  8929. */
  8930. delete = NULL;
  8931. cur = root;
  8932. while (cur != NULL) {
  8933. if (delete != NULL) {
  8934. xmlUnlinkNode(delete);
  8935. xmlFreeNode(delete);
  8936. delete = NULL;
  8937. }
  8938. if (cur->type == XML_TEXT_NODE) {
  8939. if (IS_BLANK_NODE(cur)) {
  8940. if (xmlNodeGetSpacePreserve(cur) != 1) {
  8941. delete = cur;
  8942. }
  8943. }
  8944. } else if ((cur->type != XML_ELEMENT_NODE) &&
  8945. (cur->type != XML_CDATA_SECTION_NODE)) {
  8946. delete = cur;
  8947. goto skip_children;
  8948. }
  8949. /*
  8950. * Skip to next node
  8951. */
  8952. if (cur->children != NULL) {
  8953. if ((cur->children->type != XML_ENTITY_DECL) &&
  8954. (cur->children->type != XML_ENTITY_REF_NODE) &&
  8955. (cur->children->type != XML_ENTITY_NODE)) {
  8956. cur = cur->children;
  8957. continue;
  8958. }
  8959. }
  8960. skip_children:
  8961. if (cur->next != NULL) {
  8962. cur = cur->next;
  8963. continue;
  8964. }
  8965. do {
  8966. cur = cur->parent;
  8967. if (cur == NULL)
  8968. break;
  8969. if (cur == root) {
  8970. cur = NULL;
  8971. break;
  8972. }
  8973. if (cur->next != NULL) {
  8974. cur = cur->next;
  8975. break;
  8976. }
  8977. } while (cur != NULL);
  8978. }
  8979. if (delete != NULL) {
  8980. xmlUnlinkNode(delete);
  8981. xmlFreeNode(delete);
  8982. delete = NULL;
  8983. }
  8984. }
  8985. static void
  8986. xmlSchemaClearSchemaDefaults(xmlSchemaPtr schema)
  8987. {
  8988. if (schema->flags & XML_SCHEMAS_QUALIF_ELEM)
  8989. schema->flags ^= XML_SCHEMAS_QUALIF_ELEM;
  8990. if (schema->flags & XML_SCHEMAS_QUALIF_ATTR)
  8991. schema->flags ^= XML_SCHEMAS_QUALIF_ATTR;
  8992. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  8993. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_EXTENSION;
  8994. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  8995. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION;
  8996. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_LIST)
  8997. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_LIST;
  8998. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_UNION)
  8999. schema->flags ^= XML_SCHEMAS_FINAL_DEFAULT_UNION;
  9000. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  9001. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION;
  9002. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  9003. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION;
  9004. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION)
  9005. schema->flags ^= XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION;
  9006. }
  9007. static int
  9008. xmlSchemaParseSchemaElement(xmlSchemaParserCtxtPtr ctxt,
  9009. xmlSchemaPtr schema,
  9010. xmlNodePtr node)
  9011. {
  9012. xmlAttrPtr attr;
  9013. const xmlChar *val;
  9014. int res = 0, oldErrs = ctxt->nberrors;
  9015. /*
  9016. * Those flags should be moved to the parser context flags,
  9017. * since they are not visible at the component level. I.e.
  9018. * they are used if processing schema *documents* only.
  9019. */
  9020. res = xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  9021. HFAILURE;
  9022. /*
  9023. * Since the version is of type xs:token, we won't bother to
  9024. * check it.
  9025. */
  9026. /* REMOVED:
  9027. attr = xmlSchemaGetPropNode(node, "version");
  9028. if (attr != NULL) {
  9029. res = xmlSchemaPValAttrNode(ctxt, NULL, NULL, attr,
  9030. xmlSchemaGetBuiltInType(XML_SCHEMAS_TOKEN), &val);
  9031. HFAILURE;
  9032. }
  9033. */
  9034. attr = xmlSchemaGetPropNode(node, "targetNamespace");
  9035. if (attr != NULL) {
  9036. res = xmlSchemaPValAttrNode(ctxt, NULL, attr,
  9037. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI), NULL);
  9038. HFAILURE;
  9039. if (res != 0) {
  9040. ctxt->stop = XML_SCHEMAP_S4S_ATTR_INVALID_VALUE;
  9041. goto exit;
  9042. }
  9043. }
  9044. attr = xmlSchemaGetPropNode(node, "elementFormDefault");
  9045. if (attr != NULL) {
  9046. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9047. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9048. XML_SCHEMAS_QUALIF_ELEM);
  9049. HFAILURE;
  9050. if (res != 0) {
  9051. xmlSchemaPSimpleTypeErr(ctxt,
  9052. XML_SCHEMAP_ELEMFORMDEFAULT_VALUE,
  9053. NULL, (xmlNodePtr) attr, NULL,
  9054. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9055. }
  9056. }
  9057. attr = xmlSchemaGetPropNode(node, "attributeFormDefault");
  9058. if (attr != NULL) {
  9059. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9060. res = xmlSchemaPValAttrFormDefault(val, &schema->flags,
  9061. XML_SCHEMAS_QUALIF_ATTR);
  9062. HFAILURE;
  9063. if (res != 0) {
  9064. xmlSchemaPSimpleTypeErr(ctxt,
  9065. XML_SCHEMAP_ATTRFORMDEFAULT_VALUE,
  9066. NULL, (xmlNodePtr) attr, NULL,
  9067. "(qualified | unqualified)", val, NULL, NULL, NULL);
  9068. }
  9069. }
  9070. attr = xmlSchemaGetPropNode(node, "finalDefault");
  9071. if (attr != NULL) {
  9072. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9073. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9074. XML_SCHEMAS_FINAL_DEFAULT_EXTENSION,
  9075. XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION,
  9076. -1,
  9077. XML_SCHEMAS_FINAL_DEFAULT_LIST,
  9078. XML_SCHEMAS_FINAL_DEFAULT_UNION);
  9079. HFAILURE;
  9080. if (res != 0) {
  9081. xmlSchemaPSimpleTypeErr(ctxt,
  9082. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9083. NULL, (xmlNodePtr) attr, NULL,
  9084. "(#all | List of (extension | restriction | list | union))",
  9085. val, NULL, NULL, NULL);
  9086. }
  9087. }
  9088. attr = xmlSchemaGetPropNode(node, "blockDefault");
  9089. if (attr != NULL) {
  9090. val = xmlSchemaGetNodeContent(ctxt, (xmlNodePtr) attr);
  9091. res = xmlSchemaPValAttrBlockFinal(val, &(schema->flags), -1,
  9092. XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION,
  9093. XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION,
  9094. XML_SCHEMAS_BLOCK_DEFAULT_SUBSTITUTION, -1, -1);
  9095. HFAILURE;
  9096. if (res != 0) {
  9097. xmlSchemaPSimpleTypeErr(ctxt,
  9098. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  9099. NULL, (xmlNodePtr) attr, NULL,
  9100. "(#all | List of (extension | restriction | substitution))",
  9101. val, NULL, NULL, NULL);
  9102. }
  9103. }
  9104. exit:
  9105. if (oldErrs != ctxt->nberrors)
  9106. res = ctxt->err;
  9107. return(res);
  9108. exit_failure:
  9109. return(-1);
  9110. }
  9111. /**
  9112. * xmlSchemaParseSchemaTopLevel:
  9113. * @ctxt: a schema validation context
  9114. * @schema: the schemas
  9115. * @nodes: the list of top level nodes
  9116. *
  9117. * Returns the internal XML Schema structure built from the resource or
  9118. * NULL in case of error
  9119. */
  9120. static int
  9121. xmlSchemaParseSchemaTopLevel(xmlSchemaParserCtxtPtr ctxt,
  9122. xmlSchemaPtr schema, xmlNodePtr nodes)
  9123. {
  9124. xmlNodePtr child;
  9125. xmlSchemaAnnotPtr annot;
  9126. int res = 0, oldErrs, tmpOldErrs;
  9127. if ((ctxt == NULL) || (schema == NULL) || (nodes == NULL))
  9128. return(-1);
  9129. oldErrs = ctxt->nberrors;
  9130. child = nodes;
  9131. while ((IS_SCHEMA(child, "include")) ||
  9132. (IS_SCHEMA(child, "import")) ||
  9133. (IS_SCHEMA(child, "redefine")) ||
  9134. (IS_SCHEMA(child, "annotation"))) {
  9135. if (IS_SCHEMA(child, "annotation")) {
  9136. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9137. if (schema->annot == NULL)
  9138. schema->annot = annot;
  9139. else
  9140. xmlSchemaFreeAnnot(annot);
  9141. } else if (IS_SCHEMA(child, "import")) {
  9142. tmpOldErrs = ctxt->nberrors;
  9143. res = xmlSchemaParseImport(ctxt, schema, child);
  9144. HFAILURE;
  9145. HSTOP(ctxt);
  9146. if (tmpOldErrs != ctxt->nberrors)
  9147. goto exit;
  9148. } else if (IS_SCHEMA(child, "include")) {
  9149. tmpOldErrs = ctxt->nberrors;
  9150. res = xmlSchemaParseInclude(ctxt, schema, child);
  9151. HFAILURE;
  9152. HSTOP(ctxt);
  9153. if (tmpOldErrs != ctxt->nberrors)
  9154. goto exit;
  9155. } else if (IS_SCHEMA(child, "redefine")) {
  9156. tmpOldErrs = ctxt->nberrors;
  9157. res = xmlSchemaParseRedefine(ctxt, schema, child);
  9158. HFAILURE;
  9159. HSTOP(ctxt);
  9160. if (tmpOldErrs != ctxt->nberrors)
  9161. goto exit;
  9162. }
  9163. child = child->next;
  9164. }
  9165. /*
  9166. * URGENT TODO: Change the functions to return int results.
  9167. * We need especially to catch internal errors.
  9168. */
  9169. while (child != NULL) {
  9170. if (IS_SCHEMA(child, "complexType")) {
  9171. xmlSchemaParseComplexType(ctxt, schema, child, 1);
  9172. child = child->next;
  9173. } else if (IS_SCHEMA(child, "simpleType")) {
  9174. xmlSchemaParseSimpleType(ctxt, schema, child, 1);
  9175. child = child->next;
  9176. } else if (IS_SCHEMA(child, "element")) {
  9177. xmlSchemaParseElement(ctxt, schema, child, NULL, 1);
  9178. child = child->next;
  9179. } else if (IS_SCHEMA(child, "attribute")) {
  9180. xmlSchemaParseGlobalAttribute(ctxt, schema, child);
  9181. child = child->next;
  9182. } else if (IS_SCHEMA(child, "attributeGroup")) {
  9183. xmlSchemaParseAttributeGroupDefinition(ctxt, schema, child);
  9184. child = child->next;
  9185. } else if (IS_SCHEMA(child, "group")) {
  9186. xmlSchemaParseModelGroupDefinition(ctxt, schema, child);
  9187. child = child->next;
  9188. } else if (IS_SCHEMA(child, "notation")) {
  9189. xmlSchemaParseNotation(ctxt, schema, child);
  9190. child = child->next;
  9191. } else {
  9192. xmlSchemaPContentErr(ctxt,
  9193. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  9194. NULL, child->parent, child,
  9195. NULL, "((include | import | redefine | annotation)*, "
  9196. "(((simpleType | complexType | group | attributeGroup) "
  9197. "| element | attribute | notation), annotation*)*)");
  9198. child = child->next;
  9199. }
  9200. while (IS_SCHEMA(child, "annotation")) {
  9201. /*
  9202. * TODO: We should add all annotations.
  9203. */
  9204. annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  9205. if (schema->annot == NULL)
  9206. schema->annot = annot;
  9207. else
  9208. xmlSchemaFreeAnnot(annot);
  9209. child = child->next;
  9210. }
  9211. }
  9212. exit:
  9213. ctxt->ctxtType = NULL;
  9214. if (oldErrs != ctxt->nberrors)
  9215. res = ctxt->err;
  9216. return(res);
  9217. exit_failure:
  9218. return(-1);
  9219. }
  9220. static xmlSchemaSchemaRelationPtr
  9221. xmlSchemaSchemaRelationCreate(void)
  9222. {
  9223. xmlSchemaSchemaRelationPtr ret;
  9224. ret = (xmlSchemaSchemaRelationPtr)
  9225. xmlMalloc(sizeof(xmlSchemaSchemaRelation));
  9226. if (ret == NULL) {
  9227. xmlSchemaPErrMemory(NULL, "allocating schema relation", NULL);
  9228. return(NULL);
  9229. }
  9230. memset(ret, 0, sizeof(xmlSchemaSchemaRelation));
  9231. return(ret);
  9232. }
  9233. #if 0
  9234. static void
  9235. xmlSchemaSchemaRelationFree(xmlSchemaSchemaRelationPtr rel)
  9236. {
  9237. xmlFree(rel);
  9238. }
  9239. #endif
  9240. static void
  9241. xmlSchemaRedefListFree(xmlSchemaRedefPtr redef)
  9242. {
  9243. xmlSchemaRedefPtr prev;
  9244. while (redef != NULL) {
  9245. prev = redef;
  9246. redef = redef->next;
  9247. xmlFree(prev);
  9248. }
  9249. }
  9250. static void
  9251. xmlSchemaConstructionCtxtFree(xmlSchemaConstructionCtxtPtr con)
  9252. {
  9253. /*
  9254. * After the construction context has been freed, there will be
  9255. * no schema graph available any more. Only the schema buckets
  9256. * will stay alive, which are put into the "schemasImports" and
  9257. * "includes" slots of the xmlSchema.
  9258. */
  9259. if (con->buckets != NULL)
  9260. xmlSchemaItemListFree(con->buckets);
  9261. if (con->pending != NULL)
  9262. xmlSchemaItemListFree(con->pending);
  9263. if (con->substGroups != NULL)
  9264. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  9265. if (con->redefs != NULL)
  9266. xmlSchemaRedefListFree(con->redefs);
  9267. if (con->dict != NULL)
  9268. xmlDictFree(con->dict);
  9269. xmlFree(con);
  9270. }
  9271. static xmlSchemaConstructionCtxtPtr
  9272. xmlSchemaConstructionCtxtCreate(xmlDictPtr dict)
  9273. {
  9274. xmlSchemaConstructionCtxtPtr ret;
  9275. ret = (xmlSchemaConstructionCtxtPtr)
  9276. xmlMalloc(sizeof(xmlSchemaConstructionCtxt));
  9277. if (ret == NULL) {
  9278. xmlSchemaPErrMemory(NULL,
  9279. "allocating schema construction context", NULL);
  9280. return (NULL);
  9281. }
  9282. memset(ret, 0, sizeof(xmlSchemaConstructionCtxt));
  9283. ret->buckets = xmlSchemaItemListCreate();
  9284. if (ret->buckets == NULL) {
  9285. xmlSchemaPErrMemory(NULL,
  9286. "allocating list of schema buckets", NULL);
  9287. xmlFree(ret);
  9288. return (NULL);
  9289. }
  9290. ret->pending = xmlSchemaItemListCreate();
  9291. if (ret->pending == NULL) {
  9292. xmlSchemaPErrMemory(NULL,
  9293. "allocating list of pending global components", NULL);
  9294. xmlSchemaConstructionCtxtFree(ret);
  9295. return (NULL);
  9296. }
  9297. ret->dict = dict;
  9298. xmlDictReference(dict);
  9299. return(ret);
  9300. }
  9301. static xmlSchemaParserCtxtPtr
  9302. xmlSchemaParserCtxtCreate(void)
  9303. {
  9304. xmlSchemaParserCtxtPtr ret;
  9305. ret = (xmlSchemaParserCtxtPtr) xmlMalloc(sizeof(xmlSchemaParserCtxt));
  9306. if (ret == NULL) {
  9307. xmlSchemaPErrMemory(NULL, "allocating schema parser context",
  9308. NULL);
  9309. return (NULL);
  9310. }
  9311. memset(ret, 0, sizeof(xmlSchemaParserCtxt));
  9312. ret->type = XML_SCHEMA_CTXT_PARSER;
  9313. ret->attrProhibs = xmlSchemaItemListCreate();
  9314. if (ret->attrProhibs == NULL) {
  9315. xmlFree(ret);
  9316. return(NULL);
  9317. }
  9318. return(ret);
  9319. }
  9320. /**
  9321. * xmlSchemaNewParserCtxtUseDict:
  9322. * @URL: the location of the schema
  9323. * @dict: the dictionary to be used
  9324. *
  9325. * Create an XML Schemas parse context for that file/resource expected
  9326. * to contain an XML Schemas file.
  9327. *
  9328. * Returns the parser context or NULL in case of error
  9329. */
  9330. static xmlSchemaParserCtxtPtr
  9331. xmlSchemaNewParserCtxtUseDict(const char *URL, xmlDictPtr dict)
  9332. {
  9333. xmlSchemaParserCtxtPtr ret;
  9334. ret = xmlSchemaParserCtxtCreate();
  9335. if (ret == NULL)
  9336. return (NULL);
  9337. ret->dict = dict;
  9338. xmlDictReference(dict);
  9339. if (URL != NULL)
  9340. ret->URL = xmlDictLookup(dict, (const xmlChar *) URL, -1);
  9341. return (ret);
  9342. }
  9343. static int
  9344. xmlSchemaCreatePCtxtOnVCtxt(xmlSchemaValidCtxtPtr vctxt)
  9345. {
  9346. if (vctxt->pctxt == NULL) {
  9347. if (vctxt->schema != NULL)
  9348. vctxt->pctxt =
  9349. xmlSchemaNewParserCtxtUseDict("*", vctxt->schema->dict);
  9350. else
  9351. vctxt->pctxt = xmlSchemaNewParserCtxt("*");
  9352. if (vctxt->pctxt == NULL) {
  9353. VERROR_INT("xmlSchemaCreatePCtxtOnVCtxt",
  9354. "failed to create a temp. parser context");
  9355. return (-1);
  9356. }
  9357. /* TODO: Pass user data. */
  9358. xmlSchemaSetParserErrors(vctxt->pctxt, vctxt->error,
  9359. vctxt->warning, vctxt->errCtxt);
  9360. xmlSchemaSetParserStructuredErrors(vctxt->pctxt, vctxt->serror,
  9361. vctxt->errCtxt);
  9362. }
  9363. return (0);
  9364. }
  9365. /**
  9366. * xmlSchemaGetSchemaBucket:
  9367. * @pctxt: the schema parser context
  9368. * @schemaLocation: the URI of the schema document
  9369. *
  9370. * Returns a schema bucket if it was already parsed.
  9371. *
  9372. * Returns a schema bucket if it was already parsed from
  9373. * @schemaLocation, NULL otherwise.
  9374. */
  9375. static xmlSchemaBucketPtr
  9376. xmlSchemaGetSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9377. const xmlChar *schemaLocation)
  9378. {
  9379. xmlSchemaBucketPtr cur;
  9380. xmlSchemaItemListPtr list;
  9381. list = pctxt->constructor->buckets;
  9382. if (list->nbItems == 0)
  9383. return(NULL);
  9384. else {
  9385. int i;
  9386. for (i = 0; i < list->nbItems; i++) {
  9387. cur = (xmlSchemaBucketPtr) list->items[i];
  9388. /* Pointer comparison! */
  9389. if (cur->schemaLocation == schemaLocation)
  9390. return(cur);
  9391. }
  9392. }
  9393. return(NULL);
  9394. }
  9395. static xmlSchemaBucketPtr
  9396. xmlSchemaGetChameleonSchemaBucket(xmlSchemaParserCtxtPtr pctxt,
  9397. const xmlChar *schemaLocation,
  9398. const xmlChar *targetNamespace)
  9399. {
  9400. xmlSchemaBucketPtr cur;
  9401. xmlSchemaItemListPtr list;
  9402. list = pctxt->constructor->buckets;
  9403. if (list->nbItems == 0)
  9404. return(NULL);
  9405. else {
  9406. int i;
  9407. for (i = 0; i < list->nbItems; i++) {
  9408. cur = (xmlSchemaBucketPtr) list->items[i];
  9409. /* Pointer comparison! */
  9410. if ((cur->origTargetNamespace == NULL) &&
  9411. (cur->schemaLocation == schemaLocation) &&
  9412. (cur->targetNamespace == targetNamespace))
  9413. return(cur);
  9414. }
  9415. }
  9416. return(NULL);
  9417. }
  9418. #define IS_BAD_SCHEMA_DOC(b) \
  9419. (((b)->doc == NULL) && ((b)->schemaLocation != NULL))
  9420. static xmlSchemaBucketPtr
  9421. xmlSchemaGetSchemaBucketByTNS(xmlSchemaParserCtxtPtr pctxt,
  9422. const xmlChar *targetNamespace,
  9423. int imported)
  9424. {
  9425. xmlSchemaBucketPtr cur;
  9426. xmlSchemaItemListPtr list;
  9427. list = pctxt->constructor->buckets;
  9428. if (list->nbItems == 0)
  9429. return(NULL);
  9430. else {
  9431. int i;
  9432. for (i = 0; i < list->nbItems; i++) {
  9433. cur = (xmlSchemaBucketPtr) list->items[i];
  9434. if ((! IS_BAD_SCHEMA_DOC(cur)) &&
  9435. (cur->origTargetNamespace == targetNamespace) &&
  9436. ((imported && cur->imported) ||
  9437. ((!imported) && (!cur->imported))))
  9438. return(cur);
  9439. }
  9440. }
  9441. return(NULL);
  9442. }
  9443. static int
  9444. xmlSchemaParseNewDocWithContext(xmlSchemaParserCtxtPtr pctxt,
  9445. xmlSchemaPtr schema,
  9446. xmlSchemaBucketPtr bucket)
  9447. {
  9448. int oldFlags;
  9449. xmlDocPtr oldDoc;
  9450. xmlNodePtr node;
  9451. int ret, oldErrs;
  9452. xmlSchemaBucketPtr oldbucket = pctxt->constructor->bucket;
  9453. /*
  9454. * Save old values; reset the *main* schema.
  9455. * URGENT TODO: This is not good; move the per-document information
  9456. * to the parser. Get rid of passing the main schema to the
  9457. * parsing functions.
  9458. */
  9459. oldFlags = schema->flags;
  9460. oldDoc = schema->doc;
  9461. if (schema->flags != 0)
  9462. xmlSchemaClearSchemaDefaults(schema);
  9463. schema->doc = bucket->doc;
  9464. pctxt->schema = schema;
  9465. /*
  9466. * Keep the current target namespace on the parser *not* on the
  9467. * main schema.
  9468. */
  9469. pctxt->targetNamespace = bucket->targetNamespace;
  9470. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  9471. if ((bucket->targetNamespace != NULL) &&
  9472. xmlStrEqual(bucket->targetNamespace, xmlSchemaNs)) {
  9473. /*
  9474. * We are parsing the schema for schemas!
  9475. */
  9476. pctxt->isS4S = 1;
  9477. }
  9478. /* Mark it as parsed, even if parsing fails. */
  9479. bucket->parsed++;
  9480. /* Compile the schema doc. */
  9481. node = xmlDocGetRootElement(bucket->doc);
  9482. ret = xmlSchemaParseSchemaElement(pctxt, schema, node);
  9483. if (ret != 0)
  9484. goto exit;
  9485. /* An empty schema; just get out. */
  9486. if (node->children == NULL)
  9487. goto exit;
  9488. oldErrs = pctxt->nberrors;
  9489. ret = xmlSchemaParseSchemaTopLevel(pctxt, schema, node->children);
  9490. if (ret != 0)
  9491. goto exit;
  9492. /*
  9493. * TODO: Not nice, but I'm not 100% sure we will get always an error
  9494. * as a result of the above functions; so better rely on pctxt->err
  9495. * as well.
  9496. */
  9497. if ((ret == 0) && (oldErrs != pctxt->nberrors)) {
  9498. ret = pctxt->err;
  9499. goto exit;
  9500. }
  9501. exit:
  9502. WXS_CONSTRUCTOR(pctxt)->bucket = oldbucket;
  9503. /* Restore schema values. */
  9504. schema->doc = oldDoc;
  9505. schema->flags = oldFlags;
  9506. return(ret);
  9507. }
  9508. static int
  9509. xmlSchemaParseNewDoc(xmlSchemaParserCtxtPtr pctxt,
  9510. xmlSchemaPtr schema,
  9511. xmlSchemaBucketPtr bucket)
  9512. {
  9513. xmlSchemaParserCtxtPtr newpctxt;
  9514. int res = 0;
  9515. if (bucket == NULL)
  9516. return(0);
  9517. if (bucket->parsed) {
  9518. PERROR_INT("xmlSchemaParseNewDoc",
  9519. "reparsing a schema doc");
  9520. return(-1);
  9521. }
  9522. if (bucket->doc == NULL) {
  9523. PERROR_INT("xmlSchemaParseNewDoc",
  9524. "parsing a schema doc, but there's no doc");
  9525. return(-1);
  9526. }
  9527. if (pctxt->constructor == NULL) {
  9528. PERROR_INT("xmlSchemaParseNewDoc",
  9529. "no constructor");
  9530. return(-1);
  9531. }
  9532. /* Create and init the temporary parser context. */
  9533. newpctxt = xmlSchemaNewParserCtxtUseDict(
  9534. (const char *) bucket->schemaLocation, pctxt->dict);
  9535. if (newpctxt == NULL)
  9536. return(-1);
  9537. newpctxt->constructor = pctxt->constructor;
  9538. /*
  9539. * TODO: Can we avoid that the parser knows about the main schema?
  9540. * It would be better if he knows about the current schema bucket
  9541. * only.
  9542. */
  9543. newpctxt->schema = schema;
  9544. xmlSchemaSetParserErrors(newpctxt, pctxt->error, pctxt->warning,
  9545. pctxt->errCtxt);
  9546. xmlSchemaSetParserStructuredErrors(newpctxt, pctxt->serror,
  9547. pctxt->errCtxt);
  9548. newpctxt->counter = pctxt->counter;
  9549. res = xmlSchemaParseNewDocWithContext(newpctxt, schema, bucket);
  9550. /* Channel back errors and cleanup the temporary parser context. */
  9551. if (res != 0)
  9552. pctxt->err = res;
  9553. pctxt->nberrors += newpctxt->nberrors;
  9554. pctxt->counter = newpctxt->counter;
  9555. newpctxt->constructor = NULL;
  9556. /* Free the parser context. */
  9557. xmlSchemaFreeParserCtxt(newpctxt);
  9558. return(res);
  9559. }
  9560. static void
  9561. xmlSchemaSchemaRelationAddChild(xmlSchemaBucketPtr bucket,
  9562. xmlSchemaSchemaRelationPtr rel)
  9563. {
  9564. xmlSchemaSchemaRelationPtr cur = bucket->relations;
  9565. if (cur == NULL) {
  9566. bucket->relations = rel;
  9567. return;
  9568. }
  9569. while (cur->next != NULL)
  9570. cur = cur->next;
  9571. cur->next = rel;
  9572. }
  9573. static const xmlChar *
  9574. xmlSchemaBuildAbsoluteURI(xmlDictPtr dict, const xmlChar* location,
  9575. xmlNodePtr ctxtNode)
  9576. {
  9577. /*
  9578. * Build an absolute location URI.
  9579. */
  9580. if (location != NULL) {
  9581. if (ctxtNode == NULL)
  9582. return(location);
  9583. else {
  9584. xmlChar *base, *URI;
  9585. const xmlChar *ret = NULL;
  9586. base = xmlNodeGetBase(ctxtNode->doc, ctxtNode);
  9587. if (base == NULL) {
  9588. URI = xmlBuildURI(location, ctxtNode->doc->URL);
  9589. } else {
  9590. URI = xmlBuildURI(location, base);
  9591. xmlFree(base);
  9592. }
  9593. if (URI != NULL) {
  9594. ret = xmlDictLookup(dict, URI, -1);
  9595. xmlFree(URI);
  9596. return(ret);
  9597. }
  9598. }
  9599. }
  9600. return(NULL);
  9601. }
  9602. /**
  9603. * xmlSchemaAddSchemaDoc:
  9604. * @pctxt: a schema validation context
  9605. * @schema: the schema being built
  9606. * @node: a subtree containing XML Schema informations
  9607. *
  9608. * Parse an included (and to-be-redefined) XML schema document.
  9609. *
  9610. * Returns 0 on success, a positive error code on errors and
  9611. * -1 in case of an internal or API error.
  9612. */
  9613. static int
  9614. xmlSchemaAddSchemaDoc(xmlSchemaParserCtxtPtr pctxt,
  9615. int type, /* import or include or redefine */
  9616. const xmlChar *schemaLocation,
  9617. xmlDocPtr schemaDoc,
  9618. const char *schemaBuffer,
  9619. int schemaBufferLen,
  9620. xmlNodePtr invokingNode,
  9621. const xmlChar *sourceTargetNamespace,
  9622. const xmlChar *importNamespace,
  9623. xmlSchemaBucketPtr *bucket)
  9624. {
  9625. const xmlChar *targetNamespace = NULL;
  9626. xmlSchemaSchemaRelationPtr relation = NULL;
  9627. xmlDocPtr doc = NULL;
  9628. int res = 0, err = 0, located = 0, preserveDoc = 0;
  9629. xmlSchemaBucketPtr bkt = NULL;
  9630. if (bucket != NULL)
  9631. *bucket = NULL;
  9632. switch (type) {
  9633. case XML_SCHEMA_SCHEMA_IMPORT:
  9634. case XML_SCHEMA_SCHEMA_MAIN:
  9635. err = XML_SCHEMAP_SRC_IMPORT;
  9636. break;
  9637. case XML_SCHEMA_SCHEMA_INCLUDE:
  9638. err = XML_SCHEMAP_SRC_INCLUDE;
  9639. break;
  9640. case XML_SCHEMA_SCHEMA_REDEFINE:
  9641. err = XML_SCHEMAP_SRC_REDEFINE;
  9642. break;
  9643. }
  9644. /* Special handling for the main schema:
  9645. * skip the location and relation logic and just parse the doc.
  9646. * We need just a bucket to be returned in this case.
  9647. */
  9648. if ((type == XML_SCHEMA_SCHEMA_MAIN) || (! WXS_HAS_BUCKETS(pctxt)))
  9649. goto doc_load;
  9650. /* Note that we expect the location to be an absolute URI. */
  9651. if (schemaLocation != NULL) {
  9652. bkt = xmlSchemaGetSchemaBucket(pctxt, schemaLocation);
  9653. if ((bkt != NULL) &&
  9654. (pctxt->constructor->bucket == bkt)) {
  9655. /* Report self-imports/inclusions/redefinitions. */
  9656. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9657. invokingNode, NULL,
  9658. "The schema must not import/include/redefine itself",
  9659. NULL, NULL);
  9660. goto exit;
  9661. }
  9662. }
  9663. /*
  9664. * Create a relation for the graph of schemas.
  9665. */
  9666. relation = xmlSchemaSchemaRelationCreate();
  9667. if (relation == NULL)
  9668. return(-1);
  9669. xmlSchemaSchemaRelationAddChild(pctxt->constructor->bucket,
  9670. relation);
  9671. relation->type = type;
  9672. /*
  9673. * Save the namespace import information.
  9674. */
  9675. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9676. relation->importNamespace = importNamespace;
  9677. if (schemaLocation == NULL) {
  9678. /*
  9679. * No location; this is just an import of the namespace.
  9680. * Note that we don't assign a bucket to the relation
  9681. * in this case.
  9682. */
  9683. goto exit;
  9684. }
  9685. targetNamespace = importNamespace;
  9686. }
  9687. /* Did we already fetch the doc? */
  9688. if (bkt != NULL) {
  9689. if ((WXS_IS_BUCKET_IMPMAIN(type)) && (! bkt->imported)) {
  9690. /*
  9691. * We included/redefined and then try to import a schema,
  9692. * but the new location provided for import was different.
  9693. */
  9694. if (schemaLocation == NULL)
  9695. schemaLocation = BAD_CAST "in_memory_buffer";
  9696. if (!xmlStrEqual(schemaLocation,
  9697. bkt->schemaLocation)) {
  9698. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9699. invokingNode, NULL,
  9700. "The schema document '%s' cannot be imported, since "
  9701. "it was already included or redefined",
  9702. schemaLocation, NULL);
  9703. goto exit;
  9704. }
  9705. } else if ((! WXS_IS_BUCKET_IMPMAIN(type)) && (bkt->imported)) {
  9706. /*
  9707. * We imported and then try to include/redefine a schema,
  9708. * but the new location provided for the include/redefine
  9709. * was different.
  9710. */
  9711. if (schemaLocation == NULL)
  9712. schemaLocation = BAD_CAST "in_memory_buffer";
  9713. if (!xmlStrEqual(schemaLocation,
  9714. bkt->schemaLocation)) {
  9715. xmlSchemaCustomErr(ACTXT_CAST pctxt, err,
  9716. invokingNode, NULL,
  9717. "The schema document '%s' cannot be included or "
  9718. "redefined, since it was already imported",
  9719. schemaLocation, NULL);
  9720. goto exit;
  9721. }
  9722. }
  9723. }
  9724. if (WXS_IS_BUCKET_IMPMAIN(type)) {
  9725. /*
  9726. * Given that the schemaLocation [attribute] is only a hint, it is open
  9727. * to applications to ignore all but the first <import> for a given
  9728. * namespace, regardless of the `actual value` of schemaLocation, but
  9729. * such a strategy risks missing useful information when new
  9730. * schemaLocations are offered.
  9731. *
  9732. * We will use the first <import> that comes with a location.
  9733. * Further <import>s *with* a location, will result in an error.
  9734. * TODO: Better would be to just report a warning here, but
  9735. * we'll try it this way until someone complains.
  9736. *
  9737. * Schema Document Location Strategy:
  9738. * 3 Based on the namespace name, identify an existing schema document,
  9739. * either as a resource which is an XML document or a <schema> element
  9740. * information item, in some local schema repository;
  9741. * 5 Attempt to resolve the namespace name to locate such a resource.
  9742. *
  9743. * NOTE: (3) and (5) are not supported.
  9744. */
  9745. if (bkt != NULL) {
  9746. relation->bucket = bkt;
  9747. goto exit;
  9748. }
  9749. bkt = xmlSchemaGetSchemaBucketByTNS(pctxt,
  9750. importNamespace, 1);
  9751. if (bkt != NULL) {
  9752. relation->bucket = bkt;
  9753. if (bkt->schemaLocation == NULL) {
  9754. /* First given location of the schema; load the doc. */
  9755. bkt->schemaLocation = schemaLocation;
  9756. } else {
  9757. if (!xmlStrEqual(schemaLocation,
  9758. bkt->schemaLocation)) {
  9759. /*
  9760. * Additional location given; just skip it.
  9761. * URGENT TODO: We should report a warning here.
  9762. * res = XML_SCHEMAP_SRC_IMPORT;
  9763. */
  9764. if (schemaLocation == NULL)
  9765. schemaLocation = BAD_CAST "in_memory_buffer";
  9766. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  9767. XML_SCHEMAP_WARN_SKIP_SCHEMA,
  9768. invokingNode, NULL,
  9769. "Skipping import of schema located at '%s' for the "
  9770. "namespace '%s', since this namespace was already "
  9771. "imported with the schema located at '%s'",
  9772. schemaLocation, importNamespace, bkt->schemaLocation);
  9773. }
  9774. goto exit;
  9775. }
  9776. }
  9777. /*
  9778. * No bucket + first location: load the doc and create a
  9779. * bucket.
  9780. */
  9781. } else {
  9782. /* <include> and <redefine> */
  9783. if (bkt != NULL) {
  9784. if ((bkt->origTargetNamespace == NULL) &&
  9785. (bkt->targetNamespace != sourceTargetNamespace)) {
  9786. xmlSchemaBucketPtr chamel;
  9787. /*
  9788. * Chameleon include/redefine: skip loading only if it was
  9789. * already build for the targetNamespace of the including
  9790. * schema.
  9791. */
  9792. /*
  9793. * URGENT TODO: If the schema is a chameleon-include then copy
  9794. * the components into the including schema and modify the
  9795. * targetNamespace of those components, do nothing otherwise.
  9796. * NOTE: This is currently worked-around by compiling the
  9797. * chameleon for every distinct including targetNamespace; thus
  9798. * not performant at the moment.
  9799. * TODO: Check when the namespace in wildcards for chameleons
  9800. * needs to be converted: before we built wildcard intersections
  9801. * or after.
  9802. * Answer: after!
  9803. */
  9804. chamel = xmlSchemaGetChameleonSchemaBucket(pctxt,
  9805. schemaLocation, sourceTargetNamespace);
  9806. if (chamel != NULL) {
  9807. /* A fitting chameleon was already parsed; NOP. */
  9808. relation->bucket = chamel;
  9809. goto exit;
  9810. }
  9811. /*
  9812. * We need to parse the chameleon again for a different
  9813. * targetNamespace.
  9814. * CHAMELEON TODO: Optimize this by only parsing the
  9815. * chameleon once, and then copying the components to
  9816. * the new targetNamespace.
  9817. */
  9818. bkt = NULL;
  9819. } else {
  9820. relation->bucket = bkt;
  9821. goto exit;
  9822. }
  9823. }
  9824. }
  9825. if ((bkt != NULL) && (bkt->doc != NULL)) {
  9826. PERROR_INT("xmlSchemaAddSchemaDoc",
  9827. "trying to load a schema doc, but a doc is already "
  9828. "assigned to the schema bucket");
  9829. goto exit_failure;
  9830. }
  9831. doc_load:
  9832. /*
  9833. * Load the document.
  9834. */
  9835. if (schemaDoc != NULL) {
  9836. doc = schemaDoc;
  9837. /* Don' free this one, since it was provided by the caller. */
  9838. preserveDoc = 1;
  9839. /* TODO: Does the context or the doc hold the location? */
  9840. if (schemaDoc->URL != NULL)
  9841. schemaLocation = xmlDictLookup(pctxt->dict,
  9842. schemaDoc->URL, -1);
  9843. else
  9844. schemaLocation = BAD_CAST "in_memory_buffer";
  9845. } else if ((schemaLocation != NULL) || (schemaBuffer != NULL)) {
  9846. xmlParserCtxtPtr parserCtxt;
  9847. parserCtxt = xmlNewParserCtxt();
  9848. if (parserCtxt == NULL) {
  9849. xmlSchemaPErrMemory(NULL, "xmlSchemaGetDoc, "
  9850. "allocating a parser context", NULL);
  9851. goto exit_failure;
  9852. }
  9853. if ((pctxt->dict != NULL) && (parserCtxt->dict != NULL)) {
  9854. /*
  9855. * TODO: Do we have to burden the schema parser dict with all
  9856. * the content of the schema doc?
  9857. */
  9858. xmlDictFree(parserCtxt->dict);
  9859. parserCtxt->dict = pctxt->dict;
  9860. xmlDictReference(parserCtxt->dict);
  9861. }
  9862. if (schemaLocation != NULL) {
  9863. /* Parse from file. */
  9864. doc = xmlCtxtReadFile(parserCtxt, (const char *) schemaLocation,
  9865. NULL, SCHEMAS_PARSE_OPTIONS);
  9866. } else if (schemaBuffer != NULL) {
  9867. /* Parse from memory buffer. */
  9868. doc = xmlCtxtReadMemory(parserCtxt, schemaBuffer, schemaBufferLen,
  9869. NULL, NULL, SCHEMAS_PARSE_OPTIONS);
  9870. schemaLocation = BAD_CAST "in_memory_buffer";
  9871. if (doc != NULL)
  9872. doc->URL = xmlStrdup(schemaLocation);
  9873. }
  9874. /*
  9875. * For <import>:
  9876. * 2.1 The referent is (a fragment of) a resource which is an
  9877. * XML document (see clause 1.1), which in turn corresponds to
  9878. * a <schema> element information item in a well-formed information
  9879. * set, which in turn corresponds to a valid schema.
  9880. * TODO: (2.1) fragments of XML documents are not supported.
  9881. *
  9882. * 2.2 The referent is a <schema> element information item in
  9883. * a well-formed information set, which in turn corresponds
  9884. * to a valid schema.
  9885. * TODO: (2.2) is not supported.
  9886. */
  9887. if (doc == NULL) {
  9888. xmlErrorPtr lerr;
  9889. lerr = xmlGetLastError();
  9890. /*
  9891. * Check if this a parser error, or if the document could
  9892. * just not be located.
  9893. * TODO: Try to find specific error codes to react only on
  9894. * localisation failures.
  9895. */
  9896. if ((lerr == NULL) || (lerr->domain != XML_FROM_IO)) {
  9897. /*
  9898. * We assume a parser error here.
  9899. */
  9900. located = 1;
  9901. /* TODO: Error code ?? */
  9902. res = XML_SCHEMAP_SRC_IMPORT_2_1;
  9903. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  9904. invokingNode, NULL,
  9905. "Failed to parse the XML resource '%s'",
  9906. schemaLocation, NULL);
  9907. }
  9908. }
  9909. xmlFreeParserCtxt(parserCtxt);
  9910. if ((doc == NULL) && located)
  9911. goto exit_error;
  9912. } else {
  9913. xmlSchemaPErr(pctxt, NULL,
  9914. XML_SCHEMAP_NOTHING_TO_PARSE,
  9915. "No information for parsing was provided with the "
  9916. "given schema parser context.\n",
  9917. NULL, NULL);
  9918. goto exit_failure;
  9919. }
  9920. /*
  9921. * Preprocess the document.
  9922. */
  9923. if (doc != NULL) {
  9924. xmlNodePtr docElem = NULL;
  9925. located = 1;
  9926. docElem = xmlDocGetRootElement(doc);
  9927. if (docElem == NULL) {
  9928. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOROOT,
  9929. invokingNode, NULL,
  9930. "The document '%s' has no document element",
  9931. schemaLocation, NULL);
  9932. goto exit_error;
  9933. }
  9934. /*
  9935. * Remove all the blank text nodes.
  9936. */
  9937. xmlSchemaCleanupDoc(pctxt, docElem);
  9938. /*
  9939. * Check the schema's top level element.
  9940. */
  9941. if (!IS_SCHEMA(docElem, "schema")) {
  9942. xmlSchemaCustomErr(ACTXT_CAST pctxt, XML_SCHEMAP_NOT_SCHEMA,
  9943. invokingNode, NULL,
  9944. "The XML document '%s' is not a schema document",
  9945. schemaLocation, NULL);
  9946. goto exit_error;
  9947. }
  9948. /*
  9949. * Note that we don't apply a type check for the
  9950. * targetNamespace value here.
  9951. */
  9952. targetNamespace = xmlSchemaGetProp(pctxt, docElem,
  9953. "targetNamespace");
  9954. }
  9955. /* after_doc_loading: */
  9956. if ((bkt == NULL) && located) {
  9957. /* Only create a bucket if the schema was located. */
  9958. bkt = xmlSchemaBucketCreate(pctxt, type,
  9959. targetNamespace);
  9960. if (bkt == NULL)
  9961. goto exit_failure;
  9962. }
  9963. if (bkt != NULL) {
  9964. bkt->schemaLocation = schemaLocation;
  9965. bkt->located = located;
  9966. if (doc != NULL) {
  9967. bkt->doc = doc;
  9968. bkt->targetNamespace = targetNamespace;
  9969. bkt->origTargetNamespace = targetNamespace;
  9970. if (preserveDoc)
  9971. bkt->preserveDoc = 1;
  9972. }
  9973. if (WXS_IS_BUCKET_IMPMAIN(type))
  9974. bkt->imported++;
  9975. /*
  9976. * Add it to the graph of schemas.
  9977. */
  9978. if (relation != NULL)
  9979. relation->bucket = bkt;
  9980. }
  9981. exit:
  9982. /*
  9983. * Return the bucket explicitly; this is needed for the
  9984. * main schema.
  9985. */
  9986. if (bucket != NULL)
  9987. *bucket = bkt;
  9988. return (0);
  9989. exit_error:
  9990. if ((doc != NULL) && (! preserveDoc)) {
  9991. xmlFreeDoc(doc);
  9992. if (bkt != NULL)
  9993. bkt->doc = NULL;
  9994. }
  9995. return(pctxt->err);
  9996. exit_failure:
  9997. if ((doc != NULL) && (! preserveDoc)) {
  9998. xmlFreeDoc(doc);
  9999. if (bkt != NULL)
  10000. bkt->doc = NULL;
  10001. }
  10002. return (-1);
  10003. }
  10004. /**
  10005. * xmlSchemaParseImport:
  10006. * @ctxt: a schema validation context
  10007. * @schema: the schema being built
  10008. * @node: a subtree containing XML Schema informations
  10009. *
  10010. * parse a XML schema Import definition
  10011. * *WARNING* this interface is highly subject to change
  10012. *
  10013. * Returns 0 in case of success, a positive error code if
  10014. * not valid and -1 in case of an internal error.
  10015. */
  10016. static int
  10017. xmlSchemaParseImport(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10018. xmlNodePtr node)
  10019. {
  10020. xmlNodePtr child;
  10021. const xmlChar *namespaceName = NULL, *schemaLocation = NULL;
  10022. const xmlChar *thisTargetNamespace;
  10023. xmlAttrPtr attr;
  10024. int ret = 0;
  10025. xmlSchemaBucketPtr bucket = NULL;
  10026. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10027. return (-1);
  10028. /*
  10029. * Check for illegal attributes.
  10030. */
  10031. attr = node->properties;
  10032. while (attr != NULL) {
  10033. if (attr->ns == NULL) {
  10034. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10035. (!xmlStrEqual(attr->name, BAD_CAST "namespace")) &&
  10036. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10037. xmlSchemaPIllegalAttrErr(pctxt,
  10038. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10039. }
  10040. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10041. xmlSchemaPIllegalAttrErr(pctxt,
  10042. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10043. }
  10044. attr = attr->next;
  10045. }
  10046. /*
  10047. * Extract and validate attributes.
  10048. */
  10049. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10050. "namespace", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10051. &namespaceName) != 0) {
  10052. xmlSchemaPSimpleTypeErr(pctxt,
  10053. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10054. NULL, node,
  10055. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10056. NULL, namespaceName, NULL, NULL, NULL);
  10057. return (pctxt->err);
  10058. }
  10059. if (xmlSchemaPValAttr(pctxt, NULL, node,
  10060. "schemaLocation", xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10061. &schemaLocation) != 0) {
  10062. xmlSchemaPSimpleTypeErr(pctxt,
  10063. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  10064. NULL, node,
  10065. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10066. NULL, schemaLocation, NULL, NULL, NULL);
  10067. return (pctxt->err);
  10068. }
  10069. /*
  10070. * And now for the children...
  10071. */
  10072. child = node->children;
  10073. if (IS_SCHEMA(child, "annotation")) {
  10074. /*
  10075. * the annotation here is simply discarded ...
  10076. * TODO: really?
  10077. */
  10078. child = child->next;
  10079. }
  10080. if (child != NULL) {
  10081. xmlSchemaPContentErr(pctxt,
  10082. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10083. NULL, node, child, NULL,
  10084. "(annotation?)");
  10085. }
  10086. /*
  10087. * Apply additional constraints.
  10088. *
  10089. * Note that it is important to use the original @targetNamespace
  10090. * (or none at all), to rule out imports of schemas _with_ a
  10091. * @targetNamespace if the importing schema is a chameleon schema
  10092. * (with no @targetNamespace).
  10093. */
  10094. thisTargetNamespace = WXS_BUCKET(pctxt)->origTargetNamespace;
  10095. if (namespaceName != NULL) {
  10096. /*
  10097. * 1.1 If the namespace [attribute] is present, then its `actual value`
  10098. * must not match the `actual value` of the enclosing <schema>'s
  10099. * targetNamespace [attribute].
  10100. */
  10101. if (xmlStrEqual(thisTargetNamespace, namespaceName)) {
  10102. xmlSchemaPCustomErr(pctxt,
  10103. XML_SCHEMAP_SRC_IMPORT_1_1,
  10104. NULL, node,
  10105. "The value of the attribute 'namespace' must not match "
  10106. "the target namespace '%s' of the importing schema",
  10107. thisTargetNamespace);
  10108. return (pctxt->err);
  10109. }
  10110. } else {
  10111. /*
  10112. * 1.2 If the namespace [attribute] is not present, then the enclosing
  10113. * <schema> must have a targetNamespace [attribute].
  10114. */
  10115. if (thisTargetNamespace == NULL) {
  10116. xmlSchemaPCustomErr(pctxt,
  10117. XML_SCHEMAP_SRC_IMPORT_1_2,
  10118. NULL, node,
  10119. "The attribute 'namespace' must be existent if "
  10120. "the importing schema has no target namespace",
  10121. NULL);
  10122. return (pctxt->err);
  10123. }
  10124. }
  10125. /*
  10126. * Locate and acquire the schema document.
  10127. */
  10128. if (schemaLocation != NULL)
  10129. schemaLocation = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  10130. schemaLocation, node);
  10131. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  10132. schemaLocation, NULL, NULL, 0, node, thisTargetNamespace,
  10133. namespaceName, &bucket);
  10134. if (ret != 0)
  10135. return(ret);
  10136. /*
  10137. * For <import>: "It is *not* an error for the application
  10138. * schema reference strategy to fail."
  10139. * So just don't parse if no schema document was found.
  10140. * Note that we will get no bucket if the schema could not be
  10141. * located or if there was no schemaLocation.
  10142. */
  10143. if ((bucket == NULL) && (schemaLocation != NULL)) {
  10144. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  10145. XML_SCHEMAP_WARN_UNLOCATED_SCHEMA,
  10146. node, NULL,
  10147. "Failed to locate a schema at location '%s'. "
  10148. "Skipping the import", schemaLocation, NULL, NULL);
  10149. }
  10150. if ((bucket != NULL) && CAN_PARSE_SCHEMA(bucket)) {
  10151. ret = xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10152. }
  10153. return (ret);
  10154. }
  10155. static int
  10156. xmlSchemaParseIncludeOrRedefineAttrs(xmlSchemaParserCtxtPtr pctxt,
  10157. xmlSchemaPtr schema,
  10158. xmlNodePtr node,
  10159. xmlChar **schemaLocation,
  10160. int type)
  10161. {
  10162. xmlAttrPtr attr;
  10163. if ((pctxt == NULL) || (schema == NULL) || (node == NULL) ||
  10164. (schemaLocation == NULL))
  10165. return (-1);
  10166. *schemaLocation = NULL;
  10167. /*
  10168. * Check for illegal attributes.
  10169. * Applies for both <include> and <redefine>.
  10170. */
  10171. attr = node->properties;
  10172. while (attr != NULL) {
  10173. if (attr->ns == NULL) {
  10174. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10175. (!xmlStrEqual(attr->name, BAD_CAST "schemaLocation"))) {
  10176. xmlSchemaPIllegalAttrErr(pctxt,
  10177. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10178. }
  10179. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10180. xmlSchemaPIllegalAttrErr(pctxt,
  10181. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10182. }
  10183. attr = attr->next;
  10184. }
  10185. xmlSchemaPValAttrID(pctxt, node, BAD_CAST "id");
  10186. /*
  10187. * Preliminary step, extract the URI-Reference and make an URI
  10188. * from the base.
  10189. */
  10190. /*
  10191. * Attribute "schemaLocation" is mandatory.
  10192. */
  10193. attr = xmlSchemaGetPropNode(node, "schemaLocation");
  10194. if (attr != NULL) {
  10195. xmlChar *base = NULL;
  10196. xmlChar *uri = NULL;
  10197. if (xmlSchemaPValAttrNode(pctxt, NULL, attr,
  10198. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYURI),
  10199. (const xmlChar **) schemaLocation) != 0)
  10200. goto exit_error;
  10201. base = xmlNodeGetBase(node->doc, node);
  10202. if (base == NULL) {
  10203. uri = xmlBuildURI(*schemaLocation, node->doc->URL);
  10204. } else {
  10205. uri = xmlBuildURI(*schemaLocation, base);
  10206. xmlFree(base);
  10207. }
  10208. if (uri == NULL) {
  10209. PERROR_INT("xmlSchemaParseIncludeOrRedefine",
  10210. "could not build an URI from the schemaLocation")
  10211. goto exit_failure;
  10212. }
  10213. (*schemaLocation) = (xmlChar *) xmlDictLookup(pctxt->dict, uri, -1);
  10214. xmlFree(uri);
  10215. } else {
  10216. xmlSchemaPMissingAttrErr(pctxt,
  10217. XML_SCHEMAP_S4S_ATTR_MISSING,
  10218. NULL, node, "schemaLocation", NULL);
  10219. goto exit_error;
  10220. }
  10221. /*
  10222. * Report self-inclusion and self-redefinition.
  10223. */
  10224. if (xmlStrEqual(*schemaLocation, pctxt->URL)) {
  10225. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10226. xmlSchemaPCustomErr(pctxt,
  10227. XML_SCHEMAP_SRC_REDEFINE,
  10228. NULL, node,
  10229. "The schema document '%s' cannot redefine itself.",
  10230. *schemaLocation);
  10231. } else {
  10232. xmlSchemaPCustomErr(pctxt,
  10233. XML_SCHEMAP_SRC_INCLUDE,
  10234. NULL, node,
  10235. "The schema document '%s' cannot include itself.",
  10236. *schemaLocation);
  10237. }
  10238. goto exit_error;
  10239. }
  10240. return(0);
  10241. exit_error:
  10242. return(pctxt->err);
  10243. exit_failure:
  10244. return(-1);
  10245. }
  10246. static int
  10247. xmlSchemaParseIncludeOrRedefine(xmlSchemaParserCtxtPtr pctxt,
  10248. xmlSchemaPtr schema,
  10249. xmlNodePtr node,
  10250. int type)
  10251. {
  10252. xmlNodePtr child = NULL;
  10253. const xmlChar *schemaLocation = NULL;
  10254. int res = 0; /* hasRedefinitions = 0 */
  10255. int isChameleon = 0, wasChameleon = 0;
  10256. xmlSchemaBucketPtr bucket = NULL;
  10257. if ((pctxt == NULL) || (schema == NULL) || (node == NULL))
  10258. return (-1);
  10259. /*
  10260. * Parse attributes. Note that the returned schemaLocation will
  10261. * be already converted to an absolute URI.
  10262. */
  10263. res = xmlSchemaParseIncludeOrRedefineAttrs(pctxt, schema,
  10264. node, (xmlChar **) (&schemaLocation), type);
  10265. if (res != 0)
  10266. return(res);
  10267. /*
  10268. * Load and add the schema document.
  10269. */
  10270. res = xmlSchemaAddSchemaDoc(pctxt, type, schemaLocation, NULL,
  10271. NULL, 0, node, pctxt->targetNamespace, NULL, &bucket);
  10272. if (res != 0)
  10273. return(res);
  10274. /*
  10275. * If we get no schema bucket back, then this means that the schema
  10276. * document could not be located or was broken XML or was not
  10277. * a schema document.
  10278. */
  10279. if ((bucket == NULL) || (bucket->doc == NULL)) {
  10280. if (type == XML_SCHEMA_SCHEMA_INCLUDE) {
  10281. /*
  10282. * WARNING for <include>:
  10283. * We will raise an error if the schema cannot be located
  10284. * for inclusions, since the that was the feedback from the
  10285. * schema people. I.e. the following spec piece will *not* be
  10286. * satisfied:
  10287. * SPEC src-include: "It is not an error for the `actual value` of the
  10288. * schemaLocation [attribute] to fail to resolve it all, in which
  10289. * case no corresponding inclusion is performed.
  10290. * So do we need a warning report here?"
  10291. */
  10292. res = XML_SCHEMAP_SRC_INCLUDE;
  10293. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10294. node, NULL,
  10295. "Failed to load the document '%s' for inclusion",
  10296. schemaLocation, NULL);
  10297. } else {
  10298. /*
  10299. * NOTE: This was changed to raise an error even if no redefinitions
  10300. * are specified.
  10301. *
  10302. * SPEC src-redefine (1)
  10303. * "If there are any element information items among the [children]
  10304. * other than <annotation> then the `actual value` of the
  10305. * schemaLocation [attribute] must successfully resolve."
  10306. * TODO: Ask the WG if a the location has always to resolve
  10307. * here as well!
  10308. */
  10309. res = XML_SCHEMAP_SRC_REDEFINE;
  10310. xmlSchemaCustomErr(ACTXT_CAST pctxt, res,
  10311. node, NULL,
  10312. "Failed to load the document '%s' for redefinition",
  10313. schemaLocation, NULL);
  10314. }
  10315. } else {
  10316. /*
  10317. * Check targetNamespace sanity before parsing the new schema.
  10318. * TODO: Note that we won't check further content if the
  10319. * targetNamespace was bad.
  10320. */
  10321. if (bucket->origTargetNamespace != NULL) {
  10322. /*
  10323. * SPEC src-include (2.1)
  10324. * "SII has a targetNamespace [attribute], and its `actual
  10325. * value` is identical to the `actual value` of the targetNamespace
  10326. * [attribute] of SII' (which must have such an [attribute])."
  10327. */
  10328. if (pctxt->targetNamespace == NULL) {
  10329. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10330. XML_SCHEMAP_SRC_INCLUDE,
  10331. node, NULL,
  10332. "The target namespace of the included/redefined schema "
  10333. "'%s' has to be absent, since the including/redefining "
  10334. "schema has no target namespace",
  10335. schemaLocation, NULL);
  10336. goto exit_error;
  10337. } else if (!xmlStrEqual(bucket->origTargetNamespace,
  10338. pctxt->targetNamespace)) {
  10339. /* TODO: Change error function. */
  10340. xmlSchemaPCustomErrExt(pctxt,
  10341. XML_SCHEMAP_SRC_INCLUDE,
  10342. NULL, node,
  10343. "The target namespace '%s' of the included/redefined "
  10344. "schema '%s' differs from '%s' of the "
  10345. "including/redefining schema",
  10346. bucket->origTargetNamespace, schemaLocation,
  10347. pctxt->targetNamespace);
  10348. goto exit_error;
  10349. }
  10350. } else if (pctxt->targetNamespace != NULL) {
  10351. /*
  10352. * Chameleons: the original target namespace will
  10353. * differ from the resulting namespace.
  10354. */
  10355. isChameleon = 1;
  10356. if (bucket->parsed &&
  10357. bucket->origTargetNamespace != NULL) {
  10358. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  10359. XML_SCHEMAP_SRC_INCLUDE,
  10360. node, NULL,
  10361. "The target namespace of the included/redefined schema "
  10362. "'%s' has to be absent or the same as the "
  10363. "including/redefining schema's target namespace",
  10364. schemaLocation, NULL);
  10365. goto exit_error;
  10366. }
  10367. bucket->targetNamespace = pctxt->targetNamespace;
  10368. }
  10369. }
  10370. /*
  10371. * Parse the schema.
  10372. */
  10373. if (bucket && (!bucket->parsed) && (bucket->doc != NULL)) {
  10374. if (isChameleon) {
  10375. /* TODO: Get rid of this flag on the schema itself. */
  10376. if ((schema->flags & XML_SCHEMAS_INCLUDING_CONVERT_NS) == 0) {
  10377. schema->flags |= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10378. } else
  10379. wasChameleon = 1;
  10380. }
  10381. xmlSchemaParseNewDoc(pctxt, schema, bucket);
  10382. /* Restore chameleon flag. */
  10383. if (isChameleon && (!wasChameleon))
  10384. schema->flags ^= XML_SCHEMAS_INCLUDING_CONVERT_NS;
  10385. }
  10386. /*
  10387. * And now for the children...
  10388. */
  10389. child = node->children;
  10390. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10391. /*
  10392. * Parse (simpleType | complexType | group | attributeGroup))*
  10393. */
  10394. pctxt->redefined = bucket;
  10395. /*
  10396. * How to proceed if the redefined schema was not located?
  10397. */
  10398. pctxt->isRedefine = 1;
  10399. while (IS_SCHEMA(child, "annotation") ||
  10400. IS_SCHEMA(child, "simpleType") ||
  10401. IS_SCHEMA(child, "complexType") ||
  10402. IS_SCHEMA(child, "group") ||
  10403. IS_SCHEMA(child, "attributeGroup")) {
  10404. if (IS_SCHEMA(child, "annotation")) {
  10405. /*
  10406. * TODO: discard or not?
  10407. */
  10408. } else if (IS_SCHEMA(child, "simpleType")) {
  10409. xmlSchemaParseSimpleType(pctxt, schema, child, 1);
  10410. } else if (IS_SCHEMA(child, "complexType")) {
  10411. xmlSchemaParseComplexType(pctxt, schema, child, 1);
  10412. /* hasRedefinitions = 1; */
  10413. } else if (IS_SCHEMA(child, "group")) {
  10414. /* hasRedefinitions = 1; */
  10415. xmlSchemaParseModelGroupDefinition(pctxt,
  10416. schema, child);
  10417. } else if (IS_SCHEMA(child, "attributeGroup")) {
  10418. /* hasRedefinitions = 1; */
  10419. xmlSchemaParseAttributeGroupDefinition(pctxt, schema,
  10420. child);
  10421. }
  10422. child = child->next;
  10423. }
  10424. pctxt->redefined = NULL;
  10425. pctxt->isRedefine = 0;
  10426. } else {
  10427. if (IS_SCHEMA(child, "annotation")) {
  10428. /*
  10429. * TODO: discard or not?
  10430. */
  10431. child = child->next;
  10432. }
  10433. }
  10434. if (child != NULL) {
  10435. res = XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED;
  10436. if (type == XML_SCHEMA_SCHEMA_REDEFINE) {
  10437. xmlSchemaPContentErr(pctxt, res,
  10438. NULL, node, child, NULL,
  10439. "(annotation | (simpleType | complexType | group | attributeGroup))*");
  10440. } else {
  10441. xmlSchemaPContentErr(pctxt, res,
  10442. NULL, node, child, NULL,
  10443. "(annotation?)");
  10444. }
  10445. }
  10446. return(res);
  10447. exit_error:
  10448. return(pctxt->err);
  10449. }
  10450. static int
  10451. xmlSchemaParseRedefine(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10452. xmlNodePtr node)
  10453. {
  10454. int res;
  10455. #ifndef ENABLE_REDEFINE
  10456. TODO
  10457. return(0);
  10458. #endif
  10459. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10460. XML_SCHEMA_SCHEMA_REDEFINE);
  10461. if (res != 0)
  10462. return(res);
  10463. return(0);
  10464. }
  10465. static int
  10466. xmlSchemaParseInclude(xmlSchemaParserCtxtPtr pctxt, xmlSchemaPtr schema,
  10467. xmlNodePtr node)
  10468. {
  10469. int res;
  10470. res = xmlSchemaParseIncludeOrRedefine(pctxt, schema, node,
  10471. XML_SCHEMA_SCHEMA_INCLUDE);
  10472. if (res != 0)
  10473. return(res);
  10474. return(0);
  10475. }
  10476. /**
  10477. * xmlSchemaParseModelGroup:
  10478. * @ctxt: a schema validation context
  10479. * @schema: the schema being built
  10480. * @node: a subtree containing XML Schema informations
  10481. * @type: the "compositor" type
  10482. * @particleNeeded: if a a model group with a particle
  10483. *
  10484. * parse a XML schema Sequence definition.
  10485. * Applies parts of:
  10486. * Schema Representation Constraint:
  10487. * Redefinition Constraints and Semantics (src-redefine)
  10488. * (6.1), (6.1.1), (6.1.2)
  10489. *
  10490. * Schema Component Constraint:
  10491. * All Group Limited (cos-all-limited) (2)
  10492. * TODO: Actually this should go to component-level checks,
  10493. * but is done here due to performance. Move it to an other layer
  10494. * is schema construction via an API is implemented.
  10495. *
  10496. * *WARNING* this interface is highly subject to change
  10497. *
  10498. * Returns -1 in case of error, 0 if the declaration is improper and
  10499. * 1 in case of success.
  10500. */
  10501. static xmlSchemaTreeItemPtr
  10502. xmlSchemaParseModelGroup(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10503. xmlNodePtr node, xmlSchemaTypeType type,
  10504. int withParticle)
  10505. {
  10506. xmlSchemaModelGroupPtr item;
  10507. xmlSchemaParticlePtr particle = NULL;
  10508. xmlNodePtr child = NULL;
  10509. xmlAttrPtr attr;
  10510. int min = 1, max = 1, isElemRef, hasRefs = 0;
  10511. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10512. return (NULL);
  10513. /*
  10514. * Create a model group with the given compositor.
  10515. */
  10516. item = xmlSchemaAddModelGroup(ctxt, schema, type, node);
  10517. if (item == NULL)
  10518. return (NULL);
  10519. if (withParticle) {
  10520. if (type == XML_SCHEMA_TYPE_ALL) {
  10521. min = xmlGetMinOccurs(ctxt, node, 0, 1, 1, "(0 | 1)");
  10522. max = xmlGetMaxOccurs(ctxt, node, 1, 1, 1, "1");
  10523. } else {
  10524. /* choice + sequence */
  10525. min = xmlGetMinOccurs(ctxt, node, 0, -1, 1, "xs:nonNegativeInteger");
  10526. max = xmlGetMaxOccurs(ctxt, node, 0, UNBOUNDED, 1,
  10527. "(xs:nonNegativeInteger | unbounded)");
  10528. }
  10529. xmlSchemaPCheckParticleCorrect_2(ctxt, NULL, node, min, max);
  10530. /*
  10531. * Create a particle
  10532. */
  10533. particle = xmlSchemaAddParticle(ctxt, node, min, max);
  10534. if (particle == NULL)
  10535. return (NULL);
  10536. particle->children = (xmlSchemaTreeItemPtr) item;
  10537. /*
  10538. * Check for illegal attributes.
  10539. */
  10540. attr = node->properties;
  10541. while (attr != NULL) {
  10542. if (attr->ns == NULL) {
  10543. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10544. (!xmlStrEqual(attr->name, BAD_CAST "maxOccurs")) &&
  10545. (!xmlStrEqual(attr->name, BAD_CAST "minOccurs"))) {
  10546. xmlSchemaPIllegalAttrErr(ctxt,
  10547. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10548. }
  10549. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10550. xmlSchemaPIllegalAttrErr(ctxt,
  10551. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10552. }
  10553. attr = attr->next;
  10554. }
  10555. } else {
  10556. /*
  10557. * Check for illegal attributes.
  10558. */
  10559. attr = node->properties;
  10560. while (attr != NULL) {
  10561. if (attr->ns == NULL) {
  10562. if (!xmlStrEqual(attr->name, BAD_CAST "id")) {
  10563. xmlSchemaPIllegalAttrErr(ctxt,
  10564. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10565. }
  10566. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10567. xmlSchemaPIllegalAttrErr(ctxt,
  10568. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10569. }
  10570. attr = attr->next;
  10571. }
  10572. }
  10573. /*
  10574. * Extract and validate attributes.
  10575. */
  10576. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10577. /*
  10578. * And now for the children...
  10579. */
  10580. child = node->children;
  10581. if (IS_SCHEMA(child, "annotation")) {
  10582. item->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  10583. child = child->next;
  10584. }
  10585. if (type == XML_SCHEMA_TYPE_ALL) {
  10586. xmlSchemaParticlePtr part, last = NULL;
  10587. while (IS_SCHEMA(child, "element")) {
  10588. part = (xmlSchemaParticlePtr) xmlSchemaParseElement(ctxt,
  10589. schema, child, &isElemRef, 0);
  10590. /*
  10591. * SPEC cos-all-limited (2)
  10592. * "The {max occurs} of all the particles in the {particles}
  10593. * of the ('all') group must be 0 or 1.
  10594. */
  10595. if (part != NULL) {
  10596. if (isElemRef)
  10597. hasRefs++;
  10598. if (part->minOccurs > 1) {
  10599. xmlSchemaPCustomErr(ctxt,
  10600. XML_SCHEMAP_COS_ALL_LIMITED,
  10601. NULL, child,
  10602. "Invalid value for minOccurs (must be 0 or 1)",
  10603. NULL);
  10604. /* Reset to 1. */
  10605. part->minOccurs = 1;
  10606. }
  10607. if (part->maxOccurs > 1) {
  10608. xmlSchemaPCustomErr(ctxt,
  10609. XML_SCHEMAP_COS_ALL_LIMITED,
  10610. NULL, child,
  10611. "Invalid value for maxOccurs (must be 0 or 1)",
  10612. NULL);
  10613. /* Reset to 1. */
  10614. part->maxOccurs = 1;
  10615. }
  10616. if (last == NULL)
  10617. item->children = (xmlSchemaTreeItemPtr) part;
  10618. else
  10619. last->next = (xmlSchemaTreeItemPtr) part;
  10620. last = part;
  10621. }
  10622. child = child->next;
  10623. }
  10624. if (child != NULL) {
  10625. xmlSchemaPContentErr(ctxt,
  10626. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10627. NULL, node, child, NULL,
  10628. "(annotation?, (annotation?, element*)");
  10629. }
  10630. } else {
  10631. /* choice + sequence */
  10632. xmlSchemaTreeItemPtr part = NULL, last = NULL;
  10633. while ((IS_SCHEMA(child, "element")) ||
  10634. (IS_SCHEMA(child, "group")) ||
  10635. (IS_SCHEMA(child, "any")) ||
  10636. (IS_SCHEMA(child, "choice")) ||
  10637. (IS_SCHEMA(child, "sequence"))) {
  10638. if (IS_SCHEMA(child, "element")) {
  10639. part = (xmlSchemaTreeItemPtr)
  10640. xmlSchemaParseElement(ctxt, schema, child, &isElemRef, 0);
  10641. if (part && isElemRef)
  10642. hasRefs++;
  10643. } else if (IS_SCHEMA(child, "group")) {
  10644. part =
  10645. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10646. if (part != NULL)
  10647. hasRefs++;
  10648. /*
  10649. * Handle redefinitions.
  10650. */
  10651. if (ctxt->isRedefine && ctxt->redef &&
  10652. (ctxt->redef->item->type == XML_SCHEMA_TYPE_GROUP) &&
  10653. part && part->children)
  10654. {
  10655. if ((xmlSchemaGetQNameRefName(part->children) ==
  10656. ctxt->redef->refName) &&
  10657. (xmlSchemaGetQNameRefTargetNs(part->children) ==
  10658. ctxt->redef->refTargetNs))
  10659. {
  10660. /*
  10661. * SPEC src-redefine:
  10662. * (6.1) "If it has a <group> among its contents at
  10663. * some level the `actual value` of whose ref
  10664. * [attribute] is the same as the `actual value` of
  10665. * its own name attribute plus target namespace, then
  10666. * all of the following must be true:"
  10667. * (6.1.1) "It must have exactly one such group."
  10668. */
  10669. if (ctxt->redefCounter != 0) {
  10670. xmlChar *str = NULL;
  10671. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10672. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10673. "The redefining model group definition "
  10674. "'%s' must not contain more than one "
  10675. "reference to the redefined definition",
  10676. xmlSchemaFormatQName(&str,
  10677. ctxt->redef->refTargetNs,
  10678. ctxt->redef->refName),
  10679. NULL);
  10680. FREE_AND_NULL(str)
  10681. part = NULL;
  10682. } else if (((WXS_PARTICLE(part))->minOccurs != 1) ||
  10683. ((WXS_PARTICLE(part))->maxOccurs != 1))
  10684. {
  10685. xmlChar *str = NULL;
  10686. /*
  10687. * SPEC src-redefine:
  10688. * (6.1.2) "The `actual value` of both that
  10689. * group's minOccurs and maxOccurs [attribute]
  10690. * must be 1 (or `absent`).
  10691. */
  10692. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  10693. XML_SCHEMAP_SRC_REDEFINE, child, NULL,
  10694. "The redefining model group definition "
  10695. "'%s' must not contain a reference to the "
  10696. "redefined definition with a "
  10697. "maxOccurs/minOccurs other than 1",
  10698. xmlSchemaFormatQName(&str,
  10699. ctxt->redef->refTargetNs,
  10700. ctxt->redef->refName),
  10701. NULL);
  10702. FREE_AND_NULL(str)
  10703. part = NULL;
  10704. }
  10705. ctxt->redef->reference = WXS_BASIC_CAST part;
  10706. ctxt->redefCounter++;
  10707. }
  10708. }
  10709. } else if (IS_SCHEMA(child, "any")) {
  10710. part = (xmlSchemaTreeItemPtr)
  10711. xmlSchemaParseAny(ctxt, schema, child);
  10712. } else if (IS_SCHEMA(child, "choice")) {
  10713. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10714. XML_SCHEMA_TYPE_CHOICE, 1);
  10715. } else if (IS_SCHEMA(child, "sequence")) {
  10716. part = xmlSchemaParseModelGroup(ctxt, schema, child,
  10717. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10718. }
  10719. if (part != NULL) {
  10720. if (last == NULL)
  10721. item->children = part;
  10722. else
  10723. last->next = part;
  10724. last = part;
  10725. }
  10726. child = child->next;
  10727. }
  10728. if (child != NULL) {
  10729. xmlSchemaPContentErr(ctxt,
  10730. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  10731. NULL, node, child, NULL,
  10732. "(annotation?, (element | group | choice | sequence | any)*)");
  10733. }
  10734. }
  10735. if ((max == 0) && (min == 0))
  10736. return (NULL);
  10737. if (hasRefs) {
  10738. /*
  10739. * We need to resolve references.
  10740. */
  10741. WXS_ADD_PENDING(ctxt, item);
  10742. }
  10743. if (withParticle)
  10744. return ((xmlSchemaTreeItemPtr) particle);
  10745. else
  10746. return ((xmlSchemaTreeItemPtr) item);
  10747. }
  10748. /**
  10749. * xmlSchemaParseRestriction:
  10750. * @ctxt: a schema validation context
  10751. * @schema: the schema being built
  10752. * @node: a subtree containing XML Schema informations
  10753. *
  10754. * parse a XML schema Restriction definition
  10755. * *WARNING* this interface is highly subject to change
  10756. *
  10757. * Returns the type definition or NULL in case of error
  10758. */
  10759. static xmlSchemaTypePtr
  10760. xmlSchemaParseRestriction(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  10761. xmlNodePtr node, xmlSchemaTypeType parentType)
  10762. {
  10763. xmlSchemaTypePtr type;
  10764. xmlNodePtr child = NULL;
  10765. xmlAttrPtr attr;
  10766. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  10767. return (NULL);
  10768. /* Not a component, don't create it. */
  10769. type = ctxt->ctxtType;
  10770. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  10771. /*
  10772. * Check for illegal attributes.
  10773. */
  10774. attr = node->properties;
  10775. while (attr != NULL) {
  10776. if (attr->ns == NULL) {
  10777. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  10778. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  10779. xmlSchemaPIllegalAttrErr(ctxt,
  10780. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10781. }
  10782. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  10783. xmlSchemaPIllegalAttrErr(ctxt,
  10784. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  10785. }
  10786. attr = attr->next;
  10787. }
  10788. /*
  10789. * Extract and validate attributes.
  10790. */
  10791. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  10792. /*
  10793. * Attribute
  10794. */
  10795. /*
  10796. * Extract the base type. The "base" attribute is mandatory if inside
  10797. * a complex type or if redefining.
  10798. *
  10799. * SPEC (1.2) "...otherwise (<restriction> has no <simpleType> "
  10800. * among its [children]), the simple type definition which is
  10801. * the {content type} of the type definition `resolved` to by
  10802. * the `actual value` of the base [attribute]"
  10803. */
  10804. if (xmlSchemaPValAttrQName(ctxt, schema, NULL, node, "base",
  10805. &(type->baseNs), &(type->base)) == 0)
  10806. {
  10807. if ((type->base == NULL) && (type->type == XML_SCHEMA_TYPE_COMPLEX)) {
  10808. xmlSchemaPMissingAttrErr(ctxt,
  10809. XML_SCHEMAP_S4S_ATTR_MISSING,
  10810. NULL, node, "base", NULL);
  10811. } else if ((ctxt->isRedefine) &&
  10812. (type->flags & XML_SCHEMAS_TYPE_GLOBAL))
  10813. {
  10814. if (type->base == NULL) {
  10815. xmlSchemaPMissingAttrErr(ctxt,
  10816. XML_SCHEMAP_S4S_ATTR_MISSING,
  10817. NULL, node, "base", NULL);
  10818. } else if ((! xmlStrEqual(type->base, type->name)) ||
  10819. (! xmlStrEqual(type->baseNs, type->targetNamespace)))
  10820. {
  10821. xmlChar *str1 = NULL, *str2 = NULL;
  10822. /*
  10823. * REDEFINE: SPEC src-redefine (5)
  10824. * "Within the [children], each <simpleType> must have a
  10825. * <restriction> among its [children] ... the `actual value` of
  10826. * whose base [attribute] must be the same as the `actual value`
  10827. * of its own name attribute plus target namespace;"
  10828. */
  10829. xmlSchemaPCustomErrExt(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  10830. NULL, node, "This is a redefinition, but the QName "
  10831. "value '%s' of the 'base' attribute does not match the "
  10832. "type's designation '%s'",
  10833. xmlSchemaFormatQName(&str1, type->baseNs, type->base),
  10834. xmlSchemaFormatQName(&str2, type->targetNamespace,
  10835. type->name), NULL);
  10836. FREE_AND_NULL(str1);
  10837. FREE_AND_NULL(str2);
  10838. /* Avoid confusion and erase the values. */
  10839. type->base = NULL;
  10840. type->baseNs = NULL;
  10841. }
  10842. }
  10843. }
  10844. /*
  10845. * And now for the children...
  10846. */
  10847. child = node->children;
  10848. if (IS_SCHEMA(child, "annotation")) {
  10849. /*
  10850. * Add the annotation to the simple type ancestor.
  10851. */
  10852. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  10853. xmlSchemaParseAnnotation(ctxt, child, 1));
  10854. child = child->next;
  10855. }
  10856. if (parentType == XML_SCHEMA_TYPE_SIMPLE) {
  10857. /*
  10858. * Corresponds to <simpleType><restriction><simpleType>.
  10859. */
  10860. if (IS_SCHEMA(child, "simpleType")) {
  10861. if (type->base != NULL) {
  10862. /*
  10863. * src-restriction-base-or-simpleType
  10864. * Either the base [attribute] or the simpleType [child] of the
  10865. * <restriction> element must be present, but not both.
  10866. */
  10867. xmlSchemaPContentErr(ctxt,
  10868. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10869. NULL, node, child,
  10870. "The attribute 'base' and the <simpleType> child are "
  10871. "mutually exclusive", NULL);
  10872. } else {
  10873. type->baseType = (xmlSchemaTypePtr)
  10874. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10875. }
  10876. child = child->next;
  10877. } else if (type->base == NULL) {
  10878. xmlSchemaPContentErr(ctxt,
  10879. XML_SCHEMAP_SRC_RESTRICTION_BASE_OR_SIMPLETYPE,
  10880. NULL, node, child,
  10881. "Either the attribute 'base' or a <simpleType> child "
  10882. "must be present", NULL);
  10883. }
  10884. } else if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  10885. /*
  10886. * Corresponds to <complexType><complexContent><restriction>...
  10887. * followed by:
  10888. *
  10889. * Model groups <all>, <choice> and <sequence>.
  10890. */
  10891. if (IS_SCHEMA(child, "all")) {
  10892. type->subtypes = (xmlSchemaTypePtr)
  10893. xmlSchemaParseModelGroup(ctxt, schema, child,
  10894. XML_SCHEMA_TYPE_ALL, 1);
  10895. child = child->next;
  10896. } else if (IS_SCHEMA(child, "choice")) {
  10897. type->subtypes = (xmlSchemaTypePtr)
  10898. xmlSchemaParseModelGroup(ctxt,
  10899. schema, child, XML_SCHEMA_TYPE_CHOICE, 1);
  10900. child = child->next;
  10901. } else if (IS_SCHEMA(child, "sequence")) {
  10902. type->subtypes = (xmlSchemaTypePtr)
  10903. xmlSchemaParseModelGroup(ctxt, schema, child,
  10904. XML_SCHEMA_TYPE_SEQUENCE, 1);
  10905. child = child->next;
  10906. /*
  10907. * Model group reference <group>.
  10908. */
  10909. } else if (IS_SCHEMA(child, "group")) {
  10910. type->subtypes = (xmlSchemaTypePtr)
  10911. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  10912. /*
  10913. * Note that the reference will be resolved in
  10914. * xmlSchemaResolveTypeReferences();
  10915. */
  10916. child = child->next;
  10917. }
  10918. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  10919. /*
  10920. * Corresponds to <complexType><simpleContent><restriction>...
  10921. *
  10922. * "1.1 the simple type definition corresponding to the <simpleType>
  10923. * among the [children] of <restriction> if there is one;"
  10924. */
  10925. if (IS_SCHEMA(child, "simpleType")) {
  10926. /*
  10927. * We will store the to-be-restricted simple type in
  10928. * type->contentTypeDef *temporarily*.
  10929. */
  10930. type->contentTypeDef = (xmlSchemaTypePtr)
  10931. xmlSchemaParseSimpleType(ctxt, schema, child, 0);
  10932. if ( type->contentTypeDef == NULL)
  10933. return (NULL);
  10934. child = child->next;
  10935. }
  10936. }
  10937. if ((parentType == XML_SCHEMA_TYPE_SIMPLE) ||
  10938. (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT)) {
  10939. xmlSchemaFacetPtr facet, lastfacet = NULL;
  10940. /*
  10941. * Corresponds to <complexType><simpleContent><restriction>...
  10942. * <simpleType><restriction>...
  10943. */
  10944. /*
  10945. * Add the facets to the simple type ancestor.
  10946. */
  10947. /*
  10948. * TODO: Datatypes: 4.1.3 Constraints on XML Representation of
  10949. * Simple Type Definition Schema Representation Constraint:
  10950. * *Single Facet Value*
  10951. */
  10952. while ((IS_SCHEMA(child, "minInclusive")) ||
  10953. (IS_SCHEMA(child, "minExclusive")) ||
  10954. (IS_SCHEMA(child, "maxInclusive")) ||
  10955. (IS_SCHEMA(child, "maxExclusive")) ||
  10956. (IS_SCHEMA(child, "totalDigits")) ||
  10957. (IS_SCHEMA(child, "fractionDigits")) ||
  10958. (IS_SCHEMA(child, "pattern")) ||
  10959. (IS_SCHEMA(child, "enumeration")) ||
  10960. (IS_SCHEMA(child, "whiteSpace")) ||
  10961. (IS_SCHEMA(child, "length")) ||
  10962. (IS_SCHEMA(child, "maxLength")) ||
  10963. (IS_SCHEMA(child, "minLength"))) {
  10964. facet = xmlSchemaParseFacet(ctxt, schema, child);
  10965. if (facet != NULL) {
  10966. if (lastfacet == NULL)
  10967. type->facets = facet;
  10968. else
  10969. lastfacet->next = facet;
  10970. lastfacet = facet;
  10971. lastfacet->next = NULL;
  10972. }
  10973. child = child->next;
  10974. }
  10975. /*
  10976. * Create links for derivation and validation.
  10977. */
  10978. if (type->facets != NULL) {
  10979. xmlSchemaFacetLinkPtr facetLink, lastFacetLink = NULL;
  10980. facet = type->facets;
  10981. do {
  10982. facetLink = (xmlSchemaFacetLinkPtr)
  10983. xmlMalloc(sizeof(xmlSchemaFacetLink));
  10984. if (facetLink == NULL) {
  10985. xmlSchemaPErrMemory(ctxt, "allocating a facet link", NULL);
  10986. xmlFree(facetLink);
  10987. return (NULL);
  10988. }
  10989. facetLink->facet = facet;
  10990. facetLink->next = NULL;
  10991. if (lastFacetLink == NULL)
  10992. type->facetSet = facetLink;
  10993. else
  10994. lastFacetLink->next = facetLink;
  10995. lastFacetLink = facetLink;
  10996. facet = facet->next;
  10997. } while (facet != NULL);
  10998. }
  10999. }
  11000. if (type->type == XML_SCHEMA_TYPE_COMPLEX) {
  11001. /*
  11002. * Attribute uses/declarations.
  11003. */
  11004. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11005. (xmlSchemaItemListPtr *) &(type->attrUses),
  11006. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11007. return(NULL);
  11008. /*
  11009. * Attribute wildcard.
  11010. */
  11011. if (IS_SCHEMA(child, "anyAttribute")) {
  11012. type->attributeWildcard =
  11013. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11014. child = child->next;
  11015. }
  11016. }
  11017. if (child != NULL) {
  11018. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11019. xmlSchemaPContentErr(ctxt,
  11020. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11021. NULL, node, child, NULL,
  11022. "annotation?, (group | all | choice | sequence)?, "
  11023. "((attribute | attributeGroup)*, anyAttribute?))");
  11024. } else if (parentType == XML_SCHEMA_TYPE_SIMPLE_CONTENT) {
  11025. xmlSchemaPContentErr(ctxt,
  11026. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11027. NULL, node, child, NULL,
  11028. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  11029. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  11030. "length | minLength | maxLength | enumeration | whiteSpace | "
  11031. "pattern)*)?, ((attribute | attributeGroup)*, anyAttribute?))");
  11032. } else {
  11033. /* Simple type */
  11034. xmlSchemaPContentErr(ctxt,
  11035. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11036. NULL, node, child, NULL,
  11037. "(annotation?, (simpleType?, (minExclusive | minInclusive | "
  11038. "maxExclusive | maxInclusive | totalDigits | fractionDigits | "
  11039. "length | minLength | maxLength | enumeration | whiteSpace | "
  11040. "pattern)*))");
  11041. }
  11042. }
  11043. return (NULL);
  11044. }
  11045. /**
  11046. * xmlSchemaParseExtension:
  11047. * @ctxt: a schema validation context
  11048. * @schema: the schema being built
  11049. * @node: a subtree containing XML Schema informations
  11050. *
  11051. * Parses an <extension>, which is found inside a
  11052. * <simpleContent> or <complexContent>.
  11053. * *WARNING* this interface is highly subject to change.
  11054. *
  11055. * TODO: Returns the type definition or NULL in case of error
  11056. */
  11057. static xmlSchemaTypePtr
  11058. xmlSchemaParseExtension(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11059. xmlNodePtr node, xmlSchemaTypeType parentType)
  11060. {
  11061. xmlSchemaTypePtr type;
  11062. xmlNodePtr child = NULL;
  11063. xmlAttrPtr attr;
  11064. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11065. return (NULL);
  11066. /* Not a component, don't create it. */
  11067. type = ctxt->ctxtType;
  11068. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_EXTENSION;
  11069. /*
  11070. * Check for illegal attributes.
  11071. */
  11072. attr = node->properties;
  11073. while (attr != NULL) {
  11074. if (attr->ns == NULL) {
  11075. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11076. (!xmlStrEqual(attr->name, BAD_CAST "base"))) {
  11077. xmlSchemaPIllegalAttrErr(ctxt,
  11078. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11079. }
  11080. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11081. xmlSchemaPIllegalAttrErr(ctxt,
  11082. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11083. }
  11084. attr = attr->next;
  11085. }
  11086. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11087. /*
  11088. * Attribute "base" - mandatory.
  11089. */
  11090. if ((xmlSchemaPValAttrQName(ctxt, schema, NULL, node,
  11091. "base", &(type->baseNs), &(type->base)) == 0) &&
  11092. (type->base == NULL)) {
  11093. xmlSchemaPMissingAttrErr(ctxt,
  11094. XML_SCHEMAP_S4S_ATTR_MISSING,
  11095. NULL, node, "base", NULL);
  11096. }
  11097. /*
  11098. * And now for the children...
  11099. */
  11100. child = node->children;
  11101. if (IS_SCHEMA(child, "annotation")) {
  11102. /*
  11103. * Add the annotation to the type ancestor.
  11104. */
  11105. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11106. xmlSchemaParseAnnotation(ctxt, child, 1));
  11107. child = child->next;
  11108. }
  11109. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11110. /*
  11111. * Corresponds to <complexType><complexContent><extension>... and:
  11112. *
  11113. * Model groups <all>, <choice>, <sequence> and <group>.
  11114. */
  11115. if (IS_SCHEMA(child, "all")) {
  11116. type->subtypes = (xmlSchemaTypePtr)
  11117. xmlSchemaParseModelGroup(ctxt, schema,
  11118. child, XML_SCHEMA_TYPE_ALL, 1);
  11119. child = child->next;
  11120. } else if (IS_SCHEMA(child, "choice")) {
  11121. type->subtypes = (xmlSchemaTypePtr)
  11122. xmlSchemaParseModelGroup(ctxt, schema,
  11123. child, XML_SCHEMA_TYPE_CHOICE, 1);
  11124. child = child->next;
  11125. } else if (IS_SCHEMA(child, "sequence")) {
  11126. type->subtypes = (xmlSchemaTypePtr)
  11127. xmlSchemaParseModelGroup(ctxt, schema,
  11128. child, XML_SCHEMA_TYPE_SEQUENCE, 1);
  11129. child = child->next;
  11130. } else if (IS_SCHEMA(child, "group")) {
  11131. type->subtypes = (xmlSchemaTypePtr)
  11132. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11133. /*
  11134. * Note that the reference will be resolved in
  11135. * xmlSchemaResolveTypeReferences();
  11136. */
  11137. child = child->next;
  11138. }
  11139. }
  11140. if (child != NULL) {
  11141. /*
  11142. * Attribute uses/declarations.
  11143. */
  11144. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11145. (xmlSchemaItemListPtr *) &(type->attrUses),
  11146. XML_SCHEMA_TYPE_EXTENSION, NULL) == -1)
  11147. return(NULL);
  11148. /*
  11149. * Attribute wildcard.
  11150. */
  11151. if (IS_SCHEMA(child, "anyAttribute")) {
  11152. ctxt->ctxtType->attributeWildcard =
  11153. xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11154. child = child->next;
  11155. }
  11156. }
  11157. if (child != NULL) {
  11158. if (parentType == XML_SCHEMA_TYPE_COMPLEX_CONTENT) {
  11159. /* Complex content extension. */
  11160. xmlSchemaPContentErr(ctxt,
  11161. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11162. NULL, node, child, NULL,
  11163. "(annotation?, ((group | all | choice | sequence)?, "
  11164. "((attribute | attributeGroup)*, anyAttribute?)))");
  11165. } else {
  11166. /* Simple content extension. */
  11167. xmlSchemaPContentErr(ctxt,
  11168. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11169. NULL, node, child, NULL,
  11170. "(annotation?, ((attribute | attributeGroup)*, "
  11171. "anyAttribute?))");
  11172. }
  11173. }
  11174. return (NULL);
  11175. }
  11176. /**
  11177. * xmlSchemaParseSimpleContent:
  11178. * @ctxt: a schema validation context
  11179. * @schema: the schema being built
  11180. * @node: a subtree containing XML Schema informations
  11181. *
  11182. * parse a XML schema SimpleContent definition
  11183. * *WARNING* this interface is highly subject to change
  11184. *
  11185. * Returns the type definition or NULL in case of error
  11186. */
  11187. static int
  11188. xmlSchemaParseSimpleContent(xmlSchemaParserCtxtPtr ctxt,
  11189. xmlSchemaPtr schema, xmlNodePtr node,
  11190. int *hasRestrictionOrExtension)
  11191. {
  11192. xmlSchemaTypePtr type;
  11193. xmlNodePtr child = NULL;
  11194. xmlAttrPtr attr;
  11195. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11196. (hasRestrictionOrExtension == NULL))
  11197. return (-1);
  11198. *hasRestrictionOrExtension = 0;
  11199. /* Not a component, don't create it. */
  11200. type = ctxt->ctxtType;
  11201. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  11202. /*
  11203. * Check for illegal attributes.
  11204. */
  11205. attr = node->properties;
  11206. while (attr != NULL) {
  11207. if (attr->ns == NULL) {
  11208. if ((!xmlStrEqual(attr->name, BAD_CAST "id"))) {
  11209. xmlSchemaPIllegalAttrErr(ctxt,
  11210. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11211. }
  11212. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11213. xmlSchemaPIllegalAttrErr(ctxt,
  11214. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11215. }
  11216. attr = attr->next;
  11217. }
  11218. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11219. /*
  11220. * And now for the children...
  11221. */
  11222. child = node->children;
  11223. if (IS_SCHEMA(child, "annotation")) {
  11224. /*
  11225. * Add the annotation to the complex type ancestor.
  11226. */
  11227. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11228. xmlSchemaParseAnnotation(ctxt, child, 1));
  11229. child = child->next;
  11230. }
  11231. if (child == NULL) {
  11232. xmlSchemaPContentErr(ctxt,
  11233. XML_SCHEMAP_S4S_ELEM_MISSING,
  11234. NULL, node, NULL, NULL,
  11235. "(annotation?, (restriction | extension))");
  11236. }
  11237. if (child == NULL) {
  11238. xmlSchemaPContentErr(ctxt,
  11239. XML_SCHEMAP_S4S_ELEM_MISSING,
  11240. NULL, node, NULL, NULL,
  11241. "(annotation?, (restriction | extension))");
  11242. }
  11243. if (IS_SCHEMA(child, "restriction")) {
  11244. xmlSchemaParseRestriction(ctxt, schema, child,
  11245. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11246. (*hasRestrictionOrExtension) = 1;
  11247. child = child->next;
  11248. } else if (IS_SCHEMA(child, "extension")) {
  11249. xmlSchemaParseExtension(ctxt, schema, child,
  11250. XML_SCHEMA_TYPE_SIMPLE_CONTENT);
  11251. (*hasRestrictionOrExtension) = 1;
  11252. child = child->next;
  11253. }
  11254. if (child != NULL) {
  11255. xmlSchemaPContentErr(ctxt,
  11256. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11257. NULL, node, child, NULL,
  11258. "(annotation?, (restriction | extension))");
  11259. }
  11260. return (0);
  11261. }
  11262. /**
  11263. * xmlSchemaParseComplexContent:
  11264. * @ctxt: a schema validation context
  11265. * @schema: the schema being built
  11266. * @node: a subtree containing XML Schema informations
  11267. *
  11268. * parse a XML schema ComplexContent definition
  11269. * *WARNING* this interface is highly subject to change
  11270. *
  11271. * Returns the type definition or NULL in case of error
  11272. */
  11273. static int
  11274. xmlSchemaParseComplexContent(xmlSchemaParserCtxtPtr ctxt,
  11275. xmlSchemaPtr schema, xmlNodePtr node,
  11276. int *hasRestrictionOrExtension)
  11277. {
  11278. xmlSchemaTypePtr type;
  11279. xmlNodePtr child = NULL;
  11280. xmlAttrPtr attr;
  11281. if ((ctxt == NULL) || (schema == NULL) || (node == NULL) ||
  11282. (hasRestrictionOrExtension == NULL))
  11283. return (-1);
  11284. *hasRestrictionOrExtension = 0;
  11285. /* Not a component, don't create it. */
  11286. type = ctxt->ctxtType;
  11287. /*
  11288. * Check for illegal attributes.
  11289. */
  11290. attr = node->properties;
  11291. while (attr != NULL) {
  11292. if (attr->ns == NULL) {
  11293. if ((!xmlStrEqual(attr->name, BAD_CAST "id")) &&
  11294. (!xmlStrEqual(attr->name, BAD_CAST "mixed")))
  11295. {
  11296. xmlSchemaPIllegalAttrErr(ctxt,
  11297. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11298. }
  11299. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11300. xmlSchemaPIllegalAttrErr(ctxt,
  11301. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11302. }
  11303. attr = attr->next;
  11304. }
  11305. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11306. /*
  11307. * Set the 'mixed' on the complex type ancestor.
  11308. */
  11309. if (xmlGetBooleanProp(ctxt, node, "mixed", 0)) {
  11310. if ((type->flags & XML_SCHEMAS_TYPE_MIXED) == 0)
  11311. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11312. }
  11313. child = node->children;
  11314. if (IS_SCHEMA(child, "annotation")) {
  11315. /*
  11316. * Add the annotation to the complex type ancestor.
  11317. */
  11318. xmlSchemaAddAnnotation((xmlSchemaAnnotItemPtr) type,
  11319. xmlSchemaParseAnnotation(ctxt, child, 1));
  11320. child = child->next;
  11321. }
  11322. if (child == NULL) {
  11323. xmlSchemaPContentErr(ctxt,
  11324. XML_SCHEMAP_S4S_ELEM_MISSING,
  11325. NULL, node, NULL,
  11326. NULL, "(annotation?, (restriction | extension))");
  11327. }
  11328. if (child == NULL) {
  11329. xmlSchemaPContentErr(ctxt,
  11330. XML_SCHEMAP_S4S_ELEM_MISSING,
  11331. NULL, node, NULL,
  11332. NULL, "(annotation?, (restriction | extension))");
  11333. }
  11334. if (IS_SCHEMA(child, "restriction")) {
  11335. xmlSchemaParseRestriction(ctxt, schema, child,
  11336. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11337. (*hasRestrictionOrExtension) = 1;
  11338. child = child->next;
  11339. } else if (IS_SCHEMA(child, "extension")) {
  11340. xmlSchemaParseExtension(ctxt, schema, child,
  11341. XML_SCHEMA_TYPE_COMPLEX_CONTENT);
  11342. (*hasRestrictionOrExtension) = 1;
  11343. child = child->next;
  11344. }
  11345. if (child != NULL) {
  11346. xmlSchemaPContentErr(ctxt,
  11347. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11348. NULL, node, child,
  11349. NULL, "(annotation?, (restriction | extension))");
  11350. }
  11351. return (0);
  11352. }
  11353. /**
  11354. * xmlSchemaParseComplexType:
  11355. * @ctxt: a schema validation context
  11356. * @schema: the schema being built
  11357. * @node: a subtree containing XML Schema informations
  11358. *
  11359. * parse a XML schema Complex Type definition
  11360. * *WARNING* this interface is highly subject to change
  11361. *
  11362. * Returns the type definition or NULL in case of error
  11363. */
  11364. static xmlSchemaTypePtr
  11365. xmlSchemaParseComplexType(xmlSchemaParserCtxtPtr ctxt, xmlSchemaPtr schema,
  11366. xmlNodePtr node, int topLevel)
  11367. {
  11368. xmlSchemaTypePtr type, ctxtType;
  11369. xmlNodePtr child = NULL;
  11370. const xmlChar *name = NULL;
  11371. xmlAttrPtr attr;
  11372. const xmlChar *attrValue;
  11373. #ifdef ENABLE_NAMED_LOCALS
  11374. char buf[40];
  11375. #endif
  11376. int final = 0, block = 0, hasRestrictionOrExtension = 0;
  11377. if ((ctxt == NULL) || (schema == NULL) || (node == NULL))
  11378. return (NULL);
  11379. ctxtType = ctxt->ctxtType;
  11380. if (topLevel) {
  11381. attr = xmlSchemaGetPropNode(node, "name");
  11382. if (attr == NULL) {
  11383. xmlSchemaPMissingAttrErr(ctxt,
  11384. XML_SCHEMAP_S4S_ATTR_MISSING, NULL, node, "name", NULL);
  11385. return (NULL);
  11386. } else if (xmlSchemaPValAttrNode(ctxt, NULL, attr,
  11387. xmlSchemaGetBuiltInType(XML_SCHEMAS_NCNAME), &name) != 0) {
  11388. return (NULL);
  11389. }
  11390. }
  11391. if (topLevel == 0) {
  11392. /*
  11393. * Parse as local complex type definition.
  11394. */
  11395. #ifdef ENABLE_NAMED_LOCALS
  11396. snprintf(buf, 39, "#CT%d", ctxt->counter++ + 1);
  11397. type = xmlSchemaAddType(ctxt, schema,
  11398. XML_SCHEMA_TYPE_COMPLEX,
  11399. xmlDictLookup(ctxt->dict, (const xmlChar *)buf, -1),
  11400. ctxt->targetNamespace, node, 0);
  11401. #else
  11402. type = xmlSchemaAddType(ctxt, schema,
  11403. XML_SCHEMA_TYPE_COMPLEX,
  11404. NULL, ctxt->targetNamespace, node, 0);
  11405. #endif
  11406. if (type == NULL)
  11407. return (NULL);
  11408. name = type->name;
  11409. type->node = node;
  11410. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11411. /*
  11412. * TODO: We need the target namespace.
  11413. */
  11414. } else {
  11415. /*
  11416. * Parse as global complex type definition.
  11417. */
  11418. type = xmlSchemaAddType(ctxt, schema,
  11419. XML_SCHEMA_TYPE_COMPLEX,
  11420. name, ctxt->targetNamespace, node, 1);
  11421. if (type == NULL)
  11422. return (NULL);
  11423. type->node = node;
  11424. type->type = XML_SCHEMA_TYPE_COMPLEX;
  11425. type->flags |= XML_SCHEMAS_TYPE_GLOBAL;
  11426. }
  11427. type->targetNamespace = ctxt->targetNamespace;
  11428. /*
  11429. * Handle attributes.
  11430. */
  11431. attr = node->properties;
  11432. while (attr != NULL) {
  11433. if (attr->ns == NULL) {
  11434. if (xmlStrEqual(attr->name, BAD_CAST "id")) {
  11435. /*
  11436. * Attribute "id".
  11437. */
  11438. xmlSchemaPValAttrID(ctxt, node, BAD_CAST "id");
  11439. } else if (xmlStrEqual(attr->name, BAD_CAST "mixed")) {
  11440. /*
  11441. * Attribute "mixed".
  11442. */
  11443. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11444. NULL, (xmlNodePtr) attr))
  11445. type->flags |= XML_SCHEMAS_TYPE_MIXED;
  11446. } else if (topLevel) {
  11447. /*
  11448. * Attributes of global complex type definitions.
  11449. */
  11450. if (xmlStrEqual(attr->name, BAD_CAST "name")) {
  11451. /* Pass. */
  11452. } else if (xmlStrEqual(attr->name, BAD_CAST "abstract")) {
  11453. /*
  11454. * Attribute "abstract".
  11455. */
  11456. if (xmlSchemaPGetBoolNodeValue(ctxt,
  11457. NULL, (xmlNodePtr) attr))
  11458. type->flags |= XML_SCHEMAS_TYPE_ABSTRACT;
  11459. } else if (xmlStrEqual(attr->name, BAD_CAST "final")) {
  11460. /*
  11461. * Attribute "final".
  11462. */
  11463. attrValue = xmlSchemaGetNodeContent(ctxt,
  11464. (xmlNodePtr) attr);
  11465. if (xmlSchemaPValAttrBlockFinal(attrValue,
  11466. &(type->flags),
  11467. -1,
  11468. XML_SCHEMAS_TYPE_FINAL_EXTENSION,
  11469. XML_SCHEMAS_TYPE_FINAL_RESTRICTION,
  11470. -1, -1, -1) != 0)
  11471. {
  11472. xmlSchemaPSimpleTypeErr(ctxt,
  11473. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11474. NULL, (xmlNodePtr) attr, NULL,
  11475. "(#all | List of (extension | restriction))",
  11476. attrValue, NULL, NULL, NULL);
  11477. } else
  11478. final = 1;
  11479. } else if (xmlStrEqual(attr->name, BAD_CAST "block")) {
  11480. /*
  11481. * Attribute "block".
  11482. */
  11483. attrValue = xmlSchemaGetNodeContent(ctxt,
  11484. (xmlNodePtr) attr);
  11485. if (xmlSchemaPValAttrBlockFinal(attrValue, &(type->flags),
  11486. -1,
  11487. XML_SCHEMAS_TYPE_BLOCK_EXTENSION,
  11488. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION,
  11489. -1, -1, -1) != 0) {
  11490. xmlSchemaPSimpleTypeErr(ctxt,
  11491. XML_SCHEMAP_S4S_ATTR_INVALID_VALUE,
  11492. NULL, (xmlNodePtr) attr, NULL,
  11493. "(#all | List of (extension | restriction)) ",
  11494. attrValue, NULL, NULL, NULL);
  11495. } else
  11496. block = 1;
  11497. } else {
  11498. xmlSchemaPIllegalAttrErr(ctxt,
  11499. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11500. }
  11501. } else {
  11502. xmlSchemaPIllegalAttrErr(ctxt,
  11503. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11504. }
  11505. } else if (xmlStrEqual(attr->ns->href, xmlSchemaNs)) {
  11506. xmlSchemaPIllegalAttrErr(ctxt,
  11507. XML_SCHEMAP_S4S_ATTR_NOT_ALLOWED, NULL, attr);
  11508. }
  11509. attr = attr->next;
  11510. }
  11511. if (! block) {
  11512. /*
  11513. * Apply default "block" values.
  11514. */
  11515. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_RESTRICTION)
  11516. type->flags |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  11517. if (schema->flags & XML_SCHEMAS_BLOCK_DEFAULT_EXTENSION)
  11518. type->flags |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  11519. }
  11520. if (! final) {
  11521. /*
  11522. * Apply default "block" values.
  11523. */
  11524. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_RESTRICTION)
  11525. type->flags |= XML_SCHEMAS_TYPE_FINAL_RESTRICTION;
  11526. if (schema->flags & XML_SCHEMAS_FINAL_DEFAULT_EXTENSION)
  11527. type->flags |= XML_SCHEMAS_TYPE_FINAL_EXTENSION;
  11528. }
  11529. /*
  11530. * And now for the children...
  11531. */
  11532. child = node->children;
  11533. if (IS_SCHEMA(child, "annotation")) {
  11534. type->annot = xmlSchemaParseAnnotation(ctxt, child, 1);
  11535. child = child->next;
  11536. }
  11537. ctxt->ctxtType = type;
  11538. if (IS_SCHEMA(child, "simpleContent")) {
  11539. /*
  11540. * <complexType><simpleContent>...
  11541. * 3.4.3 : 2.2
  11542. * Specifying mixed='true' when the <simpleContent>
  11543. * alternative is chosen has no effect
  11544. */
  11545. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  11546. type->flags ^= XML_SCHEMAS_TYPE_MIXED;
  11547. xmlSchemaParseSimpleContent(ctxt, schema, child,
  11548. &hasRestrictionOrExtension);
  11549. child = child->next;
  11550. } else if (IS_SCHEMA(child, "complexContent")) {
  11551. /*
  11552. * <complexType><complexContent>...
  11553. */
  11554. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  11555. xmlSchemaParseComplexContent(ctxt, schema, child,
  11556. &hasRestrictionOrExtension);
  11557. child = child->next;
  11558. } else {
  11559. /*
  11560. * E.g <complexType><sequence>... or <complexType><attribute>... etc.
  11561. *
  11562. * SPEC
  11563. * "...the third alternative (neither <simpleContent> nor
  11564. * <complexContent>) is chosen. This case is understood as shorthand
  11565. * for complex content restricting the `ur-type definition`, and the
  11566. * details of the mappings should be modified as necessary.
  11567. */
  11568. type->baseType = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  11569. type->flags |= XML_SCHEMAS_TYPE_DERIVATION_METHOD_RESTRICTION;
  11570. /*
  11571. * Parse model groups.
  11572. */
  11573. if (IS_SCHEMA(child, "all")) {
  11574. type->subtypes = (xmlSchemaTypePtr)
  11575. xmlSchemaParseModelGroup(ctxt, schema, child,
  11576. XML_SCHEMA_TYPE_ALL, 1);
  11577. child = child->next;
  11578. } else if (IS_SCHEMA(child, "choice")) {
  11579. type->subtypes = (xmlSchemaTypePtr)
  11580. xmlSchemaParseModelGroup(ctxt, schema, child,
  11581. XML_SCHEMA_TYPE_CHOICE, 1);
  11582. child = child->next;
  11583. } else if (IS_SCHEMA(child, "sequence")) {
  11584. type->subtypes = (xmlSchemaTypePtr)
  11585. xmlSchemaParseModelGroup(ctxt, schema, child,
  11586. XML_SCHEMA_TYPE_SEQUENCE, 1);
  11587. child = child->next;
  11588. } else if (IS_SCHEMA(child, "group")) {
  11589. type->subtypes = (xmlSchemaTypePtr)
  11590. xmlSchemaParseModelGroupDefRef(ctxt, schema, child);
  11591. /*
  11592. * Note that the reference will be resolved in
  11593. * xmlSchemaResolveTypeReferences();
  11594. */
  11595. child = child->next;
  11596. }
  11597. /*
  11598. * Parse attribute decls/refs.
  11599. */
  11600. if (xmlSchemaParseLocalAttributes(ctxt, schema, &child,
  11601. (xmlSchemaItemListPtr *) &(type->attrUses),
  11602. XML_SCHEMA_TYPE_RESTRICTION, NULL) == -1)
  11603. return(NULL);
  11604. /*
  11605. * Parse attribute wildcard.
  11606. */
  11607. if (IS_SCHEMA(child, "anyAttribute")) {
  11608. type->attributeWildcard = xmlSchemaParseAnyAttribute(ctxt, schema, child);
  11609. child = child->next;
  11610. }
  11611. }
  11612. if (child != NULL) {
  11613. xmlSchemaPContentErr(ctxt,
  11614. XML_SCHEMAP_S4S_ELEM_NOT_ALLOWED,
  11615. NULL, node, child,
  11616. NULL, "(annotation?, (simpleContent | complexContent | "
  11617. "((group | all | choice | sequence)?, ((attribute | "
  11618. "attributeGroup)*, anyAttribute?))))");
  11619. }
  11620. /*
  11621. * REDEFINE: SPEC src-redefine (5)
  11622. */
  11623. if (topLevel && ctxt->isRedefine && (! hasRestrictionOrExtension)) {
  11624. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_SRC_REDEFINE,
  11625. NULL, node, "This is a redefinition, thus the "
  11626. "<complexType> must have a <restriction> or <extension> "
  11627. "grand-child", NULL);
  11628. }
  11629. ctxt->ctxtType = ctxtType;
  11630. return (type);
  11631. }
  11632. /************************************************************************
  11633. * *
  11634. * Validating using Schemas *
  11635. * *
  11636. ************************************************************************/
  11637. /************************************************************************
  11638. * *
  11639. * Reading/Writing Schemas *
  11640. * *
  11641. ************************************************************************/
  11642. #if 0 /* Will be enabled if it is clear what options are needed. */
  11643. /**
  11644. * xmlSchemaParserCtxtSetOptions:
  11645. * @ctxt: a schema parser context
  11646. * @options: a combination of xmlSchemaParserOption
  11647. *
  11648. * Sets the options to be used during the parse.
  11649. *
  11650. * Returns 0 in case of success, -1 in case of an
  11651. * API error.
  11652. */
  11653. static int
  11654. xmlSchemaParserCtxtSetOptions(xmlSchemaParserCtxtPtr ctxt,
  11655. int options)
  11656. {
  11657. int i;
  11658. if (ctxt == NULL)
  11659. return (-1);
  11660. /*
  11661. * WARNING: Change the start value if adding to the
  11662. * xmlSchemaParseOption.
  11663. */
  11664. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  11665. if (options & 1<<i) {
  11666. return (-1);
  11667. }
  11668. }
  11669. ctxt->options = options;
  11670. return (0);
  11671. }
  11672. /**
  11673. * xmlSchemaValidCtxtGetOptions:
  11674. * @ctxt: a schema parser context
  11675. *
  11676. * Returns the option combination of the parser context.
  11677. */
  11678. static int
  11679. xmlSchemaParserCtxtGetOptions(xmlSchemaParserCtxtPtr ctxt)
  11680. {
  11681. if (ctxt == NULL)
  11682. return (-1);
  11683. else
  11684. return (ctxt->options);
  11685. }
  11686. #endif
  11687. /**
  11688. * xmlSchemaNewParserCtxt:
  11689. * @URL: the location of the schema
  11690. *
  11691. * Create an XML Schemas parse context for that file/resource expected
  11692. * to contain an XML Schemas file.
  11693. *
  11694. * Returns the parser context or NULL in case of error
  11695. */
  11696. xmlSchemaParserCtxtPtr
  11697. xmlSchemaNewParserCtxt(const char *URL)
  11698. {
  11699. xmlSchemaParserCtxtPtr ret;
  11700. if (URL == NULL)
  11701. return (NULL);
  11702. ret = xmlSchemaParserCtxtCreate();
  11703. if (ret == NULL)
  11704. return(NULL);
  11705. ret->dict = xmlDictCreate();
  11706. ret->URL = xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
  11707. return (ret);
  11708. }
  11709. /**
  11710. * xmlSchemaNewMemParserCtxt:
  11711. * @buffer: a pointer to a char array containing the schemas
  11712. * @size: the size of the array
  11713. *
  11714. * Create an XML Schemas parse context for that memory buffer expected
  11715. * to contain an XML Schemas file.
  11716. *
  11717. * Returns the parser context or NULL in case of error
  11718. */
  11719. xmlSchemaParserCtxtPtr
  11720. xmlSchemaNewMemParserCtxt(const char *buffer, int size)
  11721. {
  11722. xmlSchemaParserCtxtPtr ret;
  11723. if ((buffer == NULL) || (size <= 0))
  11724. return (NULL);
  11725. ret = xmlSchemaParserCtxtCreate();
  11726. if (ret == NULL)
  11727. return(NULL);
  11728. ret->buffer = buffer;
  11729. ret->size = size;
  11730. ret->dict = xmlDictCreate();
  11731. return (ret);
  11732. }
  11733. /**
  11734. * xmlSchemaNewDocParserCtxt:
  11735. * @doc: a preparsed document tree
  11736. *
  11737. * Create an XML Schemas parse context for that document.
  11738. * NB. The document may be modified during the parsing process.
  11739. *
  11740. * Returns the parser context or NULL in case of error
  11741. */
  11742. xmlSchemaParserCtxtPtr
  11743. xmlSchemaNewDocParserCtxt(xmlDocPtr doc)
  11744. {
  11745. xmlSchemaParserCtxtPtr ret;
  11746. if (doc == NULL)
  11747. return (NULL);
  11748. ret = xmlSchemaParserCtxtCreate();
  11749. if (ret == NULL)
  11750. return(NULL);
  11751. ret->doc = doc;
  11752. ret->dict = xmlDictCreate();
  11753. /* The application has responsibility for the document */
  11754. ret->preserve = 1;
  11755. return (ret);
  11756. }
  11757. /**
  11758. * xmlSchemaFreeParserCtxt:
  11759. * @ctxt: the schema parser context
  11760. *
  11761. * Free the resources associated to the schema parser context
  11762. */
  11763. void
  11764. xmlSchemaFreeParserCtxt(xmlSchemaParserCtxtPtr ctxt)
  11765. {
  11766. if (ctxt == NULL)
  11767. return;
  11768. if (ctxt->doc != NULL && !ctxt->preserve)
  11769. xmlFreeDoc(ctxt->doc);
  11770. if (ctxt->vctxt != NULL) {
  11771. xmlSchemaFreeValidCtxt(ctxt->vctxt);
  11772. }
  11773. if (ctxt->ownsConstructor && (ctxt->constructor != NULL)) {
  11774. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  11775. ctxt->constructor = NULL;
  11776. ctxt->ownsConstructor = 0;
  11777. }
  11778. if (ctxt->attrProhibs != NULL)
  11779. xmlSchemaItemListFree(ctxt->attrProhibs);
  11780. xmlDictFree(ctxt->dict);
  11781. xmlFree(ctxt);
  11782. }
  11783. /************************************************************************
  11784. * *
  11785. * Building the content models *
  11786. * *
  11787. ************************************************************************/
  11788. /**
  11789. * xmlSchemaBuildContentModelForSubstGroup:
  11790. *
  11791. * Returns 1 if nillable, 0 otherwise
  11792. */
  11793. static int
  11794. xmlSchemaBuildContentModelForSubstGroup(xmlSchemaParserCtxtPtr pctxt,
  11795. xmlSchemaParticlePtr particle, int counter, xmlAutomataStatePtr end)
  11796. {
  11797. xmlAutomataStatePtr start, tmp;
  11798. xmlSchemaElementPtr elemDecl, member;
  11799. xmlSchemaSubstGroupPtr substGroup;
  11800. int i;
  11801. int ret = 0;
  11802. elemDecl = (xmlSchemaElementPtr) particle->children;
  11803. /*
  11804. * Wrap the substitution group with a CHOICE.
  11805. */
  11806. start = pctxt->state;
  11807. if (end == NULL)
  11808. end = xmlAutomataNewState(pctxt->am);
  11809. substGroup = xmlSchemaSubstGroupGet(pctxt, elemDecl);
  11810. if (substGroup == NULL) {
  11811. xmlSchemaPErr(pctxt, WXS_ITEM_NODE(particle),
  11812. XML_SCHEMAP_INTERNAL,
  11813. "Internal error: xmlSchemaBuildContentModelForSubstGroup, "
  11814. "declaration is marked having a subst. group but none "
  11815. "available.\n", elemDecl->name, NULL);
  11816. return(0);
  11817. }
  11818. if (counter >= 0) {
  11819. /*
  11820. * NOTE that we put the declaration in, even if it's abstract.
  11821. * However, an error will be raised during *validation* if an element
  11822. * information item shall be validated against an abstract element
  11823. * declaration.
  11824. */
  11825. tmp = xmlAutomataNewCountedTrans(pctxt->am, start, NULL, counter);
  11826. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11827. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11828. /*
  11829. * Add subst. group members.
  11830. */
  11831. for (i = 0; i < substGroup->members->nbItems; i++) {
  11832. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11833. xmlAutomataNewTransition2(pctxt->am, tmp, end,
  11834. member->name, member->targetNamespace, member);
  11835. }
  11836. } else if (particle->maxOccurs == 1) {
  11837. /*
  11838. * NOTE that we put the declaration in, even if it's abstract,
  11839. */
  11840. xmlAutomataNewEpsilon(pctxt->am,
  11841. xmlAutomataNewTransition2(pctxt->am,
  11842. start, NULL,
  11843. elemDecl->name, elemDecl->targetNamespace, elemDecl), end);
  11844. /*
  11845. * Add subst. group members.
  11846. */
  11847. for (i = 0; i < substGroup->members->nbItems; i++) {
  11848. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11849. /*
  11850. * NOTE: This fixes bug #341150. xmlAutomataNewOnceTrans2()
  11851. * was incorrectly used instead of xmlAutomataNewTransition2()
  11852. * (seems like a copy&paste bug from the XML_SCHEMA_TYPE_ALL
  11853. * section in xmlSchemaBuildAContentModel() ).
  11854. * TODO: Check if xmlAutomataNewOnceTrans2() was instead
  11855. * intended for the above "counter" section originally. I.e.,
  11856. * check xs:all with subst-groups.
  11857. *
  11858. * tmp = xmlAutomataNewOnceTrans2(pctxt->am, start, NULL,
  11859. * member->name, member->targetNamespace,
  11860. * 1, 1, member);
  11861. */
  11862. tmp = xmlAutomataNewTransition2(pctxt->am, start, NULL,
  11863. member->name, member->targetNamespace, member);
  11864. xmlAutomataNewEpsilon(pctxt->am, tmp, end);
  11865. }
  11866. } else {
  11867. xmlAutomataStatePtr hop;
  11868. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11869. UNBOUNDED : particle->maxOccurs - 1;
  11870. int minOccurs = particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  11871. counter =
  11872. xmlAutomataNewCounter(pctxt->am, minOccurs,
  11873. maxOccurs);
  11874. hop = xmlAutomataNewState(pctxt->am);
  11875. xmlAutomataNewEpsilon(pctxt->am,
  11876. xmlAutomataNewTransition2(pctxt->am,
  11877. start, NULL,
  11878. elemDecl->name, elemDecl->targetNamespace, elemDecl),
  11879. hop);
  11880. /*
  11881. * Add subst. group members.
  11882. */
  11883. for (i = 0; i < substGroup->members->nbItems; i++) {
  11884. member = (xmlSchemaElementPtr) substGroup->members->items[i];
  11885. xmlAutomataNewEpsilon(pctxt->am,
  11886. xmlAutomataNewTransition2(pctxt->am,
  11887. start, NULL,
  11888. member->name, member->targetNamespace, member),
  11889. hop);
  11890. }
  11891. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  11892. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  11893. }
  11894. if (particle->minOccurs == 0) {
  11895. xmlAutomataNewEpsilon(pctxt->am, start, end);
  11896. ret = 1;
  11897. }
  11898. pctxt->state = end;
  11899. return(ret);
  11900. }
  11901. /**
  11902. * xmlSchemaBuildContentModelForElement:
  11903. *
  11904. * Returns 1 if nillable, 0 otherwise
  11905. */
  11906. static int
  11907. xmlSchemaBuildContentModelForElement(xmlSchemaParserCtxtPtr ctxt,
  11908. xmlSchemaParticlePtr particle)
  11909. {
  11910. int ret = 0;
  11911. if (((xmlSchemaElementPtr) particle->children)->flags &
  11912. XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  11913. /*
  11914. * Substitution groups.
  11915. */
  11916. ret = xmlSchemaBuildContentModelForSubstGroup(ctxt, particle, -1, NULL);
  11917. } else {
  11918. xmlSchemaElementPtr elemDecl;
  11919. xmlAutomataStatePtr start;
  11920. elemDecl = (xmlSchemaElementPtr) particle->children;
  11921. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT)
  11922. return(0);
  11923. if (particle->maxOccurs == 1) {
  11924. start = ctxt->state;
  11925. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11926. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11927. } else if ((particle->maxOccurs >= UNBOUNDED) &&
  11928. (particle->minOccurs < 2)) {
  11929. /* Special case. */
  11930. start = ctxt->state;
  11931. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11932. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11933. ctxt->state = xmlAutomataNewTransition2(ctxt->am, ctxt->state, ctxt->state,
  11934. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11935. } else {
  11936. int counter;
  11937. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  11938. UNBOUNDED : particle->maxOccurs - 1;
  11939. int minOccurs = particle->minOccurs < 1 ?
  11940. 0 : particle->minOccurs - 1;
  11941. start = xmlAutomataNewEpsilon(ctxt->am, ctxt->state, NULL);
  11942. counter = xmlAutomataNewCounter(ctxt->am, minOccurs, maxOccurs);
  11943. ctxt->state = xmlAutomataNewTransition2(ctxt->am, start, NULL,
  11944. elemDecl->name, elemDecl->targetNamespace, elemDecl);
  11945. xmlAutomataNewCountedTrans(ctxt->am, ctxt->state, start, counter);
  11946. ctxt->state = xmlAutomataNewCounterTrans(ctxt->am, ctxt->state,
  11947. NULL, counter);
  11948. }
  11949. if (particle->minOccurs == 0) {
  11950. xmlAutomataNewEpsilon(ctxt->am, start, ctxt->state);
  11951. ret = 1;
  11952. }
  11953. }
  11954. return(ret);
  11955. }
  11956. /**
  11957. * xmlSchemaBuildAContentModel:
  11958. * @ctxt: the schema parser context
  11959. * @particle: the particle component
  11960. * @name: the complex type's name whose content is being built
  11961. *
  11962. * Create the automaton for the {content type} of a complex type.
  11963. *
  11964. * Returns 1 if the content is nillable, 0 otherwise
  11965. */
  11966. static int
  11967. xmlSchemaBuildAContentModel(xmlSchemaParserCtxtPtr pctxt,
  11968. xmlSchemaParticlePtr particle)
  11969. {
  11970. int ret = 0, tmp2;
  11971. if (particle == NULL) {
  11972. PERROR_INT("xmlSchemaBuildAContentModel", "particle is NULL");
  11973. return(1);
  11974. }
  11975. if (particle->children == NULL) {
  11976. /*
  11977. * Just return in this case. A missing "term" of the particle
  11978. * might arise due to an invalid "term" component.
  11979. */
  11980. return(1);
  11981. }
  11982. switch (particle->children->type) {
  11983. case XML_SCHEMA_TYPE_ANY: {
  11984. xmlAutomataStatePtr start, end;
  11985. xmlSchemaWildcardPtr wild;
  11986. xmlSchemaWildcardNsPtr ns;
  11987. wild = (xmlSchemaWildcardPtr) particle->children;
  11988. start = pctxt->state;
  11989. end = xmlAutomataNewState(pctxt->am);
  11990. if (particle->maxOccurs == 1) {
  11991. if (wild->any == 1) {
  11992. /*
  11993. * We need to add both transitions:
  11994. *
  11995. * 1. the {"*", "*"} for elements in a namespace.
  11996. */
  11997. pctxt->state =
  11998. xmlAutomataNewTransition2(pctxt->am,
  11999. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  12000. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12001. /*
  12002. * 2. the {"*"} for elements in no namespace.
  12003. */
  12004. pctxt->state =
  12005. xmlAutomataNewTransition2(pctxt->am,
  12006. start, NULL, BAD_CAST "*", NULL, wild);
  12007. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12008. } else if (wild->nsSet != NULL) {
  12009. ns = wild->nsSet;
  12010. do {
  12011. pctxt->state = start;
  12012. pctxt->state = xmlAutomataNewTransition2(pctxt->am,
  12013. pctxt->state, NULL, BAD_CAST "*", ns->value, wild);
  12014. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12015. ns = ns->next;
  12016. } while (ns != NULL);
  12017. } else if (wild->negNsSet != NULL) {
  12018. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  12019. start, end, BAD_CAST "*", wild->negNsSet->value,
  12020. wild);
  12021. }
  12022. } else {
  12023. int counter;
  12024. xmlAutomataStatePtr hop;
  12025. int maxOccurs =
  12026. particle->maxOccurs == UNBOUNDED ? UNBOUNDED :
  12027. particle->maxOccurs - 1;
  12028. int minOccurs =
  12029. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12030. counter = xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12031. hop = xmlAutomataNewState(pctxt->am);
  12032. if (wild->any == 1) {
  12033. pctxt->state =
  12034. xmlAutomataNewTransition2(pctxt->am,
  12035. start, NULL, BAD_CAST "*", BAD_CAST "*", wild);
  12036. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12037. pctxt->state =
  12038. xmlAutomataNewTransition2(pctxt->am,
  12039. start, NULL, BAD_CAST "*", NULL, wild);
  12040. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12041. } else if (wild->nsSet != NULL) {
  12042. ns = wild->nsSet;
  12043. do {
  12044. pctxt->state =
  12045. xmlAutomataNewTransition2(pctxt->am,
  12046. start, NULL, BAD_CAST "*", ns->value, wild);
  12047. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12048. ns = ns->next;
  12049. } while (ns != NULL);
  12050. } else if (wild->negNsSet != NULL) {
  12051. pctxt->state = xmlAutomataNewNegTrans(pctxt->am,
  12052. start, hop, BAD_CAST "*", wild->negNsSet->value,
  12053. wild);
  12054. }
  12055. xmlAutomataNewCountedTrans(pctxt->am, hop, start, counter);
  12056. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12057. }
  12058. if (particle->minOccurs == 0) {
  12059. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12060. ret = 1;
  12061. }
  12062. pctxt->state = end;
  12063. break;
  12064. }
  12065. case XML_SCHEMA_TYPE_ELEMENT:
  12066. ret = xmlSchemaBuildContentModelForElement(pctxt, particle);
  12067. break;
  12068. case XML_SCHEMA_TYPE_SEQUENCE:{
  12069. xmlSchemaTreeItemPtr sub;
  12070. ret = 1;
  12071. /*
  12072. * If max and min occurrences are default (1) then
  12073. * simply iterate over the particles of the <sequence>.
  12074. */
  12075. if ((particle->minOccurs == 1) && (particle->maxOccurs == 1)) {
  12076. sub = particle->children->children;
  12077. while (sub != NULL) {
  12078. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12079. (xmlSchemaParticlePtr) sub);
  12080. if (tmp2 != 1) ret = 0;
  12081. sub = sub->next;
  12082. }
  12083. } else {
  12084. xmlAutomataStatePtr oldstate = pctxt->state;
  12085. if (particle->maxOccurs >= UNBOUNDED) {
  12086. if (particle->minOccurs > 1) {
  12087. xmlAutomataStatePtr tmp;
  12088. int counter;
  12089. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12090. oldstate, NULL);
  12091. oldstate = pctxt->state;
  12092. counter = xmlAutomataNewCounter(pctxt->am,
  12093. particle->minOccurs - 1, UNBOUNDED);
  12094. sub = particle->children->children;
  12095. while (sub != NULL) {
  12096. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12097. (xmlSchemaParticlePtr) sub);
  12098. if (tmp2 != 1) ret = 0;
  12099. sub = sub->next;
  12100. }
  12101. tmp = pctxt->state;
  12102. xmlAutomataNewCountedTrans(pctxt->am, tmp,
  12103. oldstate, counter);
  12104. pctxt->state =
  12105. xmlAutomataNewCounterTrans(pctxt->am, tmp,
  12106. NULL, counter);
  12107. if (ret == 1)
  12108. xmlAutomataNewEpsilon(pctxt->am,
  12109. oldstate, pctxt->state);
  12110. } else {
  12111. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12112. oldstate, NULL);
  12113. oldstate = pctxt->state;
  12114. sub = particle->children->children;
  12115. while (sub != NULL) {
  12116. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12117. (xmlSchemaParticlePtr) sub);
  12118. if (tmp2 != 1) ret = 0;
  12119. sub = sub->next;
  12120. }
  12121. xmlAutomataNewEpsilon(pctxt->am, pctxt->state,
  12122. oldstate);
  12123. /*
  12124. * epsilon needed to block previous trans from
  12125. * being allowed to enter back from another
  12126. * construct
  12127. */
  12128. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12129. pctxt->state, NULL);
  12130. if (particle->minOccurs == 0) {
  12131. xmlAutomataNewEpsilon(pctxt->am,
  12132. oldstate, pctxt->state);
  12133. ret = 1;
  12134. }
  12135. }
  12136. } else if ((particle->maxOccurs > 1)
  12137. || (particle->minOccurs > 1)) {
  12138. xmlAutomataStatePtr tmp;
  12139. int counter;
  12140. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12141. oldstate, NULL);
  12142. oldstate = pctxt->state;
  12143. counter = xmlAutomataNewCounter(pctxt->am,
  12144. particle->minOccurs - 1,
  12145. particle->maxOccurs - 1);
  12146. sub = particle->children->children;
  12147. while (sub != NULL) {
  12148. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12149. (xmlSchemaParticlePtr) sub);
  12150. if (tmp2 != 1) ret = 0;
  12151. sub = sub->next;
  12152. }
  12153. tmp = pctxt->state;
  12154. xmlAutomataNewCountedTrans(pctxt->am,
  12155. tmp, oldstate, counter);
  12156. pctxt->state =
  12157. xmlAutomataNewCounterTrans(pctxt->am, tmp, NULL,
  12158. counter);
  12159. if ((particle->minOccurs == 0) || (ret == 1)) {
  12160. xmlAutomataNewEpsilon(pctxt->am,
  12161. oldstate, pctxt->state);
  12162. ret = 1;
  12163. }
  12164. } else {
  12165. sub = particle->children->children;
  12166. while (sub != NULL) {
  12167. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12168. (xmlSchemaParticlePtr) sub);
  12169. if (tmp2 != 1) ret = 0;
  12170. sub = sub->next;
  12171. }
  12172. /*
  12173. * epsilon needed to block previous trans from
  12174. * being allowed to enter back from another
  12175. * construct
  12176. */
  12177. pctxt->state = xmlAutomataNewEpsilon(pctxt->am,
  12178. pctxt->state, NULL);
  12179. if (particle->minOccurs == 0) {
  12180. xmlAutomataNewEpsilon(pctxt->am, oldstate,
  12181. pctxt->state);
  12182. ret = 1;
  12183. }
  12184. }
  12185. }
  12186. break;
  12187. }
  12188. case XML_SCHEMA_TYPE_CHOICE:{
  12189. xmlSchemaTreeItemPtr sub;
  12190. xmlAutomataStatePtr start, end;
  12191. ret = 0;
  12192. start = pctxt->state;
  12193. end = xmlAutomataNewState(pctxt->am);
  12194. /*
  12195. * iterate over the subtypes and remerge the end with an
  12196. * epsilon transition
  12197. */
  12198. if (particle->maxOccurs == 1) {
  12199. sub = particle->children->children;
  12200. while (sub != NULL) {
  12201. pctxt->state = start;
  12202. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12203. (xmlSchemaParticlePtr) sub);
  12204. if (tmp2 == 1) ret = 1;
  12205. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, end);
  12206. sub = sub->next;
  12207. }
  12208. } else {
  12209. int counter;
  12210. xmlAutomataStatePtr hop, base;
  12211. int maxOccurs = particle->maxOccurs == UNBOUNDED ?
  12212. UNBOUNDED : particle->maxOccurs - 1;
  12213. int minOccurs =
  12214. particle->minOccurs < 1 ? 0 : particle->minOccurs - 1;
  12215. /*
  12216. * use a counter to keep track of the number of transitions
  12217. * which went through the choice.
  12218. */
  12219. counter =
  12220. xmlAutomataNewCounter(pctxt->am, minOccurs, maxOccurs);
  12221. hop = xmlAutomataNewState(pctxt->am);
  12222. base = xmlAutomataNewState(pctxt->am);
  12223. sub = particle->children->children;
  12224. while (sub != NULL) {
  12225. pctxt->state = base;
  12226. tmp2 = xmlSchemaBuildAContentModel(pctxt,
  12227. (xmlSchemaParticlePtr) sub);
  12228. if (tmp2 == 1) ret = 1;
  12229. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, hop);
  12230. sub = sub->next;
  12231. }
  12232. xmlAutomataNewEpsilon(pctxt->am, start, base);
  12233. xmlAutomataNewCountedTrans(pctxt->am, hop, base, counter);
  12234. xmlAutomataNewCounterTrans(pctxt->am, hop, end, counter);
  12235. if (ret == 1)
  12236. xmlAutomataNewEpsilon(pctxt->am, base, end);
  12237. }
  12238. if (particle->minOccurs == 0) {
  12239. xmlAutomataNewEpsilon(pctxt->am, start, end);
  12240. ret = 1;
  12241. }
  12242. pctxt->state = end;
  12243. break;
  12244. }
  12245. case XML_SCHEMA_TYPE_ALL:{
  12246. xmlAutomataStatePtr start, tmp;
  12247. xmlSchemaParticlePtr sub;
  12248. xmlSchemaElementPtr elemDecl;
  12249. ret = 1;
  12250. sub = (xmlSchemaParticlePtr) particle->children->children;
  12251. if (sub == NULL)
  12252. break;
  12253. ret = 0;
  12254. start = pctxt->state;
  12255. tmp = xmlAutomataNewState(pctxt->am);
  12256. xmlAutomataNewEpsilon(pctxt->am, pctxt->state, tmp);
  12257. pctxt->state = tmp;
  12258. while (sub != NULL) {
  12259. pctxt->state = tmp;
  12260. elemDecl = (xmlSchemaElementPtr) sub->children;
  12261. if (elemDecl == NULL) {
  12262. PERROR_INT("xmlSchemaBuildAContentModel",
  12263. "<element> particle has no term");
  12264. return(ret);
  12265. };
  12266. /*
  12267. * NOTE: The {max occurs} of all the particles in the
  12268. * {particles} of the group must be 0 or 1; this is
  12269. * already ensured during the parse of the content of
  12270. * <all>.
  12271. */
  12272. if (elemDecl->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) {
  12273. int counter;
  12274. /*
  12275. * This is an abstract group, we need to share
  12276. * the same counter for all the element transitions
  12277. * derived from the group
  12278. */
  12279. counter = xmlAutomataNewCounter(pctxt->am,
  12280. sub->minOccurs, sub->maxOccurs);
  12281. xmlSchemaBuildContentModelForSubstGroup(pctxt,
  12282. sub, counter, pctxt->state);
  12283. } else {
  12284. if ((sub->minOccurs == 1) &&
  12285. (sub->maxOccurs == 1)) {
  12286. xmlAutomataNewOnceTrans2(pctxt->am, pctxt->state,
  12287. pctxt->state,
  12288. elemDecl->name,
  12289. elemDecl->targetNamespace,
  12290. 1, 1, elemDecl);
  12291. } else if ((sub->minOccurs == 0) &&
  12292. (sub->maxOccurs == 1)) {
  12293. xmlAutomataNewCountTrans2(pctxt->am, pctxt->state,
  12294. pctxt->state,
  12295. elemDecl->name,
  12296. elemDecl->targetNamespace,
  12297. 0,
  12298. 1,
  12299. elemDecl);
  12300. }
  12301. }
  12302. sub = (xmlSchemaParticlePtr) sub->next;
  12303. }
  12304. pctxt->state =
  12305. xmlAutomataNewAllTrans(pctxt->am, pctxt->state, NULL, 0);
  12306. if (particle->minOccurs == 0) {
  12307. xmlAutomataNewEpsilon(pctxt->am, start, pctxt->state);
  12308. ret = 1;
  12309. }
  12310. break;
  12311. }
  12312. case XML_SCHEMA_TYPE_GROUP:
  12313. /*
  12314. * If we hit a model group definition, then this means that
  12315. * it was empty, thus was not substituted for the containing
  12316. * model group. Just do nothing in this case.
  12317. * TODO: But the group should be substituted and not occur at
  12318. * all in the content model at this point. Fix this.
  12319. */
  12320. ret = 1;
  12321. break;
  12322. default:
  12323. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  12324. "xmlSchemaBuildAContentModel",
  12325. "found unexpected term of type '%s' in content model",
  12326. WXS_ITEM_TYPE_NAME(particle->children), NULL);
  12327. return(ret);
  12328. }
  12329. return(ret);
  12330. }
  12331. /**
  12332. * xmlSchemaBuildContentModel:
  12333. * @ctxt: the schema parser context
  12334. * @type: the complex type definition
  12335. * @name: the element name
  12336. *
  12337. * Builds the content model of the complex type.
  12338. */
  12339. static void
  12340. xmlSchemaBuildContentModel(xmlSchemaTypePtr type,
  12341. xmlSchemaParserCtxtPtr ctxt)
  12342. {
  12343. if ((type->type != XML_SCHEMA_TYPE_COMPLEX) ||
  12344. (type->contModel != NULL) ||
  12345. ((type->contentType != XML_SCHEMA_CONTENT_ELEMENTS) &&
  12346. (type->contentType != XML_SCHEMA_CONTENT_MIXED)))
  12347. return;
  12348. #ifdef DEBUG_CONTENT
  12349. xmlGenericError(xmlGenericErrorContext,
  12350. "Building content model for %s\n", name);
  12351. #endif
  12352. ctxt->am = NULL;
  12353. ctxt->am = xmlNewAutomata();
  12354. if (ctxt->am == NULL) {
  12355. xmlGenericError(xmlGenericErrorContext,
  12356. "Cannot create automata for complex type %s\n", type->name);
  12357. return;
  12358. }
  12359. ctxt->state = xmlAutomataGetInitState(ctxt->am);
  12360. /*
  12361. * Build the automaton.
  12362. */
  12363. xmlSchemaBuildAContentModel(ctxt, WXS_TYPE_PARTICLE(type));
  12364. xmlAutomataSetFinalState(ctxt->am, ctxt->state);
  12365. type->contModel = xmlAutomataCompile(ctxt->am);
  12366. if (type->contModel == NULL) {
  12367. xmlSchemaPCustomErr(ctxt,
  12368. XML_SCHEMAP_INTERNAL,
  12369. WXS_BASIC_CAST type, type->node,
  12370. "Failed to compile the content model", NULL);
  12371. } else if (xmlRegexpIsDeterminist(type->contModel) != 1) {
  12372. xmlSchemaPCustomErr(ctxt,
  12373. XML_SCHEMAP_NOT_DETERMINISTIC,
  12374. /* XML_SCHEMAS_ERR_NOTDETERMINIST, */
  12375. WXS_BASIC_CAST type, type->node,
  12376. "The content model is not determinist", NULL);
  12377. } else {
  12378. #ifdef DEBUG_CONTENT_REGEXP
  12379. xmlGenericError(xmlGenericErrorContext,
  12380. "Content model of %s:\n", type->name);
  12381. xmlRegexpPrint(stderr, type->contModel);
  12382. #endif
  12383. }
  12384. ctxt->state = NULL;
  12385. xmlFreeAutomata(ctxt->am);
  12386. ctxt->am = NULL;
  12387. }
  12388. /**
  12389. * xmlSchemaResolveElementReferences:
  12390. * @elem: the schema element context
  12391. * @ctxt: the schema parser context
  12392. *
  12393. * Resolves the references of an element declaration
  12394. * or particle, which has an element declaration as it's
  12395. * term.
  12396. */
  12397. static void
  12398. xmlSchemaResolveElementReferences(xmlSchemaElementPtr elemDecl,
  12399. xmlSchemaParserCtxtPtr ctxt)
  12400. {
  12401. if ((ctxt == NULL) || (elemDecl == NULL) ||
  12402. ((elemDecl != NULL) &&
  12403. (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_RESOLVED)))
  12404. return;
  12405. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_RESOLVED;
  12406. if ((elemDecl->subtypes == NULL) && (elemDecl->namedType != NULL)) {
  12407. xmlSchemaTypePtr type;
  12408. /* (type definition) ... otherwise the type definition `resolved`
  12409. * to by the `actual value` of the type [attribute] ...
  12410. */
  12411. type = xmlSchemaGetType(ctxt->schema, elemDecl->namedType,
  12412. elemDecl->namedTypeNs);
  12413. if (type == NULL) {
  12414. xmlSchemaPResCompAttrErr(ctxt,
  12415. XML_SCHEMAP_SRC_RESOLVE,
  12416. WXS_BASIC_CAST elemDecl, elemDecl->node,
  12417. "type", elemDecl->namedType, elemDecl->namedTypeNs,
  12418. XML_SCHEMA_TYPE_BASIC, "type definition");
  12419. } else
  12420. elemDecl->subtypes = type;
  12421. }
  12422. if (elemDecl->substGroup != NULL) {
  12423. xmlSchemaElementPtr substHead;
  12424. /*
  12425. * FIXME TODO: Do we need a new field in _xmlSchemaElement for
  12426. * substitutionGroup?
  12427. */
  12428. substHead = xmlSchemaGetElem(ctxt->schema, elemDecl->substGroup,
  12429. elemDecl->substGroupNs);
  12430. if (substHead == NULL) {
  12431. xmlSchemaPResCompAttrErr(ctxt,
  12432. XML_SCHEMAP_SRC_RESOLVE,
  12433. WXS_BASIC_CAST elemDecl, NULL,
  12434. "substitutionGroup", elemDecl->substGroup,
  12435. elemDecl->substGroupNs, XML_SCHEMA_TYPE_ELEMENT, NULL);
  12436. } else {
  12437. xmlSchemaResolveElementReferences(substHead, ctxt);
  12438. /*
  12439. * Set the "substitution group affiliation".
  12440. * NOTE that now we use the "refDecl" field for this.
  12441. */
  12442. WXS_SUBST_HEAD(elemDecl) = substHead;
  12443. /*
  12444. * The type definitions is set to:
  12445. * SPEC "...the {type definition} of the element
  12446. * declaration `resolved` to by the `actual value`
  12447. * of the substitutionGroup [attribute], if present"
  12448. */
  12449. if (elemDecl->subtypes == NULL)
  12450. elemDecl->subtypes = substHead->subtypes;
  12451. }
  12452. }
  12453. /*
  12454. * SPEC "The definition of anyType serves as the default type definition
  12455. * for element declarations whose XML representation does not specify one."
  12456. */
  12457. if ((elemDecl->subtypes == NULL) &&
  12458. (elemDecl->namedType == NULL) &&
  12459. (elemDecl->substGroup == NULL))
  12460. elemDecl->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  12461. }
  12462. /**
  12463. * xmlSchemaResolveUnionMemberTypes:
  12464. * @ctxt: the schema parser context
  12465. * @type: the schema simple type definition
  12466. *
  12467. * Checks and builds the "member type definitions" property of the union
  12468. * simple type. This handles part (1), part (2) is done in
  12469. * xmlSchemaFinishMemberTypeDefinitionsProperty()
  12470. *
  12471. * Returns -1 in case of an internal error, 0 otherwise.
  12472. */
  12473. static int
  12474. xmlSchemaResolveUnionMemberTypes(xmlSchemaParserCtxtPtr ctxt,
  12475. xmlSchemaTypePtr type)
  12476. {
  12477. xmlSchemaTypeLinkPtr link, lastLink, newLink;
  12478. xmlSchemaTypePtr memberType;
  12479. /*
  12480. * SPEC (1) "If the <union> alternative is chosen, then [Definition:]
  12481. * define the explicit members as the type definitions `resolved`
  12482. * to by the items in the `actual value` of the memberTypes [attribute],
  12483. * if any, followed by the type definitions corresponding to the
  12484. * <simpleType>s among the [children] of <union>, if any."
  12485. */
  12486. /*
  12487. * Resolve references.
  12488. */
  12489. link = type->memberTypes;
  12490. lastLink = NULL;
  12491. while (link != NULL) {
  12492. const xmlChar *name, *nsName;
  12493. name = ((xmlSchemaQNameRefPtr) link->type)->name;
  12494. nsName = ((xmlSchemaQNameRefPtr) link->type)->targetNamespace;
  12495. memberType = xmlSchemaGetType(ctxt->schema, name, nsName);
  12496. if ((memberType == NULL) || (! WXS_IS_SIMPLE(memberType))) {
  12497. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  12498. WXS_BASIC_CAST type, type->node, "memberTypes",
  12499. name, nsName, XML_SCHEMA_TYPE_SIMPLE, NULL);
  12500. /*
  12501. * Remove the member type link.
  12502. */
  12503. if (lastLink == NULL)
  12504. type->memberTypes = link->next;
  12505. else
  12506. lastLink->next = link->next;
  12507. newLink = link;
  12508. link = link->next;
  12509. xmlFree(newLink);
  12510. } else {
  12511. link->type = memberType;
  12512. lastLink = link;
  12513. link = link->next;
  12514. }
  12515. }
  12516. /*
  12517. * Add local simple types,
  12518. */
  12519. memberType = type->subtypes;
  12520. while (memberType != NULL) {
  12521. link = (xmlSchemaTypeLinkPtr) xmlMalloc(sizeof(xmlSchemaTypeLink));
  12522. if (link == NULL) {
  12523. xmlSchemaPErrMemory(ctxt, "allocating a type link", NULL);
  12524. return (-1);
  12525. }
  12526. link->type = memberType;
  12527. link->next = NULL;
  12528. if (lastLink == NULL)
  12529. type->memberTypes = link;
  12530. else
  12531. lastLink->next = link;
  12532. lastLink = link;
  12533. memberType = memberType->next;
  12534. }
  12535. return (0);
  12536. }
  12537. /**
  12538. * xmlSchemaIsDerivedFromBuiltInType:
  12539. * @ctxt: the schema parser context
  12540. * @type: the type definition
  12541. * @valType: the value type
  12542. *
  12543. *
  12544. * Returns 1 if the type has the given value type, or
  12545. * is derived from such a type.
  12546. */
  12547. static int
  12548. xmlSchemaIsDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12549. {
  12550. if (type == NULL)
  12551. return (0);
  12552. if (WXS_IS_COMPLEX(type))
  12553. return (0);
  12554. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12555. if (type->builtInType == valType)
  12556. return(1);
  12557. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12558. (type->builtInType == XML_SCHEMAS_ANYTYPE))
  12559. return (0);
  12560. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12561. }
  12562. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12563. }
  12564. #if 0
  12565. /**
  12566. * xmlSchemaIsDerivedFromBuiltInType:
  12567. * @ctxt: the schema parser context
  12568. * @type: the type definition
  12569. * @valType: the value type
  12570. *
  12571. *
  12572. * Returns 1 if the type has the given value type, or
  12573. * is derived from such a type.
  12574. */
  12575. static int
  12576. xmlSchemaIsUserDerivedFromBuiltInType(xmlSchemaTypePtr type, int valType)
  12577. {
  12578. if (type == NULL)
  12579. return (0);
  12580. if (WXS_IS_COMPLEX(type))
  12581. return (0);
  12582. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  12583. if (type->builtInType == valType)
  12584. return(1);
  12585. return (0);
  12586. } else
  12587. return(xmlSchemaIsDerivedFromBuiltInType(type->subtypes, valType));
  12588. return (0);
  12589. }
  12590. static xmlSchemaTypePtr
  12591. xmlSchemaQueryBuiltInType(xmlSchemaTypePtr type)
  12592. {
  12593. if (type == NULL)
  12594. return (NULL);
  12595. if (WXS_IS_COMPLEX(type))
  12596. return (NULL);
  12597. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12598. return(type);
  12599. return(xmlSchemaQueryBuiltInType(type->subtypes));
  12600. }
  12601. #endif
  12602. /**
  12603. * xmlSchemaGetPrimitiveType:
  12604. * @type: the simpleType definition
  12605. *
  12606. * Returns the primitive type of the given type or
  12607. * NULL in case of error.
  12608. */
  12609. static xmlSchemaTypePtr
  12610. xmlSchemaGetPrimitiveType(xmlSchemaTypePtr type)
  12611. {
  12612. while (type != NULL) {
  12613. /*
  12614. * Note that anySimpleType is actually not a primitive type
  12615. * but we need that here.
  12616. */
  12617. if ((type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) ||
  12618. (type->flags & XML_SCHEMAS_TYPE_BUILTIN_PRIMITIVE))
  12619. return (type);
  12620. type = type->baseType;
  12621. }
  12622. return (NULL);
  12623. }
  12624. #if 0
  12625. /**
  12626. * xmlSchemaGetBuiltInTypeAncestor:
  12627. * @type: the simpleType definition
  12628. *
  12629. * Returns the primitive type of the given type or
  12630. * NULL in case of error.
  12631. */
  12632. static xmlSchemaTypePtr
  12633. xmlSchemaGetBuiltInTypeAncestor(xmlSchemaTypePtr type)
  12634. {
  12635. if (WXS_IS_LIST(type) || WXS_IS_UNION(type))
  12636. return (0);
  12637. while (type != NULL) {
  12638. if (type->type == XML_SCHEMA_TYPE_BASIC)
  12639. return (type);
  12640. type = type->baseType;
  12641. }
  12642. return (NULL);
  12643. }
  12644. #endif
  12645. /**
  12646. * xmlSchemaCloneWildcardNsConstraints:
  12647. * @ctxt: the schema parser context
  12648. * @dest: the destination wildcard
  12649. * @source: the source wildcard
  12650. *
  12651. * Clones the namespace constraints of source
  12652. * and assigns them to dest.
  12653. * Returns -1 on internal error, 0 otherwise.
  12654. */
  12655. static int
  12656. xmlSchemaCloneWildcardNsConstraints(xmlSchemaParserCtxtPtr ctxt,
  12657. xmlSchemaWildcardPtr dest,
  12658. xmlSchemaWildcardPtr source)
  12659. {
  12660. xmlSchemaWildcardNsPtr cur, tmp, last;
  12661. if ((source == NULL) || (dest == NULL))
  12662. return(-1);
  12663. dest->any = source->any;
  12664. cur = source->nsSet;
  12665. last = NULL;
  12666. while (cur != NULL) {
  12667. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12668. if (tmp == NULL)
  12669. return(-1);
  12670. tmp->value = cur->value;
  12671. if (last == NULL)
  12672. dest->nsSet = tmp;
  12673. else
  12674. last->next = tmp;
  12675. last = tmp;
  12676. cur = cur->next;
  12677. }
  12678. if (dest->negNsSet != NULL)
  12679. xmlSchemaFreeWildcardNsSet(dest->negNsSet);
  12680. if (source->negNsSet != NULL) {
  12681. dest->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12682. if (dest->negNsSet == NULL)
  12683. return(-1);
  12684. dest->negNsSet->value = source->negNsSet->value;
  12685. } else
  12686. dest->negNsSet = NULL;
  12687. return(0);
  12688. }
  12689. /**
  12690. * xmlSchemaUnionWildcards:
  12691. * @ctxt: the schema parser context
  12692. * @completeWild: the first wildcard
  12693. * @curWild: the second wildcard
  12694. *
  12695. * Unions the namespace constraints of the given wildcards.
  12696. * @completeWild will hold the resulting union.
  12697. * Returns a positive error code on failure, -1 in case of an
  12698. * internal error, 0 otherwise.
  12699. */
  12700. static int
  12701. xmlSchemaUnionWildcards(xmlSchemaParserCtxtPtr ctxt,
  12702. xmlSchemaWildcardPtr completeWild,
  12703. xmlSchemaWildcardPtr curWild)
  12704. {
  12705. xmlSchemaWildcardNsPtr cur, curB, tmp;
  12706. /*
  12707. * 1 If O1 and O2 are the same value, then that value must be the
  12708. * value.
  12709. */
  12710. if ((completeWild->any == curWild->any) &&
  12711. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12712. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12713. if ((completeWild->negNsSet == NULL) ||
  12714. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12715. if (completeWild->nsSet != NULL) {
  12716. int found = 0;
  12717. /*
  12718. * Check equality of sets.
  12719. */
  12720. cur = completeWild->nsSet;
  12721. while (cur != NULL) {
  12722. found = 0;
  12723. curB = curWild->nsSet;
  12724. while (curB != NULL) {
  12725. if (cur->value == curB->value) {
  12726. found = 1;
  12727. break;
  12728. }
  12729. curB = curB->next;
  12730. }
  12731. if (!found)
  12732. break;
  12733. cur = cur->next;
  12734. }
  12735. if (found)
  12736. return(0);
  12737. } else
  12738. return(0);
  12739. }
  12740. }
  12741. /*
  12742. * 2 If either O1 or O2 is any, then any must be the value
  12743. */
  12744. if (completeWild->any != curWild->any) {
  12745. if (completeWild->any == 0) {
  12746. completeWild->any = 1;
  12747. if (completeWild->nsSet != NULL) {
  12748. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12749. completeWild->nsSet = NULL;
  12750. }
  12751. if (completeWild->negNsSet != NULL) {
  12752. xmlFree(completeWild->negNsSet);
  12753. completeWild->negNsSet = NULL;
  12754. }
  12755. }
  12756. return (0);
  12757. }
  12758. /*
  12759. * 3 If both O1 and O2 are sets of (namespace names or `absent`),
  12760. * then the union of those sets must be the value.
  12761. */
  12762. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  12763. int found;
  12764. xmlSchemaWildcardNsPtr start;
  12765. cur = curWild->nsSet;
  12766. start = completeWild->nsSet;
  12767. while (cur != NULL) {
  12768. found = 0;
  12769. curB = start;
  12770. while (curB != NULL) {
  12771. if (cur->value == curB->value) {
  12772. found = 1;
  12773. break;
  12774. }
  12775. curB = curB->next;
  12776. }
  12777. if (!found) {
  12778. tmp = xmlSchemaNewWildcardNsConstraint(ctxt);
  12779. if (tmp == NULL)
  12780. return (-1);
  12781. tmp->value = cur->value;
  12782. tmp->next = completeWild->nsSet;
  12783. completeWild->nsSet = tmp;
  12784. }
  12785. cur = cur->next;
  12786. }
  12787. return(0);
  12788. }
  12789. /*
  12790. * 4 If the two are negations of different values (namespace names
  12791. * or `absent`), then a pair of not and `absent` must be the value.
  12792. */
  12793. if ((completeWild->negNsSet != NULL) &&
  12794. (curWild->negNsSet != NULL) &&
  12795. (completeWild->negNsSet->value != curWild->negNsSet->value)) {
  12796. completeWild->negNsSet->value = NULL;
  12797. return(0);
  12798. }
  12799. /*
  12800. * 5.
  12801. */
  12802. if (((completeWild->negNsSet != NULL) &&
  12803. (completeWild->negNsSet->value != NULL) &&
  12804. (curWild->nsSet != NULL)) ||
  12805. ((curWild->negNsSet != NULL) &&
  12806. (curWild->negNsSet->value != NULL) &&
  12807. (completeWild->nsSet != NULL))) {
  12808. int nsFound, absentFound = 0;
  12809. if (completeWild->nsSet != NULL) {
  12810. cur = completeWild->nsSet;
  12811. curB = curWild->negNsSet;
  12812. } else {
  12813. cur = curWild->nsSet;
  12814. curB = completeWild->negNsSet;
  12815. }
  12816. nsFound = 0;
  12817. while (cur != NULL) {
  12818. if (cur->value == NULL)
  12819. absentFound = 1;
  12820. else if (cur->value == curB->value)
  12821. nsFound = 1;
  12822. if (nsFound && absentFound)
  12823. break;
  12824. cur = cur->next;
  12825. }
  12826. if (nsFound && absentFound) {
  12827. /*
  12828. * 5.1 If the set S includes both the negated namespace
  12829. * name and `absent`, then any must be the value.
  12830. */
  12831. completeWild->any = 1;
  12832. if (completeWild->nsSet != NULL) {
  12833. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12834. completeWild->nsSet = NULL;
  12835. }
  12836. if (completeWild->negNsSet != NULL) {
  12837. xmlFree(completeWild->negNsSet);
  12838. completeWild->negNsSet = NULL;
  12839. }
  12840. } else if (nsFound && (!absentFound)) {
  12841. /*
  12842. * 5.2 If the set S includes the negated namespace name
  12843. * but not `absent`, then a pair of not and `absent` must
  12844. * be the value.
  12845. */
  12846. if (completeWild->nsSet != NULL) {
  12847. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12848. completeWild->nsSet = NULL;
  12849. }
  12850. if (completeWild->negNsSet == NULL) {
  12851. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12852. if (completeWild->negNsSet == NULL)
  12853. return (-1);
  12854. }
  12855. completeWild->negNsSet->value = NULL;
  12856. } else if ((!nsFound) && absentFound) {
  12857. /*
  12858. * 5.3 If the set S includes `absent` but not the negated
  12859. * namespace name, then the union is not expressible.
  12860. */
  12861. xmlSchemaPErr(ctxt, completeWild->node,
  12862. XML_SCHEMAP_UNION_NOT_EXPRESSIBLE,
  12863. "The union of the wildcard is not expressible.\n",
  12864. NULL, NULL);
  12865. return(XML_SCHEMAP_UNION_NOT_EXPRESSIBLE);
  12866. } else if ((!nsFound) && (!absentFound)) {
  12867. /*
  12868. * 5.4 If the set S does not include either the negated namespace
  12869. * name or `absent`, then whichever of O1 or O2 is a pair of not
  12870. * and a namespace name must be the value.
  12871. */
  12872. if (completeWild->negNsSet == NULL) {
  12873. if (completeWild->nsSet != NULL) {
  12874. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12875. completeWild->nsSet = NULL;
  12876. }
  12877. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12878. if (completeWild->negNsSet == NULL)
  12879. return (-1);
  12880. completeWild->negNsSet->value = curWild->negNsSet->value;
  12881. }
  12882. }
  12883. return (0);
  12884. }
  12885. /*
  12886. * 6.
  12887. */
  12888. if (((completeWild->negNsSet != NULL) &&
  12889. (completeWild->negNsSet->value == NULL) &&
  12890. (curWild->nsSet != NULL)) ||
  12891. ((curWild->negNsSet != NULL) &&
  12892. (curWild->negNsSet->value == NULL) &&
  12893. (completeWild->nsSet != NULL))) {
  12894. if (completeWild->nsSet != NULL) {
  12895. cur = completeWild->nsSet;
  12896. } else {
  12897. cur = curWild->nsSet;
  12898. }
  12899. while (cur != NULL) {
  12900. if (cur->value == NULL) {
  12901. /*
  12902. * 6.1 If the set S includes `absent`, then any must be the
  12903. * value.
  12904. */
  12905. completeWild->any = 1;
  12906. if (completeWild->nsSet != NULL) {
  12907. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12908. completeWild->nsSet = NULL;
  12909. }
  12910. if (completeWild->negNsSet != NULL) {
  12911. xmlFree(completeWild->negNsSet);
  12912. completeWild->negNsSet = NULL;
  12913. }
  12914. return (0);
  12915. }
  12916. cur = cur->next;
  12917. }
  12918. if (completeWild->negNsSet == NULL) {
  12919. /*
  12920. * 6.2 If the set S does not include `absent`, then a pair of not
  12921. * and `absent` must be the value.
  12922. */
  12923. if (completeWild->nsSet != NULL) {
  12924. xmlSchemaFreeWildcardNsSet(completeWild->nsSet);
  12925. completeWild->nsSet = NULL;
  12926. }
  12927. completeWild->negNsSet = xmlSchemaNewWildcardNsConstraint(ctxt);
  12928. if (completeWild->negNsSet == NULL)
  12929. return (-1);
  12930. completeWild->negNsSet->value = NULL;
  12931. }
  12932. return (0);
  12933. }
  12934. return (0);
  12935. }
  12936. /**
  12937. * xmlSchemaIntersectWildcards:
  12938. * @ctxt: the schema parser context
  12939. * @completeWild: the first wildcard
  12940. * @curWild: the second wildcard
  12941. *
  12942. * Intersects the namespace constraints of the given wildcards.
  12943. * @completeWild will hold the resulting intersection.
  12944. * Returns a positive error code on failure, -1 in case of an
  12945. * internal error, 0 otherwise.
  12946. */
  12947. static int
  12948. xmlSchemaIntersectWildcards(xmlSchemaParserCtxtPtr ctxt,
  12949. xmlSchemaWildcardPtr completeWild,
  12950. xmlSchemaWildcardPtr curWild)
  12951. {
  12952. xmlSchemaWildcardNsPtr cur, curB, prev, tmp;
  12953. /*
  12954. * 1 If O1 and O2 are the same value, then that value must be the
  12955. * value.
  12956. */
  12957. if ((completeWild->any == curWild->any) &&
  12958. ((completeWild->nsSet == NULL) == (curWild->nsSet == NULL)) &&
  12959. ((completeWild->negNsSet == NULL) == (curWild->negNsSet == NULL))) {
  12960. if ((completeWild->negNsSet == NULL) ||
  12961. (completeWild->negNsSet->value == curWild->negNsSet->value)) {
  12962. if (completeWild->nsSet != NULL) {
  12963. int found = 0;
  12964. /*
  12965. * Check equality of sets.
  12966. */
  12967. cur = completeWild->nsSet;
  12968. while (cur != NULL) {
  12969. found = 0;
  12970. curB = curWild->nsSet;
  12971. while (curB != NULL) {
  12972. if (cur->value == curB->value) {
  12973. found = 1;
  12974. break;
  12975. }
  12976. curB = curB->next;
  12977. }
  12978. if (!found)
  12979. break;
  12980. cur = cur->next;
  12981. }
  12982. if (found)
  12983. return(0);
  12984. } else
  12985. return(0);
  12986. }
  12987. }
  12988. /*
  12989. * 2 If either O1 or O2 is any, then the other must be the value.
  12990. */
  12991. if ((completeWild->any != curWild->any) && (completeWild->any)) {
  12992. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  12993. return(-1);
  12994. return(0);
  12995. }
  12996. /*
  12997. * 3 If either O1 or O2 is a pair of not and a value (a namespace
  12998. * name or `absent`) and the other is a set of (namespace names or
  12999. * `absent`), then that set, minus the negated value if it was in
  13000. * the set, minus `absent` if it was in the set, must be the value.
  13001. */
  13002. if (((completeWild->negNsSet != NULL) && (curWild->nsSet != NULL)) ||
  13003. ((curWild->negNsSet != NULL) && (completeWild->nsSet != NULL))) {
  13004. const xmlChar *neg;
  13005. if (completeWild->nsSet == NULL) {
  13006. neg = completeWild->negNsSet->value;
  13007. if (xmlSchemaCloneWildcardNsConstraints(ctxt, completeWild, curWild) == -1)
  13008. return(-1);
  13009. } else
  13010. neg = curWild->negNsSet->value;
  13011. /*
  13012. * Remove absent and negated.
  13013. */
  13014. prev = NULL;
  13015. cur = completeWild->nsSet;
  13016. while (cur != NULL) {
  13017. if (cur->value == NULL) {
  13018. if (prev == NULL)
  13019. completeWild->nsSet = cur->next;
  13020. else
  13021. prev->next = cur->next;
  13022. xmlFree(cur);
  13023. break;
  13024. }
  13025. prev = cur;
  13026. cur = cur->next;
  13027. }
  13028. if (neg != NULL) {
  13029. prev = NULL;
  13030. cur = completeWild->nsSet;
  13031. while (cur != NULL) {
  13032. if (cur->value == neg) {
  13033. if (prev == NULL)
  13034. completeWild->nsSet = cur->next;
  13035. else
  13036. prev->next = cur->next;
  13037. xmlFree(cur);
  13038. break;
  13039. }
  13040. prev = cur;
  13041. cur = cur->next;
  13042. }
  13043. }
  13044. return(0);
  13045. }
  13046. /*
  13047. * 4 If both O1 and O2 are sets of (namespace names or `absent`),
  13048. * then the intersection of those sets must be the value.
  13049. */
  13050. if ((completeWild->nsSet != NULL) && (curWild->nsSet != NULL)) {
  13051. int found;
  13052. cur = completeWild->nsSet;
  13053. prev = NULL;
  13054. while (cur != NULL) {
  13055. found = 0;
  13056. curB = curWild->nsSet;
  13057. while (curB != NULL) {
  13058. if (cur->value == curB->value) {
  13059. found = 1;
  13060. break;
  13061. }
  13062. curB = curB->next;
  13063. }
  13064. if (!found) {
  13065. if (prev == NULL)
  13066. completeWild->nsSet = cur->next;
  13067. else
  13068. prev->next = cur->next;
  13069. tmp = cur->next;
  13070. xmlFree(cur);
  13071. cur = tmp;
  13072. continue;
  13073. }
  13074. prev = cur;
  13075. cur = cur->next;
  13076. }
  13077. return(0);
  13078. }
  13079. /* 5 If the two are negations of different namespace names,
  13080. * then the intersection is not expressible
  13081. */
  13082. if ((completeWild->negNsSet != NULL) &&
  13083. (curWild->negNsSet != NULL) &&
  13084. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13085. (completeWild->negNsSet->value != NULL) &&
  13086. (curWild->negNsSet->value != NULL)) {
  13087. xmlSchemaPErr(ctxt, completeWild->node, XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE,
  13088. "The intersection of the wildcard is not expressible.\n",
  13089. NULL, NULL);
  13090. return(XML_SCHEMAP_INTERSECTION_NOT_EXPRESSIBLE);
  13091. }
  13092. /*
  13093. * 6 If the one is a negation of a namespace name and the other
  13094. * is a negation of `absent`, then the one which is the negation
  13095. * of a namespace name must be the value.
  13096. */
  13097. if ((completeWild->negNsSet != NULL) && (curWild->negNsSet != NULL) &&
  13098. (completeWild->negNsSet->value != curWild->negNsSet->value) &&
  13099. (completeWild->negNsSet->value == NULL)) {
  13100. completeWild->negNsSet->value = curWild->negNsSet->value;
  13101. }
  13102. return(0);
  13103. }
  13104. /**
  13105. * xmlSchemaIsWildcardNsConstraintSubset:
  13106. * @ctxt: the schema parser context
  13107. * @sub: the first wildcard
  13108. * @super: the second wildcard
  13109. *
  13110. * Schema Component Constraint: Wildcard Subset (cos-ns-subset)
  13111. *
  13112. * Returns 0 if the namespace constraint of @sub is an intensional
  13113. * subset of @super, 1 otherwise.
  13114. */
  13115. static int
  13116. xmlSchemaCheckCOSNSSubset(xmlSchemaWildcardPtr sub,
  13117. xmlSchemaWildcardPtr super)
  13118. {
  13119. /*
  13120. * 1 super must be any.
  13121. */
  13122. if (super->any)
  13123. return (0);
  13124. /*
  13125. * 2.1 sub must be a pair of not and a namespace name or `absent`.
  13126. * 2.2 super must be a pair of not and the same value.
  13127. */
  13128. if ((sub->negNsSet != NULL) &&
  13129. (super->negNsSet != NULL) &&
  13130. (sub->negNsSet->value == super->negNsSet->value))
  13131. return (0);
  13132. /*
  13133. * 3.1 sub must be a set whose members are either namespace names or `absent`.
  13134. */
  13135. if (sub->nsSet != NULL) {
  13136. /*
  13137. * 3.2.1 super must be the same set or a superset thereof.
  13138. */
  13139. if (super->nsSet != NULL) {
  13140. xmlSchemaWildcardNsPtr cur, curB;
  13141. int found = 0;
  13142. cur = sub->nsSet;
  13143. while (cur != NULL) {
  13144. found = 0;
  13145. curB = super->nsSet;
  13146. while (curB != NULL) {
  13147. if (cur->value == curB->value) {
  13148. found = 1;
  13149. break;
  13150. }
  13151. curB = curB->next;
  13152. }
  13153. if (!found)
  13154. return (1);
  13155. cur = cur->next;
  13156. }
  13157. if (found)
  13158. return (0);
  13159. } else if (super->negNsSet != NULL) {
  13160. xmlSchemaWildcardNsPtr cur;
  13161. /*
  13162. * 3.2.2 super must be a pair of not and a namespace name or
  13163. * `absent` and that value must not be in sub's set.
  13164. */
  13165. cur = sub->nsSet;
  13166. while (cur != NULL) {
  13167. if (cur->value == super->negNsSet->value)
  13168. return (1);
  13169. cur = cur->next;
  13170. }
  13171. return (0);
  13172. }
  13173. }
  13174. return (1);
  13175. }
  13176. static int
  13177. xmlSchemaGetEffectiveValueConstraint(xmlSchemaAttributeUsePtr attruse,
  13178. int *fixed,
  13179. const xmlChar **value,
  13180. xmlSchemaValPtr *val)
  13181. {
  13182. *fixed = 0;
  13183. *value = NULL;
  13184. if (val != 0)
  13185. *val = NULL;
  13186. if (attruse->defValue != NULL) {
  13187. *value = attruse->defValue;
  13188. if (val != NULL)
  13189. *val = attruse->defVal;
  13190. if (attruse->flags & XML_SCHEMA_ATTR_USE_FIXED)
  13191. *fixed = 1;
  13192. return(1);
  13193. } else if ((attruse->attrDecl != NULL) &&
  13194. (attruse->attrDecl->defValue != NULL)) {
  13195. *value = attruse->attrDecl->defValue;
  13196. if (val != NULL)
  13197. *val = attruse->attrDecl->defVal;
  13198. if (attruse->attrDecl->flags & XML_SCHEMAS_ATTR_FIXED)
  13199. *fixed = 1;
  13200. return(1);
  13201. }
  13202. return(0);
  13203. }
  13204. /**
  13205. * xmlSchemaCheckCVCWildcardNamespace:
  13206. * @wild: the wildcard
  13207. * @ns: the namespace
  13208. *
  13209. * Validation Rule: Wildcard allows Namespace Name
  13210. * (cvc-wildcard-namespace)
  13211. *
  13212. * Returns 0 if the given namespace matches the wildcard,
  13213. * 1 otherwise and -1 on API errors.
  13214. */
  13215. static int
  13216. xmlSchemaCheckCVCWildcardNamespace(xmlSchemaWildcardPtr wild,
  13217. const xmlChar* ns)
  13218. {
  13219. if (wild == NULL)
  13220. return(-1);
  13221. if (wild->any)
  13222. return(0);
  13223. else if (wild->nsSet != NULL) {
  13224. xmlSchemaWildcardNsPtr cur;
  13225. cur = wild->nsSet;
  13226. while (cur != NULL) {
  13227. if (xmlStrEqual(cur->value, ns))
  13228. return(0);
  13229. cur = cur->next;
  13230. }
  13231. } else if ((wild->negNsSet != NULL) && (ns != NULL) &&
  13232. (!xmlStrEqual(wild->negNsSet->value, ns)))
  13233. return(0);
  13234. return(1);
  13235. }
  13236. #define XML_SCHEMA_ACTION_DERIVE 0
  13237. #define XML_SCHEMA_ACTION_REDEFINE 1
  13238. #define WXS_ACTION_STR(a) \
  13239. ((a) == XML_SCHEMA_ACTION_DERIVE) ? (const xmlChar *) "base" : (const xmlChar *) "redefined"
  13240. /*
  13241. * Schema Component Constraint:
  13242. * Derivation Valid (Restriction, Complex)
  13243. * derivation-ok-restriction (2) - (4)
  13244. *
  13245. * ATTENTION:
  13246. * In XML Schema 1.1 this will be:
  13247. * Validation Rule:
  13248. * Checking complex type subsumption (practicalSubsumption) (1, 2 and 3)
  13249. *
  13250. */
  13251. static int
  13252. xmlSchemaCheckDerivationOKRestriction2to4(xmlSchemaParserCtxtPtr pctxt,
  13253. int action,
  13254. xmlSchemaBasicItemPtr item,
  13255. xmlSchemaBasicItemPtr baseItem,
  13256. xmlSchemaItemListPtr uses,
  13257. xmlSchemaItemListPtr baseUses,
  13258. xmlSchemaWildcardPtr wild,
  13259. xmlSchemaWildcardPtr baseWild)
  13260. {
  13261. xmlSchemaAttributeUsePtr cur = NULL, bcur;
  13262. int i, j, found; /* err = 0; */
  13263. const xmlChar *bEffValue;
  13264. int effFixed;
  13265. if (uses != NULL) {
  13266. for (i = 0; i < uses->nbItems; i++) {
  13267. cur = uses->items[i];
  13268. found = 0;
  13269. if (baseUses == NULL)
  13270. goto not_found;
  13271. for (j = 0; j < baseUses->nbItems; j++) {
  13272. bcur = baseUses->items[j];
  13273. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13274. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13275. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13276. WXS_ATTRUSE_DECL_TNS(bcur)))
  13277. {
  13278. /*
  13279. * (2.1) "If there is an attribute use in the {attribute
  13280. * uses} of the {base type definition} (call this B) whose
  13281. * {attribute declaration} has the same {name} and {target
  13282. * namespace}, then all of the following must be true:"
  13283. */
  13284. found = 1;
  13285. if ((cur->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  13286. (bcur->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED))
  13287. {
  13288. xmlChar *str = NULL;
  13289. /*
  13290. * (2.1.1) "one of the following must be true:"
  13291. * (2.1.1.1) "B's {required} is false."
  13292. * (2.1.1.2) "R's {required} is true."
  13293. */
  13294. xmlSchemaPAttrUseErr4(pctxt,
  13295. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_1,
  13296. WXS_ITEM_NODE(item), item, cur,
  13297. "The 'optional' attribute use is inconsistent "
  13298. "with the corresponding 'required' attribute use of "
  13299. "the %s %s",
  13300. WXS_ACTION_STR(action),
  13301. xmlSchemaGetComponentDesignation(&str, baseItem),
  13302. NULL, NULL);
  13303. FREE_AND_NULL(str);
  13304. /* err = pctxt->err; */
  13305. } else if (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  13306. WXS_ATTRUSE_TYPEDEF(cur),
  13307. WXS_ATTRUSE_TYPEDEF(bcur), 0) != 0)
  13308. {
  13309. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  13310. /*
  13311. * SPEC (2.1.2) "R's {attribute declaration}'s
  13312. * {type definition} must be validly derived from
  13313. * B's {type definition} given the empty set as
  13314. * defined in Type Derivation OK (Simple) ($3.14.6)."
  13315. */
  13316. xmlSchemaPAttrUseErr4(pctxt,
  13317. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_2,
  13318. WXS_ITEM_NODE(item), item, cur,
  13319. "The attribute declaration's %s "
  13320. "is not validly derived from "
  13321. "the corresponding %s of the "
  13322. "attribute declaration in the %s %s",
  13323. xmlSchemaGetComponentDesignation(&strA,
  13324. WXS_ATTRUSE_TYPEDEF(cur)),
  13325. xmlSchemaGetComponentDesignation(&strB,
  13326. WXS_ATTRUSE_TYPEDEF(bcur)),
  13327. WXS_ACTION_STR(action),
  13328. xmlSchemaGetComponentDesignation(&strC, baseItem));
  13329. /* xmlSchemaGetComponentDesignation(&str, baseItem), */
  13330. FREE_AND_NULL(strA);
  13331. FREE_AND_NULL(strB);
  13332. FREE_AND_NULL(strC);
  13333. /* err = pctxt->err; */
  13334. } else {
  13335. /*
  13336. * 2.1.3 [Definition:] Let the effective value
  13337. * constraint of an attribute use be its {value
  13338. * constraint}, if present, otherwise its {attribute
  13339. * declaration}'s {value constraint} .
  13340. */
  13341. xmlSchemaGetEffectiveValueConstraint(bcur,
  13342. &effFixed, &bEffValue, NULL);
  13343. /*
  13344. * 2.1.3 ... one of the following must be true
  13345. *
  13346. * 2.1.3.1 B's `effective value constraint` is
  13347. * `absent` or default.
  13348. */
  13349. if ((bEffValue != NULL) &&
  13350. (effFixed == 1)) {
  13351. const xmlChar *rEffValue = NULL;
  13352. xmlSchemaGetEffectiveValueConstraint(bcur,
  13353. &effFixed, &rEffValue, NULL);
  13354. /*
  13355. * 2.1.3.2 R's `effective value constraint` is
  13356. * fixed with the same string as B's.
  13357. * MAYBE TODO: Compare the computed values.
  13358. * Hmm, it says "same string" so
  13359. * string-equality might really be sufficient.
  13360. */
  13361. if ((effFixed == 0) ||
  13362. (! WXS_ARE_DEFAULT_STR_EQUAL(rEffValue, bEffValue)))
  13363. {
  13364. xmlChar *str = NULL;
  13365. xmlSchemaPAttrUseErr4(pctxt,
  13366. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_1_3,
  13367. WXS_ITEM_NODE(item), item, cur,
  13368. "The effective value constraint of the "
  13369. "attribute use is inconsistent with "
  13370. "its correspondent in the %s %s",
  13371. WXS_ACTION_STR(action),
  13372. xmlSchemaGetComponentDesignation(&str,
  13373. baseItem),
  13374. NULL, NULL);
  13375. FREE_AND_NULL(str);
  13376. /* err = pctxt->err; */
  13377. }
  13378. }
  13379. }
  13380. break;
  13381. }
  13382. }
  13383. not_found:
  13384. if (!found) {
  13385. /*
  13386. * (2.2) "otherwise the {base type definition} must have an
  13387. * {attribute wildcard} and the {target namespace} of the
  13388. * R's {attribute declaration} must be `valid` with respect
  13389. * to that wildcard, as defined in Wildcard allows Namespace
  13390. * Name ($3.10.4)."
  13391. */
  13392. if ((baseWild == NULL) ||
  13393. (xmlSchemaCheckCVCWildcardNamespace(baseWild,
  13394. (WXS_ATTRUSE_DECL(cur))->targetNamespace) != 0))
  13395. {
  13396. xmlChar *str = NULL;
  13397. xmlSchemaPAttrUseErr4(pctxt,
  13398. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_2_2,
  13399. WXS_ITEM_NODE(item), item, cur,
  13400. "Neither a matching attribute use, "
  13401. "nor a matching wildcard exists in the %s %s",
  13402. WXS_ACTION_STR(action),
  13403. xmlSchemaGetComponentDesignation(&str, baseItem),
  13404. NULL, NULL);
  13405. FREE_AND_NULL(str);
  13406. /* err = pctxt->err; */
  13407. }
  13408. }
  13409. }
  13410. }
  13411. /*
  13412. * SPEC derivation-ok-restriction (3):
  13413. * (3) "For each attribute use in the {attribute uses} of the {base type
  13414. * definition} whose {required} is true, there must be an attribute
  13415. * use with an {attribute declaration} with the same {name} and
  13416. * {target namespace} as its {attribute declaration} in the {attribute
  13417. * uses} of the complex type definition itself whose {required} is true.
  13418. */
  13419. if (baseUses != NULL) {
  13420. for (j = 0; j < baseUses->nbItems; j++) {
  13421. bcur = baseUses->items[j];
  13422. if (bcur->occurs != XML_SCHEMAS_ATTR_USE_REQUIRED)
  13423. continue;
  13424. found = 0;
  13425. if (uses != NULL) {
  13426. for (i = 0; i < uses->nbItems; i++) {
  13427. cur = uses->items[i];
  13428. if ((WXS_ATTRUSE_DECL_NAME(cur) ==
  13429. WXS_ATTRUSE_DECL_NAME(bcur)) &&
  13430. (WXS_ATTRUSE_DECL_TNS(cur) ==
  13431. WXS_ATTRUSE_DECL_TNS(bcur))) {
  13432. found = 1;
  13433. break;
  13434. }
  13435. }
  13436. }
  13437. if (!found) {
  13438. xmlChar *strA = NULL, *strB = NULL;
  13439. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13440. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_3,
  13441. NULL, item,
  13442. "A matching attribute use for the "
  13443. "'required' %s of the %s %s is missing",
  13444. xmlSchemaGetComponentDesignation(&strA, bcur),
  13445. WXS_ACTION_STR(action),
  13446. xmlSchemaGetComponentDesignation(&strB, baseItem),
  13447. NULL);
  13448. FREE_AND_NULL(strA);
  13449. FREE_AND_NULL(strB);
  13450. }
  13451. }
  13452. }
  13453. /*
  13454. * derivation-ok-restriction (4)
  13455. */
  13456. if (wild != NULL) {
  13457. /*
  13458. * (4) "If there is an {attribute wildcard}, all of the
  13459. * following must be true:"
  13460. */
  13461. if (baseWild == NULL) {
  13462. xmlChar *str = NULL;
  13463. /*
  13464. * (4.1) "The {base type definition} must also have one."
  13465. */
  13466. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13467. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_1,
  13468. NULL, item,
  13469. "The %s has an attribute wildcard, "
  13470. "but the %s %s '%s' does not have one",
  13471. WXS_ITEM_TYPE_NAME(item),
  13472. WXS_ACTION_STR(action),
  13473. WXS_ITEM_TYPE_NAME(baseItem),
  13474. xmlSchemaGetComponentQName(&str, baseItem));
  13475. FREE_AND_NULL(str);
  13476. return(pctxt->err);
  13477. } else if ((baseWild->any == 0) &&
  13478. xmlSchemaCheckCOSNSSubset(wild, baseWild))
  13479. {
  13480. xmlChar *str = NULL;
  13481. /*
  13482. * (4.2) "The complex type definition's {attribute wildcard}'s
  13483. * {namespace constraint} must be a subset of the {base type
  13484. * definition}'s {attribute wildcard}'s {namespace constraint},
  13485. * as defined by Wildcard Subset ($3.10.6)."
  13486. */
  13487. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13488. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_2,
  13489. NULL, item,
  13490. "The attribute wildcard is not a valid "
  13491. "subset of the wildcard in the %s %s '%s'",
  13492. WXS_ACTION_STR(action),
  13493. WXS_ITEM_TYPE_NAME(baseItem),
  13494. xmlSchemaGetComponentQName(&str, baseItem),
  13495. NULL);
  13496. FREE_AND_NULL(str);
  13497. return(pctxt->err);
  13498. }
  13499. /* 4.3 Unless the {base type definition} is the `ur-type
  13500. * definition`, the complex type definition's {attribute
  13501. * wildcard}'s {process contents} must be identical to or
  13502. * stronger than the {base type definition}'s {attribute
  13503. * wildcard}'s {process contents}, where strict is stronger
  13504. * than lax is stronger than skip.
  13505. */
  13506. if ((! WXS_IS_ANYTYPE(baseItem)) &&
  13507. (wild->processContents < baseWild->processContents)) {
  13508. xmlChar *str = NULL;
  13509. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  13510. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_4_3,
  13511. NULL, baseItem,
  13512. "The {process contents} of the attribute wildcard is "
  13513. "weaker than the one in the %s %s '%s'",
  13514. WXS_ACTION_STR(action),
  13515. WXS_ITEM_TYPE_NAME(baseItem),
  13516. xmlSchemaGetComponentQName(&str, baseItem),
  13517. NULL);
  13518. FREE_AND_NULL(str)
  13519. return(pctxt->err);
  13520. }
  13521. }
  13522. return(0);
  13523. }
  13524. static int
  13525. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  13526. xmlSchemaBasicItemPtr item,
  13527. xmlSchemaWildcardPtr *completeWild,
  13528. xmlSchemaItemListPtr list,
  13529. xmlSchemaItemListPtr prohibs);
  13530. /**
  13531. * xmlSchemaFixupTypeAttributeUses:
  13532. * @ctxt: the schema parser context
  13533. * @type: the complex type definition
  13534. *
  13535. *
  13536. * Builds the wildcard and the attribute uses on the given complex type.
  13537. * Returns -1 if an internal error occurs, 0 otherwise.
  13538. *
  13539. * ATTENTION TODO: Experimentally this uses pointer comparisons for
  13540. * strings, so recheck this if we start to hardcode some schemata, since
  13541. * they might not be in the same dict.
  13542. * NOTE: It is allowed to "extend" the xs:anyType type.
  13543. */
  13544. static int
  13545. xmlSchemaFixupTypeAttributeUses(xmlSchemaParserCtxtPtr pctxt,
  13546. xmlSchemaTypePtr type)
  13547. {
  13548. xmlSchemaTypePtr baseType = NULL;
  13549. xmlSchemaAttributeUsePtr use;
  13550. xmlSchemaItemListPtr uses, baseUses, prohibs = NULL;
  13551. if (type->baseType == NULL) {
  13552. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13553. "no base type");
  13554. return (-1);
  13555. }
  13556. baseType = type->baseType;
  13557. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13558. if (xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt) == -1)
  13559. return(-1);
  13560. uses = type->attrUses;
  13561. baseUses = baseType->attrUses;
  13562. /*
  13563. * Expand attribute group references. And build the 'complete'
  13564. * wildcard, i.e. intersect multiple wildcards.
  13565. * Move attribute prohibitions into a separate list.
  13566. */
  13567. if (uses != NULL) {
  13568. if (WXS_IS_RESTRICTION(type)) {
  13569. /*
  13570. * This one will transfer all attr. prohibitions
  13571. * into pctxt->attrProhibs.
  13572. */
  13573. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13574. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13575. pctxt->attrProhibs) == -1)
  13576. {
  13577. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13578. "failed to expand attributes");
  13579. }
  13580. if (pctxt->attrProhibs->nbItems != 0)
  13581. prohibs = pctxt->attrProhibs;
  13582. } else {
  13583. if (xmlSchemaExpandAttributeGroupRefs(pctxt,
  13584. WXS_BASIC_CAST type, &(type->attributeWildcard), uses,
  13585. NULL) == -1)
  13586. {
  13587. PERROR_INT("xmlSchemaFixupTypeAttributeUses",
  13588. "failed to expand attributes");
  13589. }
  13590. }
  13591. }
  13592. /*
  13593. * Inherit the attribute uses of the base type.
  13594. */
  13595. if (baseUses != NULL) {
  13596. int i, j;
  13597. xmlSchemaAttributeUseProhibPtr pro;
  13598. if (WXS_IS_RESTRICTION(type)) {
  13599. int usesCount;
  13600. xmlSchemaAttributeUsePtr tmp;
  13601. if (uses != NULL)
  13602. usesCount = uses->nbItems;
  13603. else
  13604. usesCount = 0;
  13605. /* Restriction. */
  13606. for (i = 0; i < baseUses->nbItems; i++) {
  13607. use = baseUses->items[i];
  13608. if (prohibs) {
  13609. /*
  13610. * Filter out prohibited uses.
  13611. */
  13612. for (j = 0; j < prohibs->nbItems; j++) {
  13613. pro = prohibs->items[j];
  13614. if ((WXS_ATTRUSE_DECL_NAME(use) == pro->name) &&
  13615. (WXS_ATTRUSE_DECL_TNS(use) ==
  13616. pro->targetNamespace))
  13617. {
  13618. goto inherit_next;
  13619. }
  13620. }
  13621. }
  13622. if (usesCount) {
  13623. /*
  13624. * Filter out existing uses.
  13625. */
  13626. for (j = 0; j < usesCount; j++) {
  13627. tmp = uses->items[j];
  13628. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  13629. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  13630. (WXS_ATTRUSE_DECL_TNS(use) ==
  13631. WXS_ATTRUSE_DECL_TNS(tmp)))
  13632. {
  13633. goto inherit_next;
  13634. }
  13635. }
  13636. }
  13637. if (uses == NULL) {
  13638. type->attrUses = xmlSchemaItemListCreate();
  13639. if (type->attrUses == NULL)
  13640. goto exit_failure;
  13641. uses = type->attrUses;
  13642. }
  13643. xmlSchemaItemListAddSize(uses, 2, use);
  13644. inherit_next: {}
  13645. }
  13646. } else {
  13647. /* Extension. */
  13648. for (i = 0; i < baseUses->nbItems; i++) {
  13649. use = baseUses->items[i];
  13650. if (uses == NULL) {
  13651. type->attrUses = xmlSchemaItemListCreate();
  13652. if (type->attrUses == NULL)
  13653. goto exit_failure;
  13654. uses = type->attrUses;
  13655. }
  13656. xmlSchemaItemListAddSize(uses, baseUses->nbItems, use);
  13657. }
  13658. }
  13659. }
  13660. /*
  13661. * Shrink attr. uses.
  13662. */
  13663. if (uses) {
  13664. if (uses->nbItems == 0) {
  13665. xmlSchemaItemListFree(uses);
  13666. type->attrUses = NULL;
  13667. }
  13668. /*
  13669. * TODO: We could shrink the size of the array
  13670. * to fit the actual number of items.
  13671. */
  13672. }
  13673. /*
  13674. * Compute the complete wildcard.
  13675. */
  13676. if (WXS_IS_EXTENSION(type)) {
  13677. if (baseType->attributeWildcard != NULL) {
  13678. /*
  13679. * (3.2.2.1) "If the `base wildcard` is non-`absent`, then
  13680. * the appropriate case among the following:"
  13681. */
  13682. if (type->attributeWildcard != NULL) {
  13683. /*
  13684. * Union the complete wildcard with the base wildcard.
  13685. * SPEC {attribute wildcard}
  13686. * (3.2.2.1.2) "otherwise a wildcard whose {process contents}
  13687. * and {annotation} are those of the `complete wildcard`,
  13688. * and whose {namespace constraint} is the intensional union
  13689. * of the {namespace constraint} of the `complete wildcard`
  13690. * and of the `base wildcard`, as defined in Attribute
  13691. * Wildcard Union ($3.10.6)."
  13692. */
  13693. if (xmlSchemaUnionWildcards(pctxt, type->attributeWildcard,
  13694. baseType->attributeWildcard) == -1)
  13695. goto exit_failure;
  13696. } else {
  13697. /*
  13698. * (3.2.2.1.1) "If the `complete wildcard` is `absent`,
  13699. * then the `base wildcard`."
  13700. */
  13701. type->attributeWildcard = baseType->attributeWildcard;
  13702. }
  13703. } else {
  13704. /*
  13705. * (3.2.2.2) "otherwise (the `base wildcard` is `absent`) the
  13706. * `complete wildcard`"
  13707. * NOOP
  13708. */
  13709. }
  13710. } else {
  13711. /*
  13712. * SPEC {attribute wildcard}
  13713. * (3.1) "If the <restriction> alternative is chosen, then the
  13714. * `complete wildcard`;"
  13715. * NOOP
  13716. */
  13717. }
  13718. return (0);
  13719. exit_failure:
  13720. return(-1);
  13721. }
  13722. /**
  13723. * xmlSchemaTypeFinalContains:
  13724. * @schema: the schema
  13725. * @type: the type definition
  13726. * @final: the final
  13727. *
  13728. * Evaluates if a type definition contains the given "final".
  13729. * This does take "finalDefault" into account as well.
  13730. *
  13731. * Returns 1 if the type does contain the given "final",
  13732. * 0 otherwise.
  13733. */
  13734. static int
  13735. xmlSchemaTypeFinalContains(xmlSchemaTypePtr type, int final)
  13736. {
  13737. if (type == NULL)
  13738. return (0);
  13739. if (type->flags & final)
  13740. return (1);
  13741. else
  13742. return (0);
  13743. }
  13744. /**
  13745. * xmlSchemaGetUnionSimpleTypeMemberTypes:
  13746. * @type: the Union Simple Type
  13747. *
  13748. * Returns a list of member types of @type if existing,
  13749. * returns NULL otherwise.
  13750. */
  13751. static xmlSchemaTypeLinkPtr
  13752. xmlSchemaGetUnionSimpleTypeMemberTypes(xmlSchemaTypePtr type)
  13753. {
  13754. while ((type != NULL) && (type->type == XML_SCHEMA_TYPE_SIMPLE)) {
  13755. if (type->memberTypes != NULL)
  13756. return (type->memberTypes);
  13757. else
  13758. type = type->baseType;
  13759. }
  13760. return (NULL);
  13761. }
  13762. /**
  13763. * xmlSchemaGetParticleTotalRangeMin:
  13764. * @particle: the particle
  13765. *
  13766. * Schema Component Constraint: Effective Total Range
  13767. * (all and sequence) + (choice)
  13768. *
  13769. * Returns the minimum Effective Total Range.
  13770. */
  13771. static int
  13772. xmlSchemaGetParticleTotalRangeMin(xmlSchemaParticlePtr particle)
  13773. {
  13774. if ((particle->children == NULL) ||
  13775. (particle->minOccurs == 0))
  13776. return (0);
  13777. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13778. int min = -1, cur;
  13779. xmlSchemaParticlePtr part =
  13780. (xmlSchemaParticlePtr) particle->children->children;
  13781. if (part == NULL)
  13782. return (0);
  13783. while (part != NULL) {
  13784. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13785. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13786. cur = part->minOccurs;
  13787. else
  13788. cur = xmlSchemaGetParticleTotalRangeMin(part);
  13789. if (cur == 0)
  13790. return (0);
  13791. if ((min > cur) || (min == -1))
  13792. min = cur;
  13793. part = (xmlSchemaParticlePtr) part->next;
  13794. }
  13795. return (particle->minOccurs * min);
  13796. } else {
  13797. /* <all> and <sequence> */
  13798. int sum = 0;
  13799. xmlSchemaParticlePtr part =
  13800. (xmlSchemaParticlePtr) particle->children->children;
  13801. if (part == NULL)
  13802. return (0);
  13803. do {
  13804. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13805. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13806. sum += part->minOccurs;
  13807. else
  13808. sum += xmlSchemaGetParticleTotalRangeMin(part);
  13809. part = (xmlSchemaParticlePtr) part->next;
  13810. } while (part != NULL);
  13811. return (particle->minOccurs * sum);
  13812. }
  13813. }
  13814. #if 0
  13815. /**
  13816. * xmlSchemaGetParticleTotalRangeMax:
  13817. * @particle: the particle
  13818. *
  13819. * Schema Component Constraint: Effective Total Range
  13820. * (all and sequence) + (choice)
  13821. *
  13822. * Returns the maximum Effective Total Range.
  13823. */
  13824. static int
  13825. xmlSchemaGetParticleTotalRangeMax(xmlSchemaParticlePtr particle)
  13826. {
  13827. if ((particle->children == NULL) ||
  13828. (particle->children->children == NULL))
  13829. return (0);
  13830. if (particle->children->type == XML_SCHEMA_TYPE_CHOICE) {
  13831. int max = -1, cur;
  13832. xmlSchemaParticlePtr part =
  13833. (xmlSchemaParticlePtr) particle->children->children;
  13834. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13835. if (part->children == NULL)
  13836. continue;
  13837. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13838. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13839. cur = part->maxOccurs;
  13840. else
  13841. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13842. if (cur == UNBOUNDED)
  13843. return (UNBOUNDED);
  13844. if ((max < cur) || (max == -1))
  13845. max = cur;
  13846. }
  13847. /* TODO: Handle overflows? */
  13848. return (particle->maxOccurs * max);
  13849. } else {
  13850. /* <all> and <sequence> */
  13851. int sum = 0, cur;
  13852. xmlSchemaParticlePtr part =
  13853. (xmlSchemaParticlePtr) particle->children->children;
  13854. for (; part != NULL; part = (xmlSchemaParticlePtr) part->next) {
  13855. if (part->children == NULL)
  13856. continue;
  13857. if ((part->children->type == XML_SCHEMA_TYPE_ELEMENT) ||
  13858. (part->children->type == XML_SCHEMA_TYPE_ANY))
  13859. cur = part->maxOccurs;
  13860. else
  13861. cur = xmlSchemaGetParticleTotalRangeMax(part);
  13862. if (cur == UNBOUNDED)
  13863. return (UNBOUNDED);
  13864. if ((cur > 0) && (particle->maxOccurs == UNBOUNDED))
  13865. return (UNBOUNDED);
  13866. sum += cur;
  13867. }
  13868. /* TODO: Handle overflows? */
  13869. return (particle->maxOccurs * sum);
  13870. }
  13871. }
  13872. #endif
  13873. /**
  13874. * xmlSchemaIsParticleEmptiable:
  13875. * @particle: the particle
  13876. *
  13877. * Schema Component Constraint: Particle Emptiable
  13878. * Checks whether the given particle is emptiable.
  13879. *
  13880. * Returns 1 if emptiable, 0 otherwise.
  13881. */
  13882. static int
  13883. xmlSchemaIsParticleEmptiable(xmlSchemaParticlePtr particle)
  13884. {
  13885. /*
  13886. * SPEC (1) "Its {min occurs} is 0."
  13887. */
  13888. if ((particle == NULL) || (particle->minOccurs == 0) ||
  13889. (particle->children == NULL))
  13890. return (1);
  13891. /*
  13892. * SPEC (2) "Its {term} is a group and the minimum part of the
  13893. * effective total range of that group, [...] is 0."
  13894. */
  13895. if (WXS_IS_MODEL_GROUP(particle->children)) {
  13896. if (xmlSchemaGetParticleTotalRangeMin(particle) == 0)
  13897. return (1);
  13898. }
  13899. return (0);
  13900. }
  13901. /**
  13902. * xmlSchemaCheckCOSSTDerivedOK:
  13903. * @actxt: a context
  13904. * @type: the derived simple type definition
  13905. * @baseType: the base type definition
  13906. * @subset: the subset of ('restriction', etc.)
  13907. *
  13908. * Schema Component Constraint:
  13909. * Type Derivation OK (Simple) (cos-st-derived-OK)
  13910. *
  13911. * Checks whether @type can be validly
  13912. * derived from @baseType.
  13913. *
  13914. * Returns 0 on success, an positive error code otherwise.
  13915. */
  13916. static int
  13917. xmlSchemaCheckCOSSTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  13918. xmlSchemaTypePtr type,
  13919. xmlSchemaTypePtr baseType,
  13920. int subset)
  13921. {
  13922. /*
  13923. * 1 They are the same type definition.
  13924. * TODO: The identity check might have to be more complex than this.
  13925. */
  13926. if (type == baseType)
  13927. return (0);
  13928. /*
  13929. * 2.1 restriction is not in the subset, or in the {final}
  13930. * of its own {base type definition};
  13931. *
  13932. * NOTE that this will be used also via "xsi:type".
  13933. *
  13934. * TODO: Revise this, it looks strange. How can the "type"
  13935. * not be fixed or *in* fixing?
  13936. */
  13937. if (WXS_IS_TYPE_NOT_FIXED(type))
  13938. if (xmlSchemaTypeFixup(type, actxt) == -1)
  13939. return(-1);
  13940. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  13941. if (xmlSchemaTypeFixup(baseType, actxt) == -1)
  13942. return(-1);
  13943. if ((subset & SUBSET_RESTRICTION) ||
  13944. (xmlSchemaTypeFinalContains(type->baseType,
  13945. XML_SCHEMAS_TYPE_FINAL_RESTRICTION))) {
  13946. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_1);
  13947. }
  13948. /* 2.2 */
  13949. if (type->baseType == baseType) {
  13950. /*
  13951. * 2.2.1 D's `base type definition` is B.
  13952. */
  13953. return (0);
  13954. }
  13955. /*
  13956. * 2.2.2 D's `base type definition` is not the `ur-type definition`
  13957. * and is validly derived from B given the subset, as defined by this
  13958. * constraint.
  13959. */
  13960. if ((! WXS_IS_ANYTYPE(type->baseType)) &&
  13961. (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  13962. baseType, subset) == 0)) {
  13963. return (0);
  13964. }
  13965. /*
  13966. * 2.2.3 D's {variety} is list or union and B is the `simple ur-type
  13967. * definition`.
  13968. */
  13969. if (WXS_IS_ANY_SIMPLE_TYPE(baseType) &&
  13970. (WXS_IS_LIST(type) || WXS_IS_UNION(type))) {
  13971. return (0);
  13972. }
  13973. /*
  13974. * 2.2.4 B's {variety} is union and D is validly derived from a type
  13975. * definition in B's {member type definitions} given the subset, as
  13976. * defined by this constraint.
  13977. *
  13978. * NOTE: This seems not to involve built-in types, since there is no
  13979. * built-in Union Simple Type.
  13980. */
  13981. if (WXS_IS_UNION(baseType)) {
  13982. xmlSchemaTypeLinkPtr cur;
  13983. cur = baseType->memberTypes;
  13984. while (cur != NULL) {
  13985. if (WXS_IS_TYPE_NOT_FIXED(cur->type))
  13986. if (xmlSchemaTypeFixup(cur->type, actxt) == -1)
  13987. return(-1);
  13988. if (xmlSchemaCheckCOSSTDerivedOK(actxt,
  13989. type, cur->type, subset) == 0)
  13990. {
  13991. /*
  13992. * It just has to be validly derived from at least one
  13993. * member-type.
  13994. */
  13995. return (0);
  13996. }
  13997. cur = cur->next;
  13998. }
  13999. }
  14000. return (XML_SCHEMAP_COS_ST_DERIVED_OK_2_2);
  14001. }
  14002. /**
  14003. * xmlSchemaCheckTypeDefCircularInternal:
  14004. * @pctxt: the schema parser context
  14005. * @ctxtType: the type definition
  14006. * @ancestor: an ancestor of @ctxtType
  14007. *
  14008. * Checks st-props-correct (2) + ct-props-correct (3).
  14009. * Circular type definitions are not allowed.
  14010. *
  14011. * Returns XML_SCHEMAP_ST_PROPS_CORRECT_2 if the given type is
  14012. * circular, 0 otherwise.
  14013. */
  14014. static int
  14015. xmlSchemaCheckTypeDefCircularInternal(xmlSchemaParserCtxtPtr pctxt,
  14016. xmlSchemaTypePtr ctxtType,
  14017. xmlSchemaTypePtr ancestor)
  14018. {
  14019. int ret;
  14020. if ((ancestor == NULL) || (ancestor->type == XML_SCHEMA_TYPE_BASIC))
  14021. return (0);
  14022. if (ctxtType == ancestor) {
  14023. xmlSchemaPCustomErr(pctxt,
  14024. XML_SCHEMAP_ST_PROPS_CORRECT_2,
  14025. WXS_BASIC_CAST ctxtType, WXS_ITEM_NODE(ctxtType),
  14026. "The definition is circular", NULL);
  14027. return (XML_SCHEMAP_ST_PROPS_CORRECT_2);
  14028. }
  14029. if (ancestor->flags & XML_SCHEMAS_TYPE_MARKED) {
  14030. /*
  14031. * Avoid inifinite recursion on circular types not yet checked.
  14032. */
  14033. return (0);
  14034. }
  14035. ancestor->flags |= XML_SCHEMAS_TYPE_MARKED;
  14036. ret = xmlSchemaCheckTypeDefCircularInternal(pctxt, ctxtType,
  14037. ancestor->baseType);
  14038. ancestor->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14039. return (ret);
  14040. }
  14041. /**
  14042. * xmlSchemaCheckTypeDefCircular:
  14043. * @item: the complex/simple type definition
  14044. * @ctxt: the parser context
  14045. * @name: the name
  14046. *
  14047. * Checks for circular type definitions.
  14048. */
  14049. static void
  14050. xmlSchemaCheckTypeDefCircular(xmlSchemaTypePtr item,
  14051. xmlSchemaParserCtxtPtr ctxt)
  14052. {
  14053. if ((item == NULL) ||
  14054. (item->type == XML_SCHEMA_TYPE_BASIC) ||
  14055. (item->baseType == NULL))
  14056. return;
  14057. xmlSchemaCheckTypeDefCircularInternal(ctxt, item,
  14058. item->baseType);
  14059. }
  14060. /*
  14061. * Simple Type Definition Representation OK (src-simple-type) 4
  14062. *
  14063. * "4 Circular union type definition is disallowed. That is, if the
  14064. * <union> alternative is chosen, there must not be any entries in the
  14065. * memberTypes [attribute] at any depth which resolve to the component
  14066. * corresponding to the <simpleType>."
  14067. *
  14068. * Note that this should work on the *representation* of a component,
  14069. * thus assumes any union types in the member types not being yet
  14070. * substituted. At this stage we need the variety of the types
  14071. * to be already computed.
  14072. */
  14073. static int
  14074. xmlSchemaCheckUnionTypeDefCircularRecur(xmlSchemaParserCtxtPtr pctxt,
  14075. xmlSchemaTypePtr ctxType,
  14076. xmlSchemaTypeLinkPtr members)
  14077. {
  14078. xmlSchemaTypeLinkPtr member;
  14079. xmlSchemaTypePtr memberType;
  14080. member = members;
  14081. while (member != NULL) {
  14082. memberType = member->type;
  14083. while ((memberType != NULL) &&
  14084. (memberType->type != XML_SCHEMA_TYPE_BASIC)) {
  14085. if (memberType == ctxType) {
  14086. xmlSchemaPCustomErr(pctxt,
  14087. XML_SCHEMAP_SRC_SIMPLE_TYPE_4,
  14088. WXS_BASIC_CAST ctxType, NULL,
  14089. "The union type definition is circular", NULL);
  14090. return (XML_SCHEMAP_SRC_SIMPLE_TYPE_4);
  14091. }
  14092. if ((WXS_IS_UNION(memberType)) &&
  14093. ((memberType->flags & XML_SCHEMAS_TYPE_MARKED) == 0))
  14094. {
  14095. int res;
  14096. memberType->flags |= XML_SCHEMAS_TYPE_MARKED;
  14097. res = xmlSchemaCheckUnionTypeDefCircularRecur(pctxt,
  14098. ctxType,
  14099. xmlSchemaGetUnionSimpleTypeMemberTypes(memberType));
  14100. memberType->flags ^= XML_SCHEMAS_TYPE_MARKED;
  14101. if (res != 0)
  14102. return(res);
  14103. }
  14104. memberType = memberType->baseType;
  14105. }
  14106. member = member->next;
  14107. }
  14108. return(0);
  14109. }
  14110. static int
  14111. xmlSchemaCheckUnionTypeDefCircular(xmlSchemaParserCtxtPtr pctxt,
  14112. xmlSchemaTypePtr type)
  14113. {
  14114. if (! WXS_IS_UNION(type))
  14115. return(0);
  14116. return(xmlSchemaCheckUnionTypeDefCircularRecur(pctxt, type,
  14117. type->memberTypes));
  14118. }
  14119. /**
  14120. * xmlSchemaResolveTypeReferences:
  14121. * @item: the complex/simple type definition
  14122. * @ctxt: the parser context
  14123. * @name: the name
  14124. *
  14125. * Resolves type definition references
  14126. */
  14127. static void
  14128. xmlSchemaResolveTypeReferences(xmlSchemaTypePtr typeDef,
  14129. xmlSchemaParserCtxtPtr ctxt)
  14130. {
  14131. if (typeDef == NULL)
  14132. return;
  14133. /*
  14134. * Resolve the base type.
  14135. */
  14136. if (typeDef->baseType == NULL) {
  14137. typeDef->baseType = xmlSchemaGetType(ctxt->schema,
  14138. typeDef->base, typeDef->baseNs);
  14139. if (typeDef->baseType == NULL) {
  14140. xmlSchemaPResCompAttrErr(ctxt,
  14141. XML_SCHEMAP_SRC_RESOLVE,
  14142. WXS_BASIC_CAST typeDef, typeDef->node,
  14143. "base", typeDef->base, typeDef->baseNs,
  14144. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14145. return;
  14146. }
  14147. }
  14148. if (WXS_IS_SIMPLE(typeDef)) {
  14149. if (WXS_IS_UNION(typeDef)) {
  14150. /*
  14151. * Resolve the memberTypes.
  14152. */
  14153. xmlSchemaResolveUnionMemberTypes(ctxt, typeDef);
  14154. return;
  14155. } else if (WXS_IS_LIST(typeDef)) {
  14156. /*
  14157. * Resolve the itemType.
  14158. */
  14159. if ((typeDef->subtypes == NULL) && (typeDef->base != NULL)) {
  14160. typeDef->subtypes = xmlSchemaGetType(ctxt->schema,
  14161. typeDef->base, typeDef->baseNs);
  14162. if ((typeDef->subtypes == NULL) ||
  14163. (! WXS_IS_SIMPLE(typeDef->subtypes)))
  14164. {
  14165. typeDef->subtypes = NULL;
  14166. xmlSchemaPResCompAttrErr(ctxt,
  14167. XML_SCHEMAP_SRC_RESOLVE,
  14168. WXS_BASIC_CAST typeDef, typeDef->node,
  14169. "itemType", typeDef->base, typeDef->baseNs,
  14170. XML_SCHEMA_TYPE_SIMPLE, NULL);
  14171. }
  14172. }
  14173. return;
  14174. }
  14175. }
  14176. /*
  14177. * The ball of letters below means, that if we have a particle
  14178. * which has a QName-helper component as its {term}, we want
  14179. * to resolve it...
  14180. */
  14181. else if ((WXS_TYPE_CONTENTTYPE(typeDef) != NULL) &&
  14182. ((WXS_TYPE_CONTENTTYPE(typeDef))->type ==
  14183. XML_SCHEMA_TYPE_PARTICLE) &&
  14184. (WXS_TYPE_PARTICLE_TERM(typeDef) != NULL) &&
  14185. ((WXS_TYPE_PARTICLE_TERM(typeDef))->type ==
  14186. XML_SCHEMA_EXTRA_QNAMEREF))
  14187. {
  14188. xmlSchemaQNameRefPtr ref =
  14189. WXS_QNAME_CAST WXS_TYPE_PARTICLE_TERM(typeDef);
  14190. xmlSchemaModelGroupDefPtr groupDef;
  14191. /*
  14192. * URGENT TODO: Test this.
  14193. */
  14194. WXS_TYPE_PARTICLE_TERM(typeDef) = NULL;
  14195. /*
  14196. * Resolve the MG definition reference.
  14197. */
  14198. groupDef =
  14199. WXS_MODEL_GROUPDEF_CAST xmlSchemaGetNamedComponent(ctxt->schema,
  14200. ref->itemType, ref->name, ref->targetNamespace);
  14201. if (groupDef == NULL) {
  14202. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  14203. NULL, WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)),
  14204. "ref", ref->name, ref->targetNamespace, ref->itemType,
  14205. NULL);
  14206. /* Remove the particle. */
  14207. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14208. } else if (WXS_MODELGROUPDEF_MODEL(groupDef) == NULL)
  14209. /* Remove the particle. */
  14210. WXS_TYPE_CONTENTTYPE(typeDef) = NULL;
  14211. else {
  14212. /*
  14213. * Assign the MG definition's {model group} to the
  14214. * particle's {term}.
  14215. */
  14216. WXS_TYPE_PARTICLE_TERM(typeDef) = WXS_MODELGROUPDEF_MODEL(groupDef);
  14217. if (WXS_MODELGROUPDEF_MODEL(groupDef)->type == XML_SCHEMA_TYPE_ALL) {
  14218. /*
  14219. * SPEC cos-all-limited (1.2)
  14220. * "1.2 the {term} property of a particle with
  14221. * {max occurs}=1 which is part of a pair which constitutes
  14222. * the {content type} of a complex type definition."
  14223. */
  14224. if ((WXS_TYPE_PARTICLE(typeDef))->maxOccurs != 1) {
  14225. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  14226. /* TODO: error code */
  14227. XML_SCHEMAP_COS_ALL_LIMITED,
  14228. WXS_ITEM_NODE(WXS_TYPE_PARTICLE(typeDef)), NULL,
  14229. "The particle's {max occurs} must be 1, since the "
  14230. "reference resolves to an 'all' model group",
  14231. NULL, NULL);
  14232. }
  14233. }
  14234. }
  14235. }
  14236. }
  14237. /**
  14238. * xmlSchemaCheckSTPropsCorrect:
  14239. * @ctxt: the schema parser context
  14240. * @type: the simple type definition
  14241. *
  14242. * Checks st-props-correct.
  14243. *
  14244. * Returns 0 if the properties are correct,
  14245. * if not, a positive error code and -1 on internal
  14246. * errors.
  14247. */
  14248. static int
  14249. xmlSchemaCheckSTPropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  14250. xmlSchemaTypePtr type)
  14251. {
  14252. xmlSchemaTypePtr baseType = type->baseType;
  14253. xmlChar *str = NULL;
  14254. /* STATE: error funcs converted. */
  14255. /*
  14256. * Schema Component Constraint: Simple Type Definition Properties Correct
  14257. *
  14258. * NOTE: This is somehow redundant, since we actually built a simple type
  14259. * to have all the needed information; this acts as an self test.
  14260. */
  14261. /* Base type: If the datatype has been `derived` by `restriction`
  14262. * then the Simple Type Definition component from which it is `derived`,
  14263. * otherwise the Simple Type Definition for anySimpleType ($4.1.6).
  14264. */
  14265. if (baseType == NULL) {
  14266. /*
  14267. * TODO: Think about: "modulo the impact of Missing
  14268. * Sub-components ($5.3)."
  14269. */
  14270. xmlSchemaPCustomErr(ctxt,
  14271. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14272. WXS_BASIC_CAST type, NULL,
  14273. "No base type existent", NULL);
  14274. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14275. }
  14276. if (! WXS_IS_SIMPLE(baseType)) {
  14277. xmlSchemaPCustomErr(ctxt,
  14278. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14279. WXS_BASIC_CAST type, NULL,
  14280. "The base type '%s' is not a simple type",
  14281. xmlSchemaGetComponentQName(&str, baseType));
  14282. FREE_AND_NULL(str)
  14283. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14284. }
  14285. if ((WXS_IS_LIST(type) || WXS_IS_UNION(type)) &&
  14286. (WXS_IS_RESTRICTION(type) == 0) &&
  14287. ((! WXS_IS_ANY_SIMPLE_TYPE(baseType)) &&
  14288. (baseType->type != XML_SCHEMA_TYPE_SIMPLE))) {
  14289. xmlSchemaPCustomErr(ctxt,
  14290. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14291. WXS_BASIC_CAST type, NULL,
  14292. "A type, derived by list or union, must have "
  14293. "the simple ur-type definition as base type, not '%s'",
  14294. xmlSchemaGetComponentQName(&str, baseType));
  14295. FREE_AND_NULL(str)
  14296. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14297. }
  14298. /*
  14299. * Variety: One of {atomic, list, union}.
  14300. */
  14301. if ((! WXS_IS_ATOMIC(type)) && (! WXS_IS_UNION(type)) &&
  14302. (! WXS_IS_LIST(type))) {
  14303. xmlSchemaPCustomErr(ctxt,
  14304. XML_SCHEMAP_ST_PROPS_CORRECT_1,
  14305. WXS_BASIC_CAST type, NULL,
  14306. "The variety is absent", NULL);
  14307. return (XML_SCHEMAP_ST_PROPS_CORRECT_1);
  14308. }
  14309. /* TODO: Finish this. Hmm, is this finished? */
  14310. /*
  14311. * 3 The {final} of the {base type definition} must not contain restriction.
  14312. */
  14313. if (xmlSchemaTypeFinalContains(baseType,
  14314. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14315. xmlSchemaPCustomErr(ctxt,
  14316. XML_SCHEMAP_ST_PROPS_CORRECT_3,
  14317. WXS_BASIC_CAST type, NULL,
  14318. "The 'final' of its base type '%s' must not contain "
  14319. "'restriction'",
  14320. xmlSchemaGetComponentQName(&str, baseType));
  14321. FREE_AND_NULL(str)
  14322. return (XML_SCHEMAP_ST_PROPS_CORRECT_3);
  14323. }
  14324. /*
  14325. * 2 All simple type definitions must be derived ultimately from the `simple
  14326. * ur-type definition` (so circular definitions are disallowed). That is, it
  14327. * must be possible to reach a built-in primitive datatype or the `simple
  14328. * ur-type definition` by repeatedly following the {base type definition}.
  14329. *
  14330. * NOTE: this is done in xmlSchemaCheckTypeDefCircular().
  14331. */
  14332. return (0);
  14333. }
  14334. /**
  14335. * xmlSchemaCheckCOSSTRestricts:
  14336. * @ctxt: the schema parser context
  14337. * @type: the simple type definition
  14338. *
  14339. * Schema Component Constraint:
  14340. * Derivation Valid (Restriction, Simple) (cos-st-restricts)
  14341. * Checks if the given @type (simpleType) is derived validly by restriction.
  14342. * STATUS:
  14343. *
  14344. * Returns -1 on internal errors, 0 if the type is validly derived,
  14345. * a positive error code otherwise.
  14346. */
  14347. static int
  14348. xmlSchemaCheckCOSSTRestricts(xmlSchemaParserCtxtPtr pctxt,
  14349. xmlSchemaTypePtr type)
  14350. {
  14351. xmlChar *str = NULL;
  14352. if (type->type != XML_SCHEMA_TYPE_SIMPLE) {
  14353. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14354. "given type is not a user-derived simpleType");
  14355. return (-1);
  14356. }
  14357. if (WXS_IS_ATOMIC(type)) {
  14358. xmlSchemaTypePtr primitive;
  14359. /*
  14360. * 1.1 The {base type definition} must be an atomic simple
  14361. * type definition or a built-in primitive datatype.
  14362. */
  14363. if (! WXS_IS_ATOMIC(type->baseType)) {
  14364. xmlSchemaPCustomErr(pctxt,
  14365. XML_SCHEMAP_COS_ST_RESTRICTS_1_1,
  14366. WXS_BASIC_CAST type, NULL,
  14367. "The base type '%s' is not an atomic simple type",
  14368. xmlSchemaGetComponentQName(&str, type->baseType));
  14369. FREE_AND_NULL(str)
  14370. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_1);
  14371. }
  14372. /* 1.2 The {final} of the {base type definition} must not contain
  14373. * restriction.
  14374. */
  14375. /* OPTIMIZE TODO : This is already done in xmlSchemaCheckStPropsCorrect */
  14376. if (xmlSchemaTypeFinalContains(type->baseType,
  14377. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14378. xmlSchemaPCustomErr(pctxt,
  14379. XML_SCHEMAP_COS_ST_RESTRICTS_1_2,
  14380. WXS_BASIC_CAST type, NULL,
  14381. "The final of its base type '%s' must not contain 'restriction'",
  14382. xmlSchemaGetComponentQName(&str, type->baseType));
  14383. FREE_AND_NULL(str)
  14384. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_2);
  14385. }
  14386. /*
  14387. * 1.3.1 DF must be an allowed constraining facet for the {primitive
  14388. * type definition}, as specified in the appropriate subsection of 3.2
  14389. * Primitive datatypes.
  14390. */
  14391. if (type->facets != NULL) {
  14392. xmlSchemaFacetPtr facet;
  14393. int ok = 1;
  14394. primitive = xmlSchemaGetPrimitiveType(type);
  14395. if (primitive == NULL) {
  14396. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14397. "failed to get primitive type");
  14398. return (-1);
  14399. }
  14400. facet = type->facets;
  14401. do {
  14402. if (xmlSchemaIsBuiltInTypeFacet(primitive, facet->type) == 0) {
  14403. ok = 0;
  14404. xmlSchemaPIllegalFacetAtomicErr(pctxt,
  14405. XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1,
  14406. type, primitive, facet);
  14407. }
  14408. facet = facet->next;
  14409. } while (facet != NULL);
  14410. if (ok == 0)
  14411. return (XML_SCHEMAP_COS_ST_RESTRICTS_1_3_1);
  14412. }
  14413. /*
  14414. * SPEC (1.3.2) "If there is a facet of the same kind in the {facets}
  14415. * of the {base type definition} (call this BF),then the DF's {value}
  14416. * must be a valid restriction of BF's {value} as defined in
  14417. * [XML Schemas: Datatypes]."
  14418. *
  14419. * NOTE (1.3.2) Facet derivation constraints are currently handled in
  14420. * xmlSchemaDeriveAndValidateFacets()
  14421. */
  14422. } else if (WXS_IS_LIST(type)) {
  14423. xmlSchemaTypePtr itemType = NULL;
  14424. itemType = type->subtypes;
  14425. if ((itemType == NULL) || (! WXS_IS_SIMPLE(itemType))) {
  14426. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14427. "failed to evaluate the item type");
  14428. return (-1);
  14429. }
  14430. if (WXS_IS_TYPE_NOT_FIXED(itemType))
  14431. xmlSchemaTypeFixup(itemType, ACTXT_CAST pctxt);
  14432. /*
  14433. * 2.1 The {item type definition} must have a {variety} of atomic or
  14434. * union (in which case all the {member type definitions}
  14435. * must be atomic).
  14436. */
  14437. if ((! WXS_IS_ATOMIC(itemType)) &&
  14438. (! WXS_IS_UNION(itemType))) {
  14439. xmlSchemaPCustomErr(pctxt,
  14440. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14441. WXS_BASIC_CAST type, NULL,
  14442. "The item type '%s' does not have a variety of atomic or union",
  14443. xmlSchemaGetComponentQName(&str, itemType));
  14444. FREE_AND_NULL(str)
  14445. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14446. } else if (WXS_IS_UNION(itemType)) {
  14447. xmlSchemaTypeLinkPtr member;
  14448. member = itemType->memberTypes;
  14449. while (member != NULL) {
  14450. if (! WXS_IS_ATOMIC(member->type)) {
  14451. xmlSchemaPCustomErr(pctxt,
  14452. XML_SCHEMAP_COS_ST_RESTRICTS_2_1,
  14453. WXS_BASIC_CAST type, NULL,
  14454. "The item type is a union type, but the "
  14455. "member type '%s' of this item type is not atomic",
  14456. xmlSchemaGetComponentQName(&str, member->type));
  14457. FREE_AND_NULL(str)
  14458. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_1);
  14459. }
  14460. member = member->next;
  14461. }
  14462. }
  14463. if (WXS_IS_ANY_SIMPLE_TYPE(type->baseType)) {
  14464. xmlSchemaFacetPtr facet;
  14465. /*
  14466. * This is the case if we have: <simpleType><list ..
  14467. */
  14468. /*
  14469. * 2.3.1
  14470. * 2.3.1.1 The {final} of the {item type definition} must not
  14471. * contain list.
  14472. */
  14473. if (xmlSchemaTypeFinalContains(itemType,
  14474. XML_SCHEMAS_TYPE_FINAL_LIST)) {
  14475. xmlSchemaPCustomErr(pctxt,
  14476. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1,
  14477. WXS_BASIC_CAST type, NULL,
  14478. "The final of its item type '%s' must not contain 'list'",
  14479. xmlSchemaGetComponentQName(&str, itemType));
  14480. FREE_AND_NULL(str)
  14481. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_1);
  14482. }
  14483. /*
  14484. * 2.3.1.2 The {facets} must only contain the whiteSpace
  14485. * facet component.
  14486. * OPTIMIZE TODO: the S4S already disallows any facet
  14487. * to be specified.
  14488. */
  14489. if (type->facets != NULL) {
  14490. facet = type->facets;
  14491. do {
  14492. if (facet->type != XML_SCHEMA_FACET_WHITESPACE) {
  14493. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14494. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2,
  14495. type, facet);
  14496. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_1_2);
  14497. }
  14498. facet = facet->next;
  14499. } while (facet != NULL);
  14500. }
  14501. /*
  14502. * MAYBE TODO: (Hmm, not really) Datatypes states:
  14503. * A `list` datatype can be `derived` from an `atomic` datatype
  14504. * whose `lexical space` allows space (such as string or anyURI)or
  14505. * a `union` datatype any of whose {member type definitions}'s
  14506. * `lexical space` allows space.
  14507. */
  14508. } else {
  14509. /*
  14510. * This is the case if we have: <simpleType><restriction ...
  14511. * I.e. the variety of "list" is inherited.
  14512. */
  14513. /*
  14514. * 2.3.2
  14515. * 2.3.2.1 The {base type definition} must have a {variety} of list.
  14516. */
  14517. if (! WXS_IS_LIST(type->baseType)) {
  14518. xmlSchemaPCustomErr(pctxt,
  14519. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1,
  14520. WXS_BASIC_CAST type, NULL,
  14521. "The base type '%s' must be a list type",
  14522. xmlSchemaGetComponentQName(&str, type->baseType));
  14523. FREE_AND_NULL(str)
  14524. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_1);
  14525. }
  14526. /*
  14527. * 2.3.2.2 The {final} of the {base type definition} must not
  14528. * contain restriction.
  14529. */
  14530. if (xmlSchemaTypeFinalContains(type->baseType,
  14531. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14532. xmlSchemaPCustomErr(pctxt,
  14533. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2,
  14534. WXS_BASIC_CAST type, NULL,
  14535. "The 'final' of the base type '%s' must not contain 'restriction'",
  14536. xmlSchemaGetComponentQName(&str, type->baseType));
  14537. FREE_AND_NULL(str)
  14538. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_2);
  14539. }
  14540. /*
  14541. * 2.3.2.3 The {item type definition} must be validly derived
  14542. * from the {base type definition}'s {item type definition} given
  14543. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6).
  14544. */
  14545. {
  14546. xmlSchemaTypePtr baseItemType;
  14547. baseItemType = type->baseType->subtypes;
  14548. if ((baseItemType == NULL) || (! WXS_IS_SIMPLE(baseItemType))) {
  14549. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14550. "failed to eval the item type of a base type");
  14551. return (-1);
  14552. }
  14553. if ((itemType != baseItemType) &&
  14554. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt, itemType,
  14555. baseItemType, 0) != 0)) {
  14556. xmlChar *strBIT = NULL, *strBT = NULL;
  14557. xmlSchemaPCustomErrExt(pctxt,
  14558. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3,
  14559. WXS_BASIC_CAST type, NULL,
  14560. "The item type '%s' is not validly derived from "
  14561. "the item type '%s' of the base type '%s'",
  14562. xmlSchemaGetComponentQName(&str, itemType),
  14563. xmlSchemaGetComponentQName(&strBIT, baseItemType),
  14564. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14565. FREE_AND_NULL(str)
  14566. FREE_AND_NULL(strBIT)
  14567. FREE_AND_NULL(strBT)
  14568. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_3);
  14569. }
  14570. }
  14571. if (type->facets != NULL) {
  14572. xmlSchemaFacetPtr facet;
  14573. int ok = 1;
  14574. /*
  14575. * 2.3.2.4 Only length, minLength, maxLength, whiteSpace, pattern
  14576. * and enumeration facet components are allowed among the {facets}.
  14577. */
  14578. facet = type->facets;
  14579. do {
  14580. switch (facet->type) {
  14581. case XML_SCHEMA_FACET_LENGTH:
  14582. case XML_SCHEMA_FACET_MINLENGTH:
  14583. case XML_SCHEMA_FACET_MAXLENGTH:
  14584. case XML_SCHEMA_FACET_WHITESPACE:
  14585. /*
  14586. * TODO: 2.5.1.2 List datatypes
  14587. * The value of `whiteSpace` is fixed to the value collapse.
  14588. */
  14589. case XML_SCHEMA_FACET_PATTERN:
  14590. case XML_SCHEMA_FACET_ENUMERATION:
  14591. break;
  14592. default: {
  14593. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14594. XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4,
  14595. type, facet);
  14596. /*
  14597. * We could return, but it's nicer to report all
  14598. * invalid facets.
  14599. */
  14600. ok = 0;
  14601. }
  14602. }
  14603. facet = facet->next;
  14604. } while (facet != NULL);
  14605. if (ok == 0)
  14606. return (XML_SCHEMAP_COS_ST_RESTRICTS_2_3_2_4);
  14607. /*
  14608. * SPEC (2.3.2.5) (same as 1.3.2)
  14609. *
  14610. * NOTE (2.3.2.5) This is currently done in
  14611. * xmlSchemaDeriveAndValidateFacets()
  14612. */
  14613. }
  14614. }
  14615. } else if (WXS_IS_UNION(type)) {
  14616. /*
  14617. * 3.1 The {member type definitions} must all have {variety} of
  14618. * atomic or list.
  14619. */
  14620. xmlSchemaTypeLinkPtr member;
  14621. member = type->memberTypes;
  14622. while (member != NULL) {
  14623. if (WXS_IS_TYPE_NOT_FIXED(member->type))
  14624. xmlSchemaTypeFixup(member->type, ACTXT_CAST pctxt);
  14625. if ((! WXS_IS_ATOMIC(member->type)) &&
  14626. (! WXS_IS_LIST(member->type))) {
  14627. xmlSchemaPCustomErr(pctxt,
  14628. XML_SCHEMAP_COS_ST_RESTRICTS_3_1,
  14629. WXS_BASIC_CAST type, NULL,
  14630. "The member type '%s' is neither an atomic, nor a list type",
  14631. xmlSchemaGetComponentQName(&str, member->type));
  14632. FREE_AND_NULL(str)
  14633. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_1);
  14634. }
  14635. member = member->next;
  14636. }
  14637. /*
  14638. * 3.3.1 If the {base type definition} is the `simple ur-type
  14639. * definition`
  14640. */
  14641. if (type->baseType->builtInType == XML_SCHEMAS_ANYSIMPLETYPE) {
  14642. /*
  14643. * 3.3.1.1 All of the {member type definitions} must have a
  14644. * {final} which does not contain union.
  14645. */
  14646. member = type->memberTypes;
  14647. while (member != NULL) {
  14648. if (xmlSchemaTypeFinalContains(member->type,
  14649. XML_SCHEMAS_TYPE_FINAL_UNION)) {
  14650. xmlSchemaPCustomErr(pctxt,
  14651. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1,
  14652. WXS_BASIC_CAST type, NULL,
  14653. "The 'final' of member type '%s' contains 'union'",
  14654. xmlSchemaGetComponentQName(&str, member->type));
  14655. FREE_AND_NULL(str)
  14656. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1);
  14657. }
  14658. member = member->next;
  14659. }
  14660. /*
  14661. * 3.3.1.2 The {facets} must be empty.
  14662. */
  14663. if (type->facetSet != NULL) {
  14664. xmlSchemaPCustomErr(pctxt,
  14665. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2,
  14666. WXS_BASIC_CAST type, NULL,
  14667. "No facets allowed", NULL);
  14668. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_1_2);
  14669. }
  14670. } else {
  14671. /*
  14672. * 3.3.2.1 The {base type definition} must have a {variety} of union.
  14673. * I.e. the variety of "list" is inherited.
  14674. */
  14675. if (! WXS_IS_UNION(type->baseType)) {
  14676. xmlSchemaPCustomErr(pctxt,
  14677. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1,
  14678. WXS_BASIC_CAST type, NULL,
  14679. "The base type '%s' is not a union type",
  14680. xmlSchemaGetComponentQName(&str, type->baseType));
  14681. FREE_AND_NULL(str)
  14682. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_1);
  14683. }
  14684. /*
  14685. * 3.3.2.2 The {final} of the {base type definition} must not contain restriction.
  14686. */
  14687. if (xmlSchemaTypeFinalContains(type->baseType,
  14688. XML_SCHEMAS_TYPE_FINAL_RESTRICTION)) {
  14689. xmlSchemaPCustomErr(pctxt,
  14690. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2,
  14691. WXS_BASIC_CAST type, NULL,
  14692. "The 'final' of its base type '%s' must not contain 'restriction'",
  14693. xmlSchemaGetComponentQName(&str, type->baseType));
  14694. FREE_AND_NULL(str)
  14695. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_2);
  14696. }
  14697. /*
  14698. * 3.3.2.3 The {member type definitions}, in order, must be validly
  14699. * derived from the corresponding type definitions in the {base
  14700. * type definition}'s {member type definitions} given the empty set,
  14701. * as defined in Type Derivation OK (Simple) ($3.14.6).
  14702. */
  14703. {
  14704. xmlSchemaTypeLinkPtr baseMember;
  14705. /*
  14706. * OPTIMIZE: if the type is restricting, it has no local defined
  14707. * member types and inherits the member types of the base type;
  14708. * thus a check for equality can be skipped.
  14709. */
  14710. /*
  14711. * Even worse: I cannot see a scenario where a restricting
  14712. * union simple type can have other member types as the member
  14713. * types of it's base type. This check seems not necessary with
  14714. * respect to the derivation process in libxml2.
  14715. * But necessary if constructing types with an API.
  14716. */
  14717. if (type->memberTypes != NULL) {
  14718. member = type->memberTypes;
  14719. baseMember = xmlSchemaGetUnionSimpleTypeMemberTypes(type->baseType);
  14720. if ((member == NULL) && (baseMember != NULL)) {
  14721. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14722. "different number of member types in base");
  14723. }
  14724. while (member != NULL) {
  14725. if (baseMember == NULL) {
  14726. PERROR_INT("xmlSchemaCheckCOSSTRestricts",
  14727. "different number of member types in base");
  14728. } else if ((member->type != baseMember->type) &&
  14729. (xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST pctxt,
  14730. member->type, baseMember->type, 0) != 0)) {
  14731. xmlChar *strBMT = NULL, *strBT = NULL;
  14732. xmlSchemaPCustomErrExt(pctxt,
  14733. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3,
  14734. WXS_BASIC_CAST type, NULL,
  14735. "The member type %s is not validly "
  14736. "derived from its corresponding member "
  14737. "type %s of the base type %s",
  14738. xmlSchemaGetComponentQName(&str, member->type),
  14739. xmlSchemaGetComponentQName(&strBMT, baseMember->type),
  14740. xmlSchemaGetComponentQName(&strBT, type->baseType));
  14741. FREE_AND_NULL(str)
  14742. FREE_AND_NULL(strBMT)
  14743. FREE_AND_NULL(strBT)
  14744. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_3);
  14745. }
  14746. member = member->next;
  14747. if (baseMember != NULL)
  14748. baseMember = baseMember->next;
  14749. }
  14750. }
  14751. }
  14752. /*
  14753. * 3.3.2.4 Only pattern and enumeration facet components are
  14754. * allowed among the {facets}.
  14755. */
  14756. if (type->facets != NULL) {
  14757. xmlSchemaFacetPtr facet;
  14758. int ok = 1;
  14759. facet = type->facets;
  14760. do {
  14761. if ((facet->type != XML_SCHEMA_FACET_PATTERN) &&
  14762. (facet->type != XML_SCHEMA_FACET_ENUMERATION)) {
  14763. xmlSchemaPIllegalFacetListUnionErr(pctxt,
  14764. XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4,
  14765. type, facet);
  14766. ok = 0;
  14767. }
  14768. facet = facet->next;
  14769. } while (facet != NULL);
  14770. if (ok == 0)
  14771. return (XML_SCHEMAP_COS_ST_RESTRICTS_3_3_2_4);
  14772. }
  14773. /*
  14774. * SPEC (3.3.2.5) (same as 1.3.2)
  14775. *
  14776. * NOTE (3.3.2.5) This is currently done in
  14777. * xmlSchemaDeriveAndValidateFacets()
  14778. */
  14779. }
  14780. }
  14781. return (0);
  14782. }
  14783. /**
  14784. * xmlSchemaCheckSRCSimpleType:
  14785. * @ctxt: the schema parser context
  14786. * @type: the simple type definition
  14787. *
  14788. * Checks crc-simple-type constraints.
  14789. *
  14790. * Returns 0 if the constraints are satisfied,
  14791. * if not a positive error code and -1 on internal
  14792. * errors.
  14793. */
  14794. #if 0
  14795. static int
  14796. xmlSchemaCheckSRCSimpleType(xmlSchemaParserCtxtPtr ctxt,
  14797. xmlSchemaTypePtr type)
  14798. {
  14799. /*
  14800. * src-simple-type.1 The corresponding simple type definition, if any,
  14801. * must satisfy the conditions set out in Constraints on Simple Type
  14802. * Definition Schema Components ($3.14.6).
  14803. */
  14804. if (WXS_IS_RESTRICTION(type)) {
  14805. /*
  14806. * src-simple-type.2 "If the <restriction> alternative is chosen,
  14807. * either it must have a base [attribute] or a <simpleType> among its
  14808. * [children], but not both."
  14809. * NOTE: This is checked in the parse function of <restriction>.
  14810. */
  14811. /*
  14812. *
  14813. */
  14814. } else if (WXS_IS_LIST(type)) {
  14815. /* src-simple-type.3 "If the <list> alternative is chosen, either it must have
  14816. * an itemType [attribute] or a <simpleType> among its [children],
  14817. * but not both."
  14818. *
  14819. * NOTE: This is checked in the parse function of <list>.
  14820. */
  14821. } else if (WXS_IS_UNION(type)) {
  14822. /*
  14823. * src-simple-type.4 is checked in xmlSchemaCheckUnionTypeDefCircular().
  14824. */
  14825. }
  14826. return (0);
  14827. }
  14828. #endif
  14829. static int
  14830. xmlSchemaCreateVCtxtOnPCtxt(xmlSchemaParserCtxtPtr ctxt)
  14831. {
  14832. if (ctxt->vctxt == NULL) {
  14833. ctxt->vctxt = xmlSchemaNewValidCtxt(NULL);
  14834. if (ctxt->vctxt == NULL) {
  14835. xmlSchemaPErr(ctxt, NULL,
  14836. XML_SCHEMAP_INTERNAL,
  14837. "Internal error: xmlSchemaCreateVCtxtOnPCtxt, "
  14838. "failed to create a temp. validation context.\n",
  14839. NULL, NULL);
  14840. return (-1);
  14841. }
  14842. /* TODO: Pass user data. */
  14843. xmlSchemaSetValidErrors(ctxt->vctxt,
  14844. ctxt->error, ctxt->warning, ctxt->errCtxt);
  14845. xmlSchemaSetValidStructuredErrors(ctxt->vctxt,
  14846. ctxt->serror, ctxt->errCtxt);
  14847. }
  14848. return (0);
  14849. }
  14850. static int
  14851. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  14852. xmlNodePtr node,
  14853. xmlSchemaTypePtr type,
  14854. const xmlChar *value,
  14855. xmlSchemaValPtr *retVal,
  14856. int fireErrors,
  14857. int normalize,
  14858. int isNormalized);
  14859. /**
  14860. * xmlSchemaParseCheckCOSValidDefault:
  14861. * @pctxt: the schema parser context
  14862. * @type: the simple type definition
  14863. * @value: the default value
  14864. * @node: an optional node (the holder of the value)
  14865. *
  14866. * Schema Component Constraint: Element Default Valid (Immediate)
  14867. * (cos-valid-default)
  14868. * This will be used by the parser only. For the validator there's
  14869. * an other version.
  14870. *
  14871. * Returns 0 if the constraints are satisfied,
  14872. * if not, a positive error code and -1 on internal
  14873. * errors.
  14874. */
  14875. static int
  14876. xmlSchemaParseCheckCOSValidDefault(xmlSchemaParserCtxtPtr pctxt,
  14877. xmlNodePtr node,
  14878. xmlSchemaTypePtr type,
  14879. const xmlChar *value,
  14880. xmlSchemaValPtr *val)
  14881. {
  14882. int ret = 0;
  14883. /*
  14884. * cos-valid-default:
  14885. * Schema Component Constraint: Element Default Valid (Immediate)
  14886. * For a string to be a valid default with respect to a type
  14887. * definition the appropriate case among the following must be true:
  14888. */
  14889. if WXS_IS_COMPLEX(type) {
  14890. /*
  14891. * Complex type.
  14892. *
  14893. * SPEC (2.1) "its {content type} must be a simple type definition
  14894. * or mixed."
  14895. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  14896. * type}'s particle must be `emptiable` as defined by
  14897. * Particle Emptiable ($3.9.6)."
  14898. */
  14899. if ((! WXS_HAS_SIMPLE_CONTENT(type)) &&
  14900. ((! WXS_HAS_MIXED_CONTENT(type)) || (! WXS_EMPTIABLE(type)))) {
  14901. /* NOTE that this covers (2.2.2) as well. */
  14902. xmlSchemaPCustomErr(pctxt,
  14903. XML_SCHEMAP_COS_VALID_DEFAULT_2_1,
  14904. WXS_BASIC_CAST type, type->node,
  14905. "For a string to be a valid default, the type definition "
  14906. "must be a simple type or a complex type with mixed content "
  14907. "and a particle emptiable", NULL);
  14908. return(XML_SCHEMAP_COS_VALID_DEFAULT_2_1);
  14909. }
  14910. }
  14911. /*
  14912. * 1 If the type definition is a simple type definition, then the string
  14913. * must be `valid` with respect to that definition as defined by String
  14914. * Valid ($3.14.4).
  14915. *
  14916. * AND
  14917. *
  14918. * 2.2.1 If the {content type} is a simple type definition, then the
  14919. * string must be `valid` with respect to that simple type definition
  14920. * as defined by String Valid ($3.14.4).
  14921. */
  14922. if (WXS_IS_SIMPLE(type))
  14923. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  14924. type, value, val, 1, 1, 0);
  14925. else if (WXS_HAS_SIMPLE_CONTENT(type))
  14926. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt, node,
  14927. type->contentTypeDef, value, val, 1, 1, 0);
  14928. else
  14929. return (ret);
  14930. if (ret < 0) {
  14931. PERROR_INT("xmlSchemaParseCheckCOSValidDefault",
  14932. "calling xmlSchemaVCheckCVCSimpleType()");
  14933. }
  14934. return (ret);
  14935. }
  14936. /**
  14937. * xmlSchemaCheckCTPropsCorrect:
  14938. * @ctxt: the schema parser context
  14939. * @type: the complex type definition
  14940. *
  14941. *.(4.6) Constraints on Complex Type Definition Schema Components
  14942. * Schema Component Constraint:
  14943. * Complex Type Definition Properties Correct (ct-props-correct)
  14944. * STATUS: (seems) complete
  14945. *
  14946. * Returns 0 if the constraints are satisfied, a positive
  14947. * error code if not and -1 if an internal error occurred.
  14948. */
  14949. static int
  14950. xmlSchemaCheckCTPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  14951. xmlSchemaTypePtr type)
  14952. {
  14953. /*
  14954. * TODO: Correct the error code; XML_SCHEMAP_SRC_CT_1 is used temporarily.
  14955. *
  14956. * SPEC (1) "The values of the properties of a complex type definition must
  14957. * be as described in the property tableau in The Complex Type Definition
  14958. * Schema Component ($3.4.1), modulo the impact of Missing
  14959. * Sub-components ($5.3)."
  14960. */
  14961. if ((type->baseType != NULL) &&
  14962. (WXS_IS_SIMPLE(type->baseType)) &&
  14963. (WXS_IS_EXTENSION(type) == 0)) {
  14964. /*
  14965. * SPEC (2) "If the {base type definition} is a simple type definition,
  14966. * the {derivation method} must be extension."
  14967. */
  14968. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  14969. XML_SCHEMAP_SRC_CT_1,
  14970. NULL, WXS_BASIC_CAST type,
  14971. "If the base type is a simple type, the derivation method must be "
  14972. "'extension'", NULL, NULL);
  14973. return (XML_SCHEMAP_SRC_CT_1);
  14974. }
  14975. /*
  14976. * SPEC (3) "Circular definitions are disallowed, except for the `ur-type
  14977. * definition`. That is, it must be possible to reach the `ur-type
  14978. * definition` by repeatedly following the {base type definition}."
  14979. *
  14980. * NOTE (3) is done in xmlSchemaCheckTypeDefCircular().
  14981. */
  14982. /*
  14983. * NOTE that (4) and (5) need the following:
  14984. * - attribute uses need to be already inherited (apply attr. prohibitions)
  14985. * - attribute group references need to be expanded already
  14986. * - simple types need to be typefixed already
  14987. */
  14988. if (type->attrUses &&
  14989. (((xmlSchemaItemListPtr) type->attrUses)->nbItems > 1))
  14990. {
  14991. xmlSchemaItemListPtr uses = (xmlSchemaItemListPtr) type->attrUses;
  14992. xmlSchemaAttributeUsePtr use, tmp;
  14993. int i, j, hasId = 0;
  14994. for (i = uses->nbItems -1; i >= 0; i--) {
  14995. use = uses->items[i];
  14996. /*
  14997. * SPEC ct-props-correct
  14998. * (4) "Two distinct attribute declarations in the
  14999. * {attribute uses} must not have identical {name}s and
  15000. * {target namespace}s."
  15001. */
  15002. if (i > 0) {
  15003. for (j = i -1; j >= 0; j--) {
  15004. tmp = uses->items[j];
  15005. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15006. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  15007. (WXS_ATTRUSE_DECL_TNS(use) ==
  15008. WXS_ATTRUSE_DECL_TNS(tmp)))
  15009. {
  15010. xmlChar *str = NULL;
  15011. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15012. XML_SCHEMAP_AG_PROPS_CORRECT,
  15013. NULL, WXS_BASIC_CAST type,
  15014. "Duplicate %s",
  15015. xmlSchemaGetComponentDesignation(&str, use),
  15016. NULL);
  15017. FREE_AND_NULL(str);
  15018. /*
  15019. * Remove the duplicate.
  15020. */
  15021. if (xmlSchemaItemListRemove(uses, i) == -1)
  15022. goto exit_failure;
  15023. goto next_use;
  15024. }
  15025. }
  15026. }
  15027. /*
  15028. * SPEC ct-props-correct
  15029. * (5) "Two distinct attribute declarations in the
  15030. * {attribute uses} must not have {type definition}s which
  15031. * are or are derived from ID."
  15032. */
  15033. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  15034. if (xmlSchemaIsDerivedFromBuiltInType(
  15035. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  15036. {
  15037. if (hasId) {
  15038. xmlChar *str = NULL;
  15039. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15040. XML_SCHEMAP_AG_PROPS_CORRECT,
  15041. NULL, WXS_BASIC_CAST type,
  15042. "There must not exist more than one attribute "
  15043. "declaration of type 'xs:ID' "
  15044. "(or derived from 'xs:ID'). The %s violates this "
  15045. "constraint",
  15046. xmlSchemaGetComponentDesignation(&str, use),
  15047. NULL);
  15048. FREE_AND_NULL(str);
  15049. if (xmlSchemaItemListRemove(uses, i) == -1)
  15050. goto exit_failure;
  15051. }
  15052. hasId = 1;
  15053. }
  15054. }
  15055. next_use: {}
  15056. }
  15057. }
  15058. return (0);
  15059. exit_failure:
  15060. return(-1);
  15061. }
  15062. static int
  15063. xmlSchemaAreEqualTypes(xmlSchemaTypePtr typeA,
  15064. xmlSchemaTypePtr typeB)
  15065. {
  15066. /*
  15067. * TODO: This should implement component-identity
  15068. * in the future.
  15069. */
  15070. if ((typeA == NULL) || (typeB == NULL))
  15071. return (0);
  15072. return (typeA == typeB);
  15073. }
  15074. /**
  15075. * xmlSchemaCheckCOSCTDerivedOK:
  15076. * @ctxt: the schema parser context
  15077. * @type: the to-be derived complex type definition
  15078. * @baseType: the base complex type definition
  15079. * @set: the given set
  15080. *
  15081. * Schema Component Constraint:
  15082. * Type Derivation OK (Complex) (cos-ct-derived-ok)
  15083. *
  15084. * STATUS: completed
  15085. *
  15086. * Returns 0 if the constraints are satisfied, or 1
  15087. * if not.
  15088. */
  15089. static int
  15090. xmlSchemaCheckCOSCTDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15091. xmlSchemaTypePtr type,
  15092. xmlSchemaTypePtr baseType,
  15093. int set)
  15094. {
  15095. int equal = xmlSchemaAreEqualTypes(type, baseType);
  15096. /* TODO: Error codes. */
  15097. /*
  15098. * SPEC "For a complex type definition (call it D, for derived)
  15099. * to be validly derived from a type definition (call this
  15100. * B, for base) given a subset of {extension, restriction}
  15101. * all of the following must be true:"
  15102. */
  15103. if (! equal) {
  15104. /*
  15105. * SPEC (1) "If B and D are not the same type definition, then the
  15106. * {derivation method} of D must not be in the subset."
  15107. */
  15108. if (((set & SUBSET_EXTENSION) && (WXS_IS_EXTENSION(type))) ||
  15109. ((set & SUBSET_RESTRICTION) && (WXS_IS_RESTRICTION(type))))
  15110. return (1);
  15111. } else {
  15112. /*
  15113. * SPEC (2.1) "B and D must be the same type definition."
  15114. */
  15115. return (0);
  15116. }
  15117. /*
  15118. * SPEC (2.2) "B must be D's {base type definition}."
  15119. */
  15120. if (type->baseType == baseType)
  15121. return (0);
  15122. /*
  15123. * SPEC (2.3.1) "D's {base type definition} must not be the `ur-type
  15124. * definition`."
  15125. */
  15126. if (WXS_IS_ANYTYPE(type->baseType))
  15127. return (1);
  15128. if (WXS_IS_COMPLEX(type->baseType)) {
  15129. /*
  15130. * SPEC (2.3.2.1) "If D's {base type definition} is complex, then it
  15131. * must be validly derived from B given the subset as defined by this
  15132. * constraint."
  15133. */
  15134. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type->baseType,
  15135. baseType, set));
  15136. } else {
  15137. /*
  15138. * SPEC (2.3.2.2) "If D's {base type definition} is simple, then it
  15139. * must be validly derived from B given the subset as defined in Type
  15140. * Derivation OK (Simple) ($3.14.6).
  15141. */
  15142. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type->baseType,
  15143. baseType, set));
  15144. }
  15145. }
  15146. /**
  15147. * xmlSchemaCheckCOSDerivedOK:
  15148. * @type: the derived simple type definition
  15149. * @baseType: the base type definition
  15150. *
  15151. * Calls:
  15152. * Type Derivation OK (Simple) AND Type Derivation OK (Complex)
  15153. *
  15154. * Checks whether @type can be validly derived from @baseType.
  15155. *
  15156. * Returns 0 on success, an positive error code otherwise.
  15157. */
  15158. static int
  15159. xmlSchemaCheckCOSDerivedOK(xmlSchemaAbstractCtxtPtr actxt,
  15160. xmlSchemaTypePtr type,
  15161. xmlSchemaTypePtr baseType,
  15162. int set)
  15163. {
  15164. if (WXS_IS_SIMPLE(type))
  15165. return (xmlSchemaCheckCOSSTDerivedOK(actxt, type, baseType, set));
  15166. else
  15167. return (xmlSchemaCheckCOSCTDerivedOK(actxt, type, baseType, set));
  15168. }
  15169. /**
  15170. * xmlSchemaCheckCOSCTExtends:
  15171. * @ctxt: the schema parser context
  15172. * @type: the complex type definition
  15173. *
  15174. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15175. * Schema Component Constraint:
  15176. * Derivation Valid (Extension) (cos-ct-extends)
  15177. *
  15178. * STATUS:
  15179. * missing:
  15180. * (1.5)
  15181. * (1.4.3.2.2.2) "Particle Valid (Extension)"
  15182. *
  15183. * Returns 0 if the constraints are satisfied, a positive
  15184. * error code if not and -1 if an internal error occurred.
  15185. */
  15186. static int
  15187. xmlSchemaCheckCOSCTExtends(xmlSchemaParserCtxtPtr ctxt,
  15188. xmlSchemaTypePtr type)
  15189. {
  15190. xmlSchemaTypePtr base = type->baseType;
  15191. /*
  15192. * TODO: Correct the error code; XML_SCHEMAP_COS_CT_EXTENDS_1_1 is used
  15193. * temporarily only.
  15194. */
  15195. /*
  15196. * SPEC (1) "If the {base type definition} is a complex type definition,
  15197. * then all of the following must be true:"
  15198. */
  15199. if (WXS_IS_COMPLEX(base)) {
  15200. /*
  15201. * SPEC (1.1) "The {final} of the {base type definition} must not
  15202. * contain extension."
  15203. */
  15204. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15205. xmlSchemaPCustomErr(ctxt,
  15206. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15207. WXS_BASIC_CAST type, NULL,
  15208. "The 'final' of the base type definition "
  15209. "contains 'extension'", NULL);
  15210. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15211. }
  15212. /*
  15213. * ATTENTION: The constrains (1.2) and (1.3) are not applied,
  15214. * since they are automatically satisfied through the
  15215. * inheriting mechanism.
  15216. * Note that even if redefining components, the inheriting mechanism
  15217. * is used.
  15218. */
  15219. #if 0
  15220. /*
  15221. * SPEC (1.2) "Its {attribute uses} must be a subset of the {attribute
  15222. * uses}
  15223. * of the complex type definition itself, that is, for every attribute
  15224. * use in the {attribute uses} of the {base type definition}, there
  15225. * must be an attribute use in the {attribute uses} of the complex
  15226. * type definition itself whose {attribute declaration} has the same
  15227. * {name}, {target namespace} and {type definition} as its attribute
  15228. * declaration"
  15229. */
  15230. if (base->attrUses != NULL) {
  15231. int i, j, found;
  15232. xmlSchemaAttributeUsePtr use, buse;
  15233. for (i = 0; i < (WXS_LIST_CAST base->attrUses)->nbItems; i ++) {
  15234. buse = (WXS_LIST_CAST base->attrUses)->items[i];
  15235. found = 0;
  15236. if (type->attrUses != NULL) {
  15237. use = (WXS_LIST_CAST type->attrUses)->items[j];
  15238. for (j = 0; j < (WXS_LIST_CAST type->attrUses)->nbItems; j ++)
  15239. {
  15240. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  15241. WXS_ATTRUSE_DECL_NAME(buse)) &&
  15242. (WXS_ATTRUSE_DECL_TNS(use) ==
  15243. WXS_ATTRUSE_DECL_TNS(buse)) &&
  15244. (WXS_ATTRUSE_TYPEDEF(use) ==
  15245. WXS_ATTRUSE_TYPEDEF(buse))
  15246. {
  15247. found = 1;
  15248. break;
  15249. }
  15250. }
  15251. }
  15252. if (! found) {
  15253. xmlChar *str = NULL;
  15254. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15255. XML_SCHEMAP_COS_CT_EXTENDS_1_2,
  15256. NULL, WXS_BASIC_CAST type,
  15257. /*
  15258. * TODO: The report does not indicate that also the
  15259. * type needs to be the same.
  15260. */
  15261. "This type is missing a matching correspondent "
  15262. "for its {base type}'s %s in its {attribute uses}",
  15263. xmlSchemaGetComponentDesignation(&str,
  15264. buse->children),
  15265. NULL);
  15266. FREE_AND_NULL(str)
  15267. }
  15268. }
  15269. }
  15270. /*
  15271. * SPEC (1.3) "If it has an {attribute wildcard}, the complex type
  15272. * definition must also have one, and the base type definition's
  15273. * {attribute wildcard}'s {namespace constraint} must be a subset
  15274. * of the complex type definition's {attribute wildcard}'s {namespace
  15275. * constraint}, as defined by Wildcard Subset ($3.10.6)."
  15276. */
  15277. /*
  15278. * MAYBE TODO: Enable if ever needed. But this will be needed only
  15279. * if created the type via a schema construction API.
  15280. */
  15281. if (base->attributeWildcard != NULL) {
  15282. if (type->attributeWildcard == NULL) {
  15283. xmlChar *str = NULL;
  15284. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15285. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15286. NULL, type,
  15287. "The base %s has an attribute wildcard, "
  15288. "but this type is missing an attribute wildcard",
  15289. xmlSchemaGetComponentDesignation(&str, base));
  15290. FREE_AND_NULL(str)
  15291. } else if (xmlSchemaCheckCOSNSSubset(
  15292. base->attributeWildcard, type->attributeWildcard))
  15293. {
  15294. xmlChar *str = NULL;
  15295. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  15296. XML_SCHEMAP_COS_CT_EXTENDS_1_3,
  15297. NULL, type,
  15298. "The attribute wildcard is not a valid "
  15299. "superset of the one in the base %s",
  15300. xmlSchemaGetComponentDesignation(&str, base));
  15301. FREE_AND_NULL(str)
  15302. }
  15303. }
  15304. #endif
  15305. /*
  15306. * SPEC (1.4) "One of the following must be true:"
  15307. */
  15308. if ((type->contentTypeDef != NULL) &&
  15309. (type->contentTypeDef == base->contentTypeDef)) {
  15310. /*
  15311. * SPEC (1.4.1) "The {content type} of the {base type definition}
  15312. * and the {content type} of the complex type definition itself
  15313. * must be the same simple type definition"
  15314. * PASS
  15315. */
  15316. } else if ((type->contentType == XML_SCHEMA_CONTENT_EMPTY) &&
  15317. (base->contentType == XML_SCHEMA_CONTENT_EMPTY) ) {
  15318. /*
  15319. * SPEC (1.4.2) "The {content type} of both the {base type
  15320. * definition} and the complex type definition itself must
  15321. * be empty."
  15322. * PASS
  15323. */
  15324. } else {
  15325. /*
  15326. * SPEC (1.4.3) "All of the following must be true:"
  15327. */
  15328. if (type->subtypes == NULL) {
  15329. /*
  15330. * SPEC 1.4.3.1 The {content type} of the complex type
  15331. * definition itself must specify a particle.
  15332. */
  15333. xmlSchemaPCustomErr(ctxt,
  15334. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15335. WXS_BASIC_CAST type, NULL,
  15336. "The content type must specify a particle", NULL);
  15337. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15338. }
  15339. /*
  15340. * SPEC (1.4.3.2) "One of the following must be true:"
  15341. */
  15342. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15343. /*
  15344. * SPEC (1.4.3.2.1) "The {content type} of the {base type
  15345. * definition} must be empty.
  15346. * PASS
  15347. */
  15348. } else {
  15349. /*
  15350. * SPEC (1.4.3.2.2) "All of the following must be true:"
  15351. */
  15352. if ((type->contentType != base->contentType) ||
  15353. ((type->contentType != XML_SCHEMA_CONTENT_MIXED) &&
  15354. (type->contentType != XML_SCHEMA_CONTENT_ELEMENTS))) {
  15355. /*
  15356. * SPEC (1.4.3.2.2.1) "Both {content type}s must be mixed
  15357. * or both must be element-only."
  15358. */
  15359. xmlSchemaPCustomErr(ctxt,
  15360. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15361. WXS_BASIC_CAST type, NULL,
  15362. "The content type of both, the type and its base "
  15363. "type, must either 'mixed' or 'element-only'", NULL);
  15364. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15365. }
  15366. /*
  15367. * URGENT TODO SPEC (1.4.3.2.2.2) "The particle of the
  15368. * complex type definition must be a `valid extension`
  15369. * of the {base type definition}'s particle, as defined
  15370. * in Particle Valid (Extension) ($3.9.6)."
  15371. *
  15372. * NOTE that we won't check "Particle Valid (Extension)",
  15373. * since it is ensured by the derivation process in
  15374. * xmlSchemaTypeFixup(). We need to implement this when heading
  15375. * for a construction API
  15376. * TODO: !! This is needed to be checked if redefining a type !!
  15377. */
  15378. }
  15379. /*
  15380. * URGENT TODO (1.5)
  15381. */
  15382. }
  15383. } else {
  15384. /*
  15385. * SPEC (2) "If the {base type definition} is a simple type definition,
  15386. * then all of the following must be true:"
  15387. */
  15388. if (type->contentTypeDef != base) {
  15389. /*
  15390. * SPEC (2.1) "The {content type} must be the same simple type
  15391. * definition."
  15392. */
  15393. xmlSchemaPCustomErr(ctxt,
  15394. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15395. WXS_BASIC_CAST type, NULL,
  15396. "The content type must be the simple base type", NULL);
  15397. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15398. }
  15399. if (base->flags & XML_SCHEMAS_TYPE_FINAL_EXTENSION) {
  15400. /*
  15401. * SPEC (2.2) "The {final} of the {base type definition} must not
  15402. * contain extension"
  15403. * NOTE that this is the same as (1.1).
  15404. */
  15405. xmlSchemaPCustomErr(ctxt,
  15406. XML_SCHEMAP_COS_CT_EXTENDS_1_1,
  15407. WXS_BASIC_CAST type, NULL,
  15408. "The 'final' of the base type definition "
  15409. "contains 'extension'", NULL);
  15410. return (XML_SCHEMAP_COS_CT_EXTENDS_1_1);
  15411. }
  15412. }
  15413. return (0);
  15414. }
  15415. /**
  15416. * xmlSchemaCheckDerivationOKRestriction:
  15417. * @ctxt: the schema parser context
  15418. * @type: the complex type definition
  15419. *
  15420. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15421. * Schema Component Constraint:
  15422. * Derivation Valid (Restriction, Complex) (derivation-ok-restriction)
  15423. *
  15424. * STATUS:
  15425. * missing:
  15426. * (5.4.2) ???
  15427. *
  15428. * ATTENTION:
  15429. * In XML Schema 1.1 this will be:
  15430. * Validation Rule: Checking complex type subsumption
  15431. *
  15432. * Returns 0 if the constraints are satisfied, a positive
  15433. * error code if not and -1 if an internal error occurred.
  15434. */
  15435. static int
  15436. xmlSchemaCheckDerivationOKRestriction(xmlSchemaParserCtxtPtr ctxt,
  15437. xmlSchemaTypePtr type)
  15438. {
  15439. xmlSchemaTypePtr base;
  15440. /*
  15441. * TODO: Correct the error code; XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1 is used
  15442. * temporarily only.
  15443. */
  15444. base = type->baseType;
  15445. if (! WXS_IS_COMPLEX(base)) {
  15446. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15447. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15448. type->node, WXS_BASIC_CAST type,
  15449. "The base type must be a complex type", NULL, NULL);
  15450. return(ctxt->err);
  15451. }
  15452. if (base->flags & XML_SCHEMAS_TYPE_FINAL_RESTRICTION) {
  15453. /*
  15454. * SPEC (1) "The {base type definition} must be a complex type
  15455. * definition whose {final} does not contain restriction."
  15456. */
  15457. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15458. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15459. type->node, WXS_BASIC_CAST type,
  15460. "The 'final' of the base type definition "
  15461. "contains 'restriction'", NULL, NULL);
  15462. return (ctxt->err);
  15463. }
  15464. /*
  15465. * SPEC (2), (3) and (4)
  15466. * Those are handled in a separate function, since the
  15467. * same constraints are needed for redefinition of
  15468. * attribute groups as well.
  15469. */
  15470. if (xmlSchemaCheckDerivationOKRestriction2to4(ctxt,
  15471. XML_SCHEMA_ACTION_DERIVE,
  15472. WXS_BASIC_CAST type, WXS_BASIC_CAST base,
  15473. type->attrUses, base->attrUses,
  15474. type->attributeWildcard,
  15475. base->attributeWildcard) == -1)
  15476. {
  15477. return(-1);
  15478. }
  15479. /*
  15480. * SPEC (5) "One of the following must be true:"
  15481. */
  15482. if (base->builtInType == XML_SCHEMAS_ANYTYPE) {
  15483. /*
  15484. * SPEC (5.1) "The {base type definition} must be the
  15485. * `ur-type definition`."
  15486. * PASS
  15487. */
  15488. } else if ((type->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15489. (type->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15490. /*
  15491. * SPEC (5.2.1) "The {content type} of the complex type definition
  15492. * must be a simple type definition"
  15493. *
  15494. * SPEC (5.2.2) "One of the following must be true:"
  15495. */
  15496. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15497. (base->contentType == XML_SCHEMA_CONTENT_BASIC))
  15498. {
  15499. int err;
  15500. /*
  15501. * SPEC (5.2.2.1) "The {content type} of the {base type
  15502. * definition} must be a simple type definition from which
  15503. * the {content type} is validly derived given the empty
  15504. * set as defined in Type Derivation OK (Simple) ($3.14.6)."
  15505. *
  15506. * ATTENTION TODO: This seems not needed if the type implicitly
  15507. * derived from the base type.
  15508. *
  15509. */
  15510. err = xmlSchemaCheckCOSSTDerivedOK(ACTXT_CAST ctxt,
  15511. type->contentTypeDef, base->contentTypeDef, 0);
  15512. if (err != 0) {
  15513. xmlChar *strA = NULL, *strB = NULL;
  15514. if (err == -1)
  15515. return(-1);
  15516. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  15517. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15518. NULL, WXS_BASIC_CAST type,
  15519. "The {content type} %s is not validly derived from the "
  15520. "base type's {content type} %s",
  15521. xmlSchemaGetComponentDesignation(&strA,
  15522. type->contentTypeDef),
  15523. xmlSchemaGetComponentDesignation(&strB,
  15524. base->contentTypeDef));
  15525. FREE_AND_NULL(strA);
  15526. FREE_AND_NULL(strB);
  15527. return(ctxt->err);
  15528. }
  15529. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15530. (xmlSchemaIsParticleEmptiable(
  15531. (xmlSchemaParticlePtr) base->subtypes))) {
  15532. /*
  15533. * SPEC (5.2.2.2) "The {base type definition} must be mixed
  15534. * and have a particle which is `emptiable` as defined in
  15535. * Particle Emptiable ($3.9.6)."
  15536. * PASS
  15537. */
  15538. } else {
  15539. xmlSchemaPCustomErr(ctxt,
  15540. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15541. WXS_BASIC_CAST type, NULL,
  15542. "The content type of the base type must be either "
  15543. "a simple type or 'mixed' and an emptiable particle", NULL);
  15544. return (ctxt->err);
  15545. }
  15546. } else if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15547. /*
  15548. * SPEC (5.3.1) "The {content type} of the complex type itself must
  15549. * be empty"
  15550. */
  15551. if (base->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  15552. /*
  15553. * SPEC (5.3.2.1) "The {content type} of the {base type
  15554. * definition} must also be empty."
  15555. * PASS
  15556. */
  15557. } else if (((base->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15558. (base->contentType == XML_SCHEMA_CONTENT_MIXED)) &&
  15559. xmlSchemaIsParticleEmptiable(
  15560. (xmlSchemaParticlePtr) base->subtypes)) {
  15561. /*
  15562. * SPEC (5.3.2.2) "The {content type} of the {base type
  15563. * definition} must be elementOnly or mixed and have a particle
  15564. * which is `emptiable` as defined in Particle Emptiable ($3.9.6)."
  15565. * PASS
  15566. */
  15567. } else {
  15568. xmlSchemaPCustomErr(ctxt,
  15569. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15570. WXS_BASIC_CAST type, NULL,
  15571. "The content type of the base type must be either "
  15572. "empty or 'mixed' (or 'elements-only') and an emptiable "
  15573. "particle", NULL);
  15574. return (ctxt->err);
  15575. }
  15576. } else if ((type->contentType == XML_SCHEMA_CONTENT_ELEMENTS) ||
  15577. WXS_HAS_MIXED_CONTENT(type)) {
  15578. /*
  15579. * SPEC (5.4.1.1) "The {content type} of the complex type definition
  15580. * itself must be element-only"
  15581. */
  15582. if (WXS_HAS_MIXED_CONTENT(type) && (! WXS_HAS_MIXED_CONTENT(base))) {
  15583. /*
  15584. * SPEC (5.4.1.2) "The {content type} of the complex type
  15585. * definition itself and of the {base type definition} must be
  15586. * mixed"
  15587. */
  15588. xmlSchemaPCustomErr(ctxt,
  15589. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15590. WXS_BASIC_CAST type, NULL,
  15591. "If the content type is 'mixed', then the content type of the "
  15592. "base type must also be 'mixed'", NULL);
  15593. return (ctxt->err);
  15594. }
  15595. /*
  15596. * SPEC (5.4.2) "The particle of the complex type definition itself
  15597. * must be a `valid restriction` of the particle of the {content
  15598. * type} of the {base type definition} as defined in Particle Valid
  15599. * (Restriction) ($3.9.6).
  15600. *
  15601. * URGENT TODO: (5.4.2)
  15602. */
  15603. } else {
  15604. xmlSchemaPCustomErr(ctxt,
  15605. XML_SCHEMAP_DERIVATION_OK_RESTRICTION_1,
  15606. WXS_BASIC_CAST type, NULL,
  15607. "The type is not a valid restriction of its base type", NULL);
  15608. return (ctxt->err);
  15609. }
  15610. return (0);
  15611. }
  15612. /**
  15613. * xmlSchemaCheckCTComponent:
  15614. * @ctxt: the schema parser context
  15615. * @type: the complex type definition
  15616. *
  15617. * (3.4.6) Constraints on Complex Type Definition Schema Components
  15618. *
  15619. * Returns 0 if the constraints are satisfied, a positive
  15620. * error code if not and -1 if an internal error occurred.
  15621. */
  15622. static int
  15623. xmlSchemaCheckCTComponent(xmlSchemaParserCtxtPtr ctxt,
  15624. xmlSchemaTypePtr type)
  15625. {
  15626. int ret;
  15627. /*
  15628. * Complex Type Definition Properties Correct
  15629. */
  15630. ret = xmlSchemaCheckCTPropsCorrect(ctxt, type);
  15631. if (ret != 0)
  15632. return (ret);
  15633. if (WXS_IS_EXTENSION(type))
  15634. ret = xmlSchemaCheckCOSCTExtends(ctxt, type);
  15635. else
  15636. ret = xmlSchemaCheckDerivationOKRestriction(ctxt, type);
  15637. return (ret);
  15638. }
  15639. /**
  15640. * xmlSchemaCheckSRCCT:
  15641. * @ctxt: the schema parser context
  15642. * @type: the complex type definition
  15643. *
  15644. * (3.4.3) Constraints on XML Representations of Complex Type Definitions:
  15645. * Schema Representation Constraint:
  15646. * Complex Type Definition Representation OK (src-ct)
  15647. *
  15648. * Returns 0 if the constraints are satisfied, a positive
  15649. * error code if not and -1 if an internal error occurred.
  15650. */
  15651. static int
  15652. xmlSchemaCheckSRCCT(xmlSchemaParserCtxtPtr ctxt,
  15653. xmlSchemaTypePtr type)
  15654. {
  15655. xmlSchemaTypePtr base;
  15656. int ret = 0;
  15657. /*
  15658. * TODO: Adjust the error codes here, as I used
  15659. * XML_SCHEMAP_SRC_CT_1 only yet.
  15660. */
  15661. base = type->baseType;
  15662. if (! WXS_HAS_SIMPLE_CONTENT(type)) {
  15663. /*
  15664. * 1 If the <complexContent> alternative is chosen, the type definition
  15665. * `resolved` to by the `actual value` of the base [attribute]
  15666. * must be a complex type definition;
  15667. */
  15668. if (! WXS_IS_COMPLEX(base)) {
  15669. xmlChar *str = NULL;
  15670. xmlSchemaPCustomErr(ctxt,
  15671. XML_SCHEMAP_SRC_CT_1,
  15672. WXS_BASIC_CAST type, type->node,
  15673. "If using <complexContent>, the base type is expected to be "
  15674. "a complex type. The base type '%s' is a simple type",
  15675. xmlSchemaFormatQName(&str, base->targetNamespace,
  15676. base->name));
  15677. FREE_AND_NULL(str)
  15678. return (XML_SCHEMAP_SRC_CT_1);
  15679. }
  15680. } else {
  15681. /*
  15682. * SPEC
  15683. * 2 If the <simpleContent> alternative is chosen, all of the
  15684. * following must be true:
  15685. * 2.1 The type definition `resolved` to by the `actual value` of the
  15686. * base [attribute] must be one of the following:
  15687. */
  15688. if (WXS_IS_SIMPLE(base)) {
  15689. if (WXS_IS_EXTENSION(type) == 0) {
  15690. xmlChar *str = NULL;
  15691. /*
  15692. * 2.1.3 only if the <extension> alternative is also
  15693. * chosen, a simple type definition.
  15694. */
  15695. /* TODO: Change error code to ..._SRC_CT_2_1_3. */
  15696. xmlSchemaPCustomErr(ctxt,
  15697. XML_SCHEMAP_SRC_CT_1,
  15698. WXS_BASIC_CAST type, NULL,
  15699. "If using <simpleContent> and <restriction>, the base "
  15700. "type must be a complex type. The base type '%s' is "
  15701. "a simple type",
  15702. xmlSchemaFormatQName(&str, base->targetNamespace,
  15703. base->name));
  15704. FREE_AND_NULL(str)
  15705. return (XML_SCHEMAP_SRC_CT_1);
  15706. }
  15707. } else {
  15708. /* Base type is a complex type. */
  15709. if ((base->contentType == XML_SCHEMA_CONTENT_SIMPLE) ||
  15710. (base->contentType == XML_SCHEMA_CONTENT_BASIC)) {
  15711. /*
  15712. * 2.1.1 a complex type definition whose {content type} is a
  15713. * simple type definition;
  15714. * PASS
  15715. */
  15716. if (base->contentTypeDef == NULL) {
  15717. xmlSchemaPCustomErr(ctxt, XML_SCHEMAP_INTERNAL,
  15718. WXS_BASIC_CAST type, NULL,
  15719. "Internal error: xmlSchemaCheckSRCCT, "
  15720. "'%s', base type has no content type",
  15721. type->name);
  15722. return (-1);
  15723. }
  15724. } else if ((base->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  15725. (WXS_IS_RESTRICTION(type))) {
  15726. /*
  15727. * 2.1.2 only if the <restriction> alternative is also
  15728. * chosen, a complex type definition whose {content type}
  15729. * is mixed and a particle emptiable.
  15730. */
  15731. if (! xmlSchemaIsParticleEmptiable(
  15732. (xmlSchemaParticlePtr) base->subtypes)) {
  15733. ret = XML_SCHEMAP_SRC_CT_1;
  15734. } else
  15735. /*
  15736. * Attention: at this point the <simpleType> child is in
  15737. * ->contentTypeDef (put there during parsing).
  15738. */
  15739. if (type->contentTypeDef == NULL) {
  15740. xmlChar *str = NULL;
  15741. /*
  15742. * 2.2 If clause 2.1.2 above is satisfied, then there
  15743. * must be a <simpleType> among the [children] of
  15744. * <restriction>.
  15745. */
  15746. /* TODO: Change error code to ..._SRC_CT_2_2. */
  15747. xmlSchemaPCustomErr(ctxt,
  15748. XML_SCHEMAP_SRC_CT_1,
  15749. WXS_BASIC_CAST type, NULL,
  15750. "A <simpleType> is expected among the children "
  15751. "of <restriction>, if <simpleContent> is used and "
  15752. "the base type '%s' is a complex type",
  15753. xmlSchemaFormatQName(&str, base->targetNamespace,
  15754. base->name));
  15755. FREE_AND_NULL(str)
  15756. return (XML_SCHEMAP_SRC_CT_1);
  15757. }
  15758. } else {
  15759. ret = XML_SCHEMAP_SRC_CT_1;
  15760. }
  15761. }
  15762. if (ret > 0) {
  15763. xmlChar *str = NULL;
  15764. if (WXS_IS_RESTRICTION(type)) {
  15765. xmlSchemaPCustomErr(ctxt,
  15766. XML_SCHEMAP_SRC_CT_1,
  15767. WXS_BASIC_CAST type, NULL,
  15768. "If <simpleContent> and <restriction> is used, the "
  15769. "base type must be a simple type or a complex type with "
  15770. "mixed content and particle emptiable. The base type "
  15771. "'%s' is none of those",
  15772. xmlSchemaFormatQName(&str, base->targetNamespace,
  15773. base->name));
  15774. } else {
  15775. xmlSchemaPCustomErr(ctxt,
  15776. XML_SCHEMAP_SRC_CT_1,
  15777. WXS_BASIC_CAST type, NULL,
  15778. "If <simpleContent> and <extension> is used, the "
  15779. "base type must be a simple type. The base type '%s' "
  15780. "is a complex type",
  15781. xmlSchemaFormatQName(&str, base->targetNamespace,
  15782. base->name));
  15783. }
  15784. FREE_AND_NULL(str)
  15785. }
  15786. }
  15787. /*
  15788. * SPEC (3) "The corresponding complex type definition component must
  15789. * satisfy the conditions set out in Constraints on Complex Type
  15790. * Definition Schema Components ($3.4.6);"
  15791. * NOTE (3) will be done in xmlSchemaTypeFixup().
  15792. */
  15793. /*
  15794. * SPEC (4) If clause 2.2.1 or clause 2.2.2 in the correspondence specification
  15795. * above for {attribute wildcard} is satisfied, the intensional
  15796. * intersection must be expressible, as defined in Attribute Wildcard
  15797. * Intersection ($3.10.6).
  15798. * NOTE (4) is done in xmlSchemaFixupTypeAttributeUses().
  15799. */
  15800. return (ret);
  15801. }
  15802. #ifdef ENABLE_PARTICLE_RESTRICTION
  15803. /**
  15804. * xmlSchemaCheckParticleRangeOK:
  15805. * @ctxt: the schema parser context
  15806. * @type: the complex type definition
  15807. *
  15808. * (3.9.6) Constraints on Particle Schema Components
  15809. * Schema Component Constraint:
  15810. * Occurrence Range OK (range-ok)
  15811. *
  15812. * STATUS: complete
  15813. *
  15814. * Returns 0 if the constraints are satisfied, a positive
  15815. * error code if not and -1 if an internal error occurred.
  15816. */
  15817. static int
  15818. xmlSchemaCheckParticleRangeOK(int rmin, int rmax,
  15819. int bmin, int bmax)
  15820. {
  15821. if (rmin < bmin)
  15822. return (1);
  15823. if ((bmax != UNBOUNDED) &&
  15824. (rmax > bmax))
  15825. return (1);
  15826. return (0);
  15827. }
  15828. /**
  15829. * xmlSchemaCheckRCaseNameAndTypeOK:
  15830. * @ctxt: the schema parser context
  15831. * @r: the restricting element declaration particle
  15832. * @b: the base element declaration particle
  15833. *
  15834. * (3.9.6) Constraints on Particle Schema Components
  15835. * Schema Component Constraint:
  15836. * Particle Restriction OK (Elt:Elt -- NameAndTypeOK)
  15837. * (rcase-NameAndTypeOK)
  15838. *
  15839. * STATUS:
  15840. * MISSING (3.2.3)
  15841. * CLARIFY: (3.2.2)
  15842. *
  15843. * Returns 0 if the constraints are satisfied, a positive
  15844. * error code if not and -1 if an internal error occurred.
  15845. */
  15846. static int
  15847. xmlSchemaCheckRCaseNameAndTypeOK(xmlSchemaParserCtxtPtr ctxt,
  15848. xmlSchemaParticlePtr r,
  15849. xmlSchemaParticlePtr b)
  15850. {
  15851. xmlSchemaElementPtr elemR, elemB;
  15852. /* TODO: Error codes (rcase-NameAndTypeOK). */
  15853. elemR = (xmlSchemaElementPtr) r->children;
  15854. elemB = (xmlSchemaElementPtr) b->children;
  15855. /*
  15856. * SPEC (1) "The declarations' {name}s and {target namespace}s are
  15857. * the same."
  15858. */
  15859. if ((elemR != elemB) &&
  15860. ((! xmlStrEqual(elemR->name, elemB->name)) ||
  15861. (! xmlStrEqual(elemR->targetNamespace, elemB->targetNamespace))))
  15862. return (1);
  15863. /*
  15864. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15865. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  15866. */
  15867. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15868. b->minOccurs, b->maxOccurs) != 0)
  15869. return (1);
  15870. /*
  15871. * SPEC (3.1) "Both B's declaration's {scope} and R's declaration's
  15872. * {scope} are global."
  15873. */
  15874. if (elemR == elemB)
  15875. return (0);
  15876. /*
  15877. * SPEC (3.2.1) "Either B's {nillable} is true or R's {nillable} is false."
  15878. */
  15879. if (((elemB->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) &&
  15880. (elemR->flags & XML_SCHEMAS_ELEM_NILLABLE))
  15881. return (1);
  15882. /*
  15883. * SPEC (3.2.2) "either B's declaration's {value constraint} is absent,
  15884. * or is not fixed, or R's declaration's {value constraint} is fixed
  15885. * with the same value."
  15886. */
  15887. if ((elemB->value != NULL) && (elemB->flags & XML_SCHEMAS_ELEM_FIXED) &&
  15888. ((elemR->value == NULL) ||
  15889. ((elemR->flags & XML_SCHEMAS_ELEM_FIXED) == 0) ||
  15890. /* TODO: Equality of the initial value or normalized or canonical? */
  15891. (! xmlStrEqual(elemR->value, elemB->value))))
  15892. return (1);
  15893. /*
  15894. * TODO: SPEC (3.2.3) "R's declaration's {identity-constraint
  15895. * definitions} is a subset of B's declaration's {identity-constraint
  15896. * definitions}, if any."
  15897. */
  15898. if (elemB->idcs != NULL) {
  15899. /* TODO */
  15900. }
  15901. /*
  15902. * SPEC (3.2.4) "R's declaration's {disallowed substitutions} is a
  15903. * superset of B's declaration's {disallowed substitutions}."
  15904. */
  15905. if (((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) &&
  15906. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) == 0)) ||
  15907. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) &&
  15908. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) == 0)) ||
  15909. ((elemB->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) &&
  15910. ((elemR->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION) == 0)))
  15911. return (1);
  15912. /*
  15913. * SPEC (3.2.5) "R's {type definition} is validly derived given
  15914. * {extension, list, union} from B's {type definition}"
  15915. *
  15916. * BADSPEC TODO: What's the point of adding "list" and "union" to the
  15917. * set, if the corresponding constraints handle "restriction" and
  15918. * "extension" only?
  15919. *
  15920. */
  15921. {
  15922. int set = 0;
  15923. set |= SUBSET_EXTENSION;
  15924. set |= SUBSET_LIST;
  15925. set |= SUBSET_UNION;
  15926. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST ctxt, elemR->subtypes,
  15927. elemB->subtypes, set) != 0)
  15928. return (1);
  15929. }
  15930. return (0);
  15931. }
  15932. /**
  15933. * xmlSchemaCheckRCaseNSCompat:
  15934. * @ctxt: the schema parser context
  15935. * @r: the restricting element declaration particle
  15936. * @b: the base wildcard particle
  15937. *
  15938. * (3.9.6) Constraints on Particle Schema Components
  15939. * Schema Component Constraint:
  15940. * Particle Derivation OK (Elt:Any -- NSCompat)
  15941. * (rcase-NSCompat)
  15942. *
  15943. * STATUS: complete
  15944. *
  15945. * Returns 0 if the constraints are satisfied, a positive
  15946. * error code if not and -1 if an internal error occurred.
  15947. */
  15948. static int
  15949. xmlSchemaCheckRCaseNSCompat(xmlSchemaParserCtxtPtr ctxt,
  15950. xmlSchemaParticlePtr r,
  15951. xmlSchemaParticlePtr b)
  15952. {
  15953. /* TODO:Error codes (rcase-NSCompat). */
  15954. /*
  15955. * SPEC "For an element declaration particle to be a `valid restriction`
  15956. * of a wildcard particle all of the following must be true:"
  15957. *
  15958. * SPEC (1) "The element declaration's {target namespace} is `valid`
  15959. * with respect to the wildcard's {namespace constraint} as defined by
  15960. * Wildcard allows Namespace Name ($3.10.4)."
  15961. */
  15962. if (xmlSchemaCheckCVCWildcardNamespace((xmlSchemaWildcardPtr) b->children,
  15963. ((xmlSchemaElementPtr) r->children)->targetNamespace) != 0)
  15964. return (1);
  15965. /*
  15966. * SPEC (2) "R's occurrence range is a valid restriction of B's
  15967. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  15968. */
  15969. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  15970. b->minOccurs, b->maxOccurs) != 0)
  15971. return (1);
  15972. return (0);
  15973. }
  15974. /**
  15975. * xmlSchemaCheckRCaseRecurseAsIfGroup:
  15976. * @ctxt: the schema parser context
  15977. * @r: the restricting element declaration particle
  15978. * @b: the base model group particle
  15979. *
  15980. * (3.9.6) Constraints on Particle Schema Components
  15981. * Schema Component Constraint:
  15982. * Particle Derivation OK (Elt:All/Choice/Sequence -- RecurseAsIfGroup)
  15983. * (rcase-RecurseAsIfGroup)
  15984. *
  15985. * STATUS: TODO
  15986. *
  15987. * Returns 0 if the constraints are satisfied, a positive
  15988. * error code if not and -1 if an internal error occurred.
  15989. */
  15990. static int
  15991. xmlSchemaCheckRCaseRecurseAsIfGroup(xmlSchemaParserCtxtPtr ctxt,
  15992. xmlSchemaParticlePtr r,
  15993. xmlSchemaParticlePtr b)
  15994. {
  15995. /* TODO: Error codes (rcase-RecurseAsIfGroup). */
  15996. TODO
  15997. return (0);
  15998. }
  15999. /**
  16000. * xmlSchemaCheckRCaseNSSubset:
  16001. * @ctxt: the schema parser context
  16002. * @r: the restricting wildcard particle
  16003. * @b: the base wildcard particle
  16004. *
  16005. * (3.9.6) Constraints on Particle Schema Components
  16006. * Schema Component Constraint:
  16007. * Particle Derivation OK (Any:Any -- NSSubset)
  16008. * (rcase-NSSubset)
  16009. *
  16010. * STATUS: complete
  16011. *
  16012. * Returns 0 if the constraints are satisfied, a positive
  16013. * error code if not and -1 if an internal error occurred.
  16014. */
  16015. static int
  16016. xmlSchemaCheckRCaseNSSubset(xmlSchemaParserCtxtPtr ctxt,
  16017. xmlSchemaParticlePtr r,
  16018. xmlSchemaParticlePtr b,
  16019. int isAnyTypeBase)
  16020. {
  16021. /* TODO: Error codes (rcase-NSSubset). */
  16022. /*
  16023. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16024. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16025. */
  16026. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16027. b->minOccurs, b->maxOccurs))
  16028. return (1);
  16029. /*
  16030. * SPEC (2) "R's {namespace constraint} must be an intensional subset
  16031. * of B's {namespace constraint} as defined by Wildcard Subset ($3.10.6)."
  16032. */
  16033. if (xmlSchemaCheckCOSNSSubset((xmlSchemaWildcardPtr) r->children,
  16034. (xmlSchemaWildcardPtr) b->children))
  16035. return (1);
  16036. /*
  16037. * SPEC (3) "Unless B is the content model wildcard of the `ur-type
  16038. * definition`, R's {process contents} must be identical to or stronger
  16039. * than B's {process contents}, where strict is stronger than lax is
  16040. * stronger than skip."
  16041. */
  16042. if (! isAnyTypeBase) {
  16043. if ( ((xmlSchemaWildcardPtr) r->children)->processContents <
  16044. ((xmlSchemaWildcardPtr) b->children)->processContents)
  16045. return (1);
  16046. }
  16047. return (0);
  16048. }
  16049. /**
  16050. * xmlSchemaCheckCOSParticleRestrict:
  16051. * @ctxt: the schema parser context
  16052. * @type: the complex type definition
  16053. *
  16054. * (3.9.6) Constraints on Particle Schema Components
  16055. * Schema Component Constraint:
  16056. * Particle Valid (Restriction) (cos-particle-restrict)
  16057. *
  16058. * STATUS: TODO
  16059. *
  16060. * Returns 0 if the constraints are satisfied, a positive
  16061. * error code if not and -1 if an internal error occurred.
  16062. */
  16063. static int
  16064. xmlSchemaCheckCOSParticleRestrict(xmlSchemaParserCtxtPtr ctxt,
  16065. xmlSchemaParticlePtr r,
  16066. xmlSchemaParticlePtr b)
  16067. {
  16068. int ret = 0;
  16069. /*part = WXS_TYPE_PARTICLE(type);
  16070. basePart = WXS_TYPE_PARTICLE(base);
  16071. */
  16072. TODO
  16073. /*
  16074. * SPEC (1) "They are the same particle."
  16075. */
  16076. if (r == b)
  16077. return (0);
  16078. return (0);
  16079. }
  16080. #if 0
  16081. /**
  16082. * xmlSchemaCheckRCaseNSRecurseCheckCardinality:
  16083. * @ctxt: the schema parser context
  16084. * @r: the model group particle
  16085. * @b: the base wildcard particle
  16086. *
  16087. * (3.9.6) Constraints on Particle Schema Components
  16088. * Schema Component Constraint:
  16089. * Particle Derivation OK (All/Choice/Sequence:Any --
  16090. * NSRecurseCheckCardinality)
  16091. * (rcase-NSRecurseCheckCardinality)
  16092. *
  16093. * STATUS: TODO: subst-groups
  16094. *
  16095. * Returns 0 if the constraints are satisfied, a positive
  16096. * error code if not and -1 if an internal error occurred.
  16097. */
  16098. static int
  16099. xmlSchemaCheckRCaseNSRecurseCheckCardinality(xmlSchemaParserCtxtPtr ctxt,
  16100. xmlSchemaParticlePtr r,
  16101. xmlSchemaParticlePtr b)
  16102. {
  16103. xmlSchemaParticlePtr part;
  16104. /* TODO: Error codes (rcase-NSRecurseCheckCardinality). */
  16105. if ((r->children == NULL) || (r->children->children == NULL))
  16106. return (-1);
  16107. /*
  16108. * SPEC "For a group particle to be a `valid restriction` of a
  16109. * wildcard particle..."
  16110. *
  16111. * SPEC (1) "Every member of the {particles} of the group is a `valid
  16112. * restriction` of the wildcard as defined by
  16113. * Particle Valid (Restriction) ($3.9.6)."
  16114. */
  16115. part = (xmlSchemaParticlePtr) r->children->children;
  16116. do {
  16117. if (xmlSchemaCheckCOSParticleRestrict(ctxt, part, b))
  16118. return (1);
  16119. part = (xmlSchemaParticlePtr) part->next;
  16120. } while (part != NULL);
  16121. /*
  16122. * SPEC (2) "The effective total range of the group [...] is a
  16123. * valid restriction of B's occurrence range as defined by
  16124. * Occurrence Range OK ($3.9.6)."
  16125. */
  16126. if (xmlSchemaCheckParticleRangeOK(
  16127. xmlSchemaGetParticleTotalRangeMin(r),
  16128. xmlSchemaGetParticleTotalRangeMax(r),
  16129. b->minOccurs, b->maxOccurs) != 0)
  16130. return (1);
  16131. return (0);
  16132. }
  16133. #endif
  16134. /**
  16135. * xmlSchemaCheckRCaseRecurse:
  16136. * @ctxt: the schema parser context
  16137. * @r: the <all> or <sequence> model group particle
  16138. * @b: the base <all> or <sequence> model group particle
  16139. *
  16140. * (3.9.6) Constraints on Particle Schema Components
  16141. * Schema Component Constraint:
  16142. * Particle Derivation OK (All:All,Sequence:Sequence --
  16143. Recurse)
  16144. * (rcase-Recurse)
  16145. *
  16146. * STATUS: ?
  16147. * TODO: subst-groups
  16148. *
  16149. * Returns 0 if the constraints are satisfied, a positive
  16150. * error code if not and -1 if an internal error occurred.
  16151. */
  16152. static int
  16153. xmlSchemaCheckRCaseRecurse(xmlSchemaParserCtxtPtr ctxt,
  16154. xmlSchemaParticlePtr r,
  16155. xmlSchemaParticlePtr b)
  16156. {
  16157. /* xmlSchemaParticlePtr part; */
  16158. /* TODO: Error codes (rcase-Recurse). */
  16159. if ((r->children == NULL) || (b->children == NULL) ||
  16160. (r->children->type != b->children->type))
  16161. return (-1);
  16162. /*
  16163. * SPEC "For an all or sequence group particle to be a `valid
  16164. * restriction` of another group particle with the same {compositor}..."
  16165. *
  16166. * SPEC (1) "R's occurrence range is a valid restriction of B's
  16167. * occurrence range as defined by Occurrence Range OK ($3.9.6)."
  16168. */
  16169. if (xmlSchemaCheckParticleRangeOK(r->minOccurs, r->maxOccurs,
  16170. b->minOccurs, b->maxOccurs))
  16171. return (1);
  16172. return (0);
  16173. }
  16174. #endif
  16175. #define FACET_RESTR_MUTUAL_ERR(fac1, fac2) \
  16176. xmlSchemaPCustomErrExt(pctxt, \
  16177. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16178. WXS_BASIC_CAST fac1, fac1->node, \
  16179. "It is an error for both '%s' and '%s' to be specified on the "\
  16180. "same type definition", \
  16181. BAD_CAST xmlSchemaFacetTypeToString(fac1->type), \
  16182. BAD_CAST xmlSchemaFacetTypeToString(fac2->type), NULL);
  16183. #define FACET_RESTR_ERR(fac1, msg) \
  16184. xmlSchemaPCustomErr(pctxt, \
  16185. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16186. WXS_BASIC_CAST fac1, fac1->node, \
  16187. msg, NULL);
  16188. #define FACET_RESTR_FIXED_ERR(fac) \
  16189. xmlSchemaPCustomErr(pctxt, \
  16190. XML_SCHEMAP_INVALID_FACET_VALUE, \
  16191. WXS_BASIC_CAST fac, fac->node, \
  16192. "The base type's facet is 'fixed', thus the value must not " \
  16193. "differ", NULL);
  16194. static void
  16195. xmlSchemaDeriveFacetErr(xmlSchemaParserCtxtPtr pctxt,
  16196. xmlSchemaFacetPtr facet1,
  16197. xmlSchemaFacetPtr facet2,
  16198. int lessGreater,
  16199. int orEqual,
  16200. int ofBase)
  16201. {
  16202. xmlChar *msg = NULL;
  16203. msg = xmlStrdup(BAD_CAST "'");
  16204. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet1->type));
  16205. msg = xmlStrcat(msg, BAD_CAST "' has to be");
  16206. if (lessGreater == 0)
  16207. msg = xmlStrcat(msg, BAD_CAST " equal to");
  16208. if (lessGreater == 1)
  16209. msg = xmlStrcat(msg, BAD_CAST " greater than");
  16210. else
  16211. msg = xmlStrcat(msg, BAD_CAST " less than");
  16212. if (orEqual)
  16213. msg = xmlStrcat(msg, BAD_CAST " or equal to");
  16214. msg = xmlStrcat(msg, BAD_CAST " '");
  16215. msg = xmlStrcat(msg, xmlSchemaFacetTypeToString(facet2->type));
  16216. if (ofBase)
  16217. msg = xmlStrcat(msg, BAD_CAST "' of the base type");
  16218. else
  16219. msg = xmlStrcat(msg, BAD_CAST "'");
  16220. xmlSchemaPCustomErr(pctxt,
  16221. XML_SCHEMAP_INVALID_FACET_VALUE,
  16222. WXS_BASIC_CAST facet1, NULL,
  16223. (const char *) msg, NULL);
  16224. if (msg != NULL)
  16225. xmlFree(msg);
  16226. }
  16227. /*
  16228. * xmlSchemaDeriveAndValidateFacets:
  16229. *
  16230. * Schema Component Constraint: Simple Type Restriction (Facets)
  16231. * (st-restrict-facets)
  16232. */
  16233. static int
  16234. xmlSchemaDeriveAndValidateFacets(xmlSchemaParserCtxtPtr pctxt,
  16235. xmlSchemaTypePtr type)
  16236. {
  16237. xmlSchemaTypePtr base = type->baseType;
  16238. xmlSchemaFacetLinkPtr link, cur, last = NULL;
  16239. xmlSchemaFacetPtr facet, bfacet,
  16240. flength = NULL, ftotdig = NULL, ffracdig = NULL,
  16241. fmaxlen = NULL, fminlen = NULL, /* facets of the current type */
  16242. fmininc = NULL, fmaxinc = NULL,
  16243. fminexc = NULL, fmaxexc = NULL,
  16244. bflength = NULL, bftotdig = NULL, bffracdig = NULL,
  16245. bfmaxlen = NULL, bfminlen = NULL, /* facets of the base type */
  16246. bfmininc = NULL, bfmaxinc = NULL,
  16247. bfminexc = NULL, bfmaxexc = NULL;
  16248. int res; /* err = 0, fixedErr; */
  16249. /*
  16250. * SPEC st-restrict-facets 1:
  16251. * "The {variety} of R is the same as that of B."
  16252. */
  16253. /*
  16254. * SPEC st-restrict-facets 2:
  16255. * "If {variety} is atomic, the {primitive type definition}
  16256. * of R is the same as that of B."
  16257. *
  16258. * NOTE: we leave 1 & 2 out for now, since this will be
  16259. * satisfied by the derivation process.
  16260. * CONSTRUCTION TODO: Maybe needed if using a construction API.
  16261. */
  16262. /*
  16263. * SPEC st-restrict-facets 3:
  16264. * "The {facets} of R are the union of S and the {facets}
  16265. * of B, eliminating duplicates. To eliminate duplicates,
  16266. * when a facet of the same kind occurs in both S and the
  16267. * {facets} of B, the one in the {facets} of B is not
  16268. * included, with the exception of enumeration and pattern
  16269. * facets, for which multiple occurrences with distinct values
  16270. * are allowed."
  16271. */
  16272. if ((type->facetSet == NULL) && (base->facetSet == NULL))
  16273. return (0);
  16274. last = type->facetSet;
  16275. if (last != NULL)
  16276. while (last->next != NULL)
  16277. last = last->next;
  16278. for (cur = type->facetSet; cur != NULL; cur = cur->next) {
  16279. facet = cur->facet;
  16280. switch (facet->type) {
  16281. case XML_SCHEMA_FACET_LENGTH:
  16282. flength = facet; break;
  16283. case XML_SCHEMA_FACET_MINLENGTH:
  16284. fminlen = facet; break;
  16285. case XML_SCHEMA_FACET_MININCLUSIVE:
  16286. fmininc = facet; break;
  16287. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16288. fminexc = facet; break;
  16289. case XML_SCHEMA_FACET_MAXLENGTH:
  16290. fmaxlen = facet; break;
  16291. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16292. fmaxinc = facet; break;
  16293. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16294. fmaxexc = facet; break;
  16295. case XML_SCHEMA_FACET_TOTALDIGITS:
  16296. ftotdig = facet; break;
  16297. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16298. ffracdig = facet; break;
  16299. default:
  16300. break;
  16301. }
  16302. }
  16303. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16304. facet = cur->facet;
  16305. switch (facet->type) {
  16306. case XML_SCHEMA_FACET_LENGTH:
  16307. bflength = facet; break;
  16308. case XML_SCHEMA_FACET_MINLENGTH:
  16309. bfminlen = facet; break;
  16310. case XML_SCHEMA_FACET_MININCLUSIVE:
  16311. bfmininc = facet; break;
  16312. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  16313. bfminexc = facet; break;
  16314. case XML_SCHEMA_FACET_MAXLENGTH:
  16315. bfmaxlen = facet; break;
  16316. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  16317. bfmaxinc = facet; break;
  16318. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  16319. bfmaxexc = facet; break;
  16320. case XML_SCHEMA_FACET_TOTALDIGITS:
  16321. bftotdig = facet; break;
  16322. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  16323. bffracdig = facet; break;
  16324. default:
  16325. break;
  16326. }
  16327. }
  16328. /*
  16329. * length and minLength or maxLength (2.2) + (3.2)
  16330. */
  16331. if (flength && (fminlen || fmaxlen)) {
  16332. FACET_RESTR_ERR(flength, "It is an error for both 'length' and "
  16333. "either of 'minLength' or 'maxLength' to be specified on "
  16334. "the same type definition")
  16335. }
  16336. /*
  16337. * Mutual exclusions in the same derivation step.
  16338. */
  16339. if ((fmaxinc) && (fmaxexc)) {
  16340. /*
  16341. * SCC "maxInclusive and maxExclusive"
  16342. */
  16343. FACET_RESTR_MUTUAL_ERR(fmaxinc, fmaxexc)
  16344. }
  16345. if ((fmininc) && (fminexc)) {
  16346. /*
  16347. * SCC "minInclusive and minExclusive"
  16348. */
  16349. FACET_RESTR_MUTUAL_ERR(fmininc, fminexc)
  16350. }
  16351. if (flength && bflength) {
  16352. /*
  16353. * SCC "length valid restriction"
  16354. * The values have to be equal.
  16355. */
  16356. res = xmlSchemaCompareValues(flength->val, bflength->val);
  16357. if (res == -2)
  16358. goto internal_error;
  16359. if (res != 0)
  16360. xmlSchemaDeriveFacetErr(pctxt, flength, bflength, 0, 0, 1);
  16361. if ((res != 0) && (bflength->fixed)) {
  16362. FACET_RESTR_FIXED_ERR(flength)
  16363. }
  16364. }
  16365. if (fminlen && bfminlen) {
  16366. /*
  16367. * SCC "minLength valid restriction"
  16368. * minLength >= BASE minLength
  16369. */
  16370. res = xmlSchemaCompareValues(fminlen->val, bfminlen->val);
  16371. if (res == -2)
  16372. goto internal_error;
  16373. if (res == -1)
  16374. xmlSchemaDeriveFacetErr(pctxt, fminlen, bfminlen, 1, 1, 1);
  16375. if ((res != 0) && (bfminlen->fixed)) {
  16376. FACET_RESTR_FIXED_ERR(fminlen)
  16377. }
  16378. }
  16379. if (fmaxlen && bfmaxlen) {
  16380. /*
  16381. * SCC "maxLength valid restriction"
  16382. * maxLength <= BASE minLength
  16383. */
  16384. res = xmlSchemaCompareValues(fmaxlen->val, bfmaxlen->val);
  16385. if (res == -2)
  16386. goto internal_error;
  16387. if (res == 1)
  16388. xmlSchemaDeriveFacetErr(pctxt, fmaxlen, bfmaxlen, -1, 1, 1);
  16389. if ((res != 0) && (bfmaxlen->fixed)) {
  16390. FACET_RESTR_FIXED_ERR(fmaxlen)
  16391. }
  16392. }
  16393. /*
  16394. * SCC "length and minLength or maxLength"
  16395. */
  16396. if (! flength)
  16397. flength = bflength;
  16398. if (flength) {
  16399. if (! fminlen)
  16400. fminlen = bfminlen;
  16401. if (fminlen) {
  16402. /* (1.1) length >= minLength */
  16403. res = xmlSchemaCompareValues(flength->val, fminlen->val);
  16404. if (res == -2)
  16405. goto internal_error;
  16406. if (res == -1)
  16407. xmlSchemaDeriveFacetErr(pctxt, flength, fminlen, 1, 1, 0);
  16408. }
  16409. if (! fmaxlen)
  16410. fmaxlen = bfmaxlen;
  16411. if (fmaxlen) {
  16412. /* (2.1) length <= maxLength */
  16413. res = xmlSchemaCompareValues(flength->val, fmaxlen->val);
  16414. if (res == -2)
  16415. goto internal_error;
  16416. if (res == 1)
  16417. xmlSchemaDeriveFacetErr(pctxt, flength, fmaxlen, -1, 1, 0);
  16418. }
  16419. }
  16420. if (fmaxinc) {
  16421. /*
  16422. * "maxInclusive"
  16423. */
  16424. if (fmininc) {
  16425. /* SCC "maxInclusive >= minInclusive" */
  16426. res = xmlSchemaCompareValues(fmaxinc->val, fmininc->val);
  16427. if (res == -2)
  16428. goto internal_error;
  16429. if (res == -1) {
  16430. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, fmininc, 1, 1, 0);
  16431. }
  16432. }
  16433. /*
  16434. * SCC "maxInclusive valid restriction"
  16435. */
  16436. if (bfmaxinc) {
  16437. /* maxInclusive <= BASE maxInclusive */
  16438. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxinc->val);
  16439. if (res == -2)
  16440. goto internal_error;
  16441. if (res == 1)
  16442. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxinc, -1, 1, 1);
  16443. if ((res != 0) && (bfmaxinc->fixed)) {
  16444. FACET_RESTR_FIXED_ERR(fmaxinc)
  16445. }
  16446. }
  16447. if (bfmaxexc) {
  16448. /* maxInclusive < BASE maxExclusive */
  16449. res = xmlSchemaCompareValues(fmaxinc->val, bfmaxexc->val);
  16450. if (res == -2)
  16451. goto internal_error;
  16452. if (res != -1) {
  16453. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmaxexc, -1, 0, 1);
  16454. }
  16455. }
  16456. if (bfmininc) {
  16457. /* maxInclusive >= BASE minInclusive */
  16458. res = xmlSchemaCompareValues(fmaxinc->val, bfmininc->val);
  16459. if (res == -2)
  16460. goto internal_error;
  16461. if (res == -1) {
  16462. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfmininc, 1, 1, 1);
  16463. }
  16464. }
  16465. if (bfminexc) {
  16466. /* maxInclusive > BASE minExclusive */
  16467. res = xmlSchemaCompareValues(fmaxinc->val, bfminexc->val);
  16468. if (res == -2)
  16469. goto internal_error;
  16470. if (res != 1) {
  16471. xmlSchemaDeriveFacetErr(pctxt, fmaxinc, bfminexc, 1, 0, 1);
  16472. }
  16473. }
  16474. }
  16475. if (fmaxexc) {
  16476. /*
  16477. * "maxExclusive >= minExclusive"
  16478. */
  16479. if (fminexc) {
  16480. res = xmlSchemaCompareValues(fmaxexc->val, fminexc->val);
  16481. if (res == -2)
  16482. goto internal_error;
  16483. if (res == -1) {
  16484. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, fminexc, 1, 1, 0);
  16485. }
  16486. }
  16487. /*
  16488. * "maxExclusive valid restriction"
  16489. */
  16490. if (bfmaxexc) {
  16491. /* maxExclusive <= BASE maxExclusive */
  16492. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxexc->val);
  16493. if (res == -2)
  16494. goto internal_error;
  16495. if (res == 1) {
  16496. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxexc, -1, 1, 1);
  16497. }
  16498. if ((res != 0) && (bfmaxexc->fixed)) {
  16499. FACET_RESTR_FIXED_ERR(fmaxexc)
  16500. }
  16501. }
  16502. if (bfmaxinc) {
  16503. /* maxExclusive <= BASE maxInclusive */
  16504. res = xmlSchemaCompareValues(fmaxexc->val, bfmaxinc->val);
  16505. if (res == -2)
  16506. goto internal_error;
  16507. if (res == 1) {
  16508. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmaxinc, -1, 1, 1);
  16509. }
  16510. }
  16511. if (bfmininc) {
  16512. /* maxExclusive > BASE minInclusive */
  16513. res = xmlSchemaCompareValues(fmaxexc->val, bfmininc->val);
  16514. if (res == -2)
  16515. goto internal_error;
  16516. if (res != 1) {
  16517. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfmininc, 1, 0, 1);
  16518. }
  16519. }
  16520. if (bfminexc) {
  16521. /* maxExclusive > BASE minExclusive */
  16522. res = xmlSchemaCompareValues(fmaxexc->val, bfminexc->val);
  16523. if (res == -2)
  16524. goto internal_error;
  16525. if (res != 1) {
  16526. xmlSchemaDeriveFacetErr(pctxt, fmaxexc, bfminexc, 1, 0, 1);
  16527. }
  16528. }
  16529. }
  16530. if (fminexc) {
  16531. /*
  16532. * "minExclusive < maxInclusive"
  16533. */
  16534. if (fmaxinc) {
  16535. res = xmlSchemaCompareValues(fminexc->val, fmaxinc->val);
  16536. if (res == -2)
  16537. goto internal_error;
  16538. if (res != -1) {
  16539. xmlSchemaDeriveFacetErr(pctxt, fminexc, fmaxinc, -1, 0, 0);
  16540. }
  16541. }
  16542. /*
  16543. * "minExclusive valid restriction"
  16544. */
  16545. if (bfminexc) {
  16546. /* minExclusive >= BASE minExclusive */
  16547. res = xmlSchemaCompareValues(fminexc->val, bfminexc->val);
  16548. if (res == -2)
  16549. goto internal_error;
  16550. if (res == -1) {
  16551. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfminexc, 1, 1, 1);
  16552. }
  16553. if ((res != 0) && (bfminexc->fixed)) {
  16554. FACET_RESTR_FIXED_ERR(fminexc)
  16555. }
  16556. }
  16557. if (bfmaxinc) {
  16558. /* minExclusive <= BASE maxInclusive */
  16559. res = xmlSchemaCompareValues(fminexc->val, bfmaxinc->val);
  16560. if (res == -2)
  16561. goto internal_error;
  16562. if (res == 1) {
  16563. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxinc, -1, 1, 1);
  16564. }
  16565. }
  16566. if (bfmininc) {
  16567. /* minExclusive >= BASE minInclusive */
  16568. res = xmlSchemaCompareValues(fminexc->val, bfmininc->val);
  16569. if (res == -2)
  16570. goto internal_error;
  16571. if (res == -1) {
  16572. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmininc, 1, 1, 1);
  16573. }
  16574. }
  16575. if (bfmaxexc) {
  16576. /* minExclusive < BASE maxExclusive */
  16577. res = xmlSchemaCompareValues(fminexc->val, bfmaxexc->val);
  16578. if (res == -2)
  16579. goto internal_error;
  16580. if (res != -1) {
  16581. xmlSchemaDeriveFacetErr(pctxt, fminexc, bfmaxexc, -1, 0, 1);
  16582. }
  16583. }
  16584. }
  16585. if (fmininc) {
  16586. /*
  16587. * "minInclusive < maxExclusive"
  16588. */
  16589. if (fmaxexc) {
  16590. res = xmlSchemaCompareValues(fmininc->val, fmaxexc->val);
  16591. if (res == -2)
  16592. goto internal_error;
  16593. if (res != -1) {
  16594. xmlSchemaDeriveFacetErr(pctxt, fmininc, fmaxexc, -1, 0, 0);
  16595. }
  16596. }
  16597. /*
  16598. * "minExclusive valid restriction"
  16599. */
  16600. if (bfmininc) {
  16601. /* minInclusive >= BASE minInclusive */
  16602. res = xmlSchemaCompareValues(fmininc->val, bfmininc->val);
  16603. if (res == -2)
  16604. goto internal_error;
  16605. if (res == -1) {
  16606. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmininc, 1, 1, 1);
  16607. }
  16608. if ((res != 0) && (bfmininc->fixed)) {
  16609. FACET_RESTR_FIXED_ERR(fmininc)
  16610. }
  16611. }
  16612. if (bfmaxinc) {
  16613. /* minInclusive <= BASE maxInclusive */
  16614. res = xmlSchemaCompareValues(fmininc->val, bfmaxinc->val);
  16615. if (res == -2)
  16616. goto internal_error;
  16617. if (res == 1) {
  16618. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxinc, -1, 1, 1);
  16619. }
  16620. }
  16621. if (bfminexc) {
  16622. /* minInclusive > BASE minExclusive */
  16623. res = xmlSchemaCompareValues(fmininc->val, bfminexc->val);
  16624. if (res == -2)
  16625. goto internal_error;
  16626. if (res != 1)
  16627. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfminexc, 1, 0, 1);
  16628. }
  16629. if (bfmaxexc) {
  16630. /* minInclusive < BASE maxExclusive */
  16631. res = xmlSchemaCompareValues(fmininc->val, bfmaxexc->val);
  16632. if (res == -2)
  16633. goto internal_error;
  16634. if (res != -1)
  16635. xmlSchemaDeriveFacetErr(pctxt, fmininc, bfmaxexc, -1, 0, 1);
  16636. }
  16637. }
  16638. if (ftotdig && bftotdig) {
  16639. /*
  16640. * SCC " totalDigits valid restriction"
  16641. * totalDigits <= BASE totalDigits
  16642. */
  16643. res = xmlSchemaCompareValues(ftotdig->val, bftotdig->val);
  16644. if (res == -2)
  16645. goto internal_error;
  16646. if (res == 1)
  16647. xmlSchemaDeriveFacetErr(pctxt, ftotdig, bftotdig,
  16648. -1, 1, 1);
  16649. if ((res != 0) && (bftotdig->fixed)) {
  16650. FACET_RESTR_FIXED_ERR(ftotdig)
  16651. }
  16652. }
  16653. if (ffracdig && bffracdig) {
  16654. /*
  16655. * SCC "fractionDigits valid restriction"
  16656. * fractionDigits <= BASE fractionDigits
  16657. */
  16658. res = xmlSchemaCompareValues(ffracdig->val, bffracdig->val);
  16659. if (res == -2)
  16660. goto internal_error;
  16661. if (res == 1)
  16662. xmlSchemaDeriveFacetErr(pctxt, ffracdig, bffracdig,
  16663. -1, 1, 1);
  16664. if ((res != 0) && (bffracdig->fixed)) {
  16665. FACET_RESTR_FIXED_ERR(ffracdig)
  16666. }
  16667. }
  16668. /*
  16669. * SCC "fractionDigits less than or equal to totalDigits"
  16670. */
  16671. if (! ftotdig)
  16672. ftotdig = bftotdig;
  16673. if (! ffracdig)
  16674. ffracdig = bffracdig;
  16675. if (ftotdig && ffracdig) {
  16676. res = xmlSchemaCompareValues(ffracdig->val, ftotdig->val);
  16677. if (res == -2)
  16678. goto internal_error;
  16679. if (res == 1)
  16680. xmlSchemaDeriveFacetErr(pctxt, ffracdig, ftotdig,
  16681. -1, 1, 0);
  16682. }
  16683. /*
  16684. * *Enumerations* won' be added here, since only the first set
  16685. * of enumerations in the ancestor-or-self axis is used
  16686. * for validation, plus we need to use the base type of those
  16687. * enumerations for whitespace.
  16688. *
  16689. * *Patterns*: won't be add here, since they are ORed at
  16690. * type level and ANDed at ancestor level. This will
  16691. * happen during validation by walking the base axis
  16692. * of the type.
  16693. */
  16694. for (cur = base->facetSet; cur != NULL; cur = cur->next) {
  16695. bfacet = cur->facet;
  16696. /*
  16697. * Special handling of enumerations and patterns.
  16698. * TODO: hmm, they should not appear in the set, so remove this.
  16699. */
  16700. if ((bfacet->type == XML_SCHEMA_FACET_PATTERN) ||
  16701. (bfacet->type == XML_SCHEMA_FACET_ENUMERATION))
  16702. continue;
  16703. /*
  16704. * Search for a duplicate facet in the current type.
  16705. */
  16706. link = type->facetSet;
  16707. /* err = 0; */
  16708. /* fixedErr = 0; */
  16709. while (link != NULL) {
  16710. facet = link->facet;
  16711. if (facet->type == bfacet->type) {
  16712. switch (facet->type) {
  16713. case XML_SCHEMA_FACET_WHITESPACE:
  16714. /*
  16715. * The whitespace must be stronger.
  16716. */
  16717. if (facet->whitespace < bfacet->whitespace) {
  16718. FACET_RESTR_ERR(facet,
  16719. "The 'whitespace' value has to be equal to "
  16720. "or stronger than the 'whitespace' value of "
  16721. "the base type")
  16722. }
  16723. if ((bfacet->fixed) &&
  16724. (facet->whitespace != bfacet->whitespace)) {
  16725. FACET_RESTR_FIXED_ERR(facet)
  16726. }
  16727. break;
  16728. default:
  16729. break;
  16730. }
  16731. /* Duplicate found. */
  16732. break;
  16733. }
  16734. link = link->next;
  16735. }
  16736. /*
  16737. * If no duplicate was found: add the base types's facet
  16738. * to the set.
  16739. */
  16740. if (link == NULL) {
  16741. link = (xmlSchemaFacetLinkPtr)
  16742. xmlMalloc(sizeof(xmlSchemaFacetLink));
  16743. if (link == NULL) {
  16744. xmlSchemaPErrMemory(pctxt,
  16745. "deriving facets, creating a facet link", NULL);
  16746. return (-1);
  16747. }
  16748. link->facet = cur->facet;
  16749. link->next = NULL;
  16750. if (last == NULL)
  16751. type->facetSet = link;
  16752. else
  16753. last->next = link;
  16754. last = link;
  16755. }
  16756. }
  16757. return (0);
  16758. internal_error:
  16759. PERROR_INT("xmlSchemaDeriveAndValidateFacets",
  16760. "an error occurred");
  16761. return (-1);
  16762. }
  16763. static int
  16764. xmlSchemaFinishMemberTypeDefinitionsProperty(xmlSchemaParserCtxtPtr pctxt,
  16765. xmlSchemaTypePtr type)
  16766. {
  16767. xmlSchemaTypeLinkPtr link, lastLink, prevLink, subLink, newLink;
  16768. /*
  16769. * The actual value is then formed by replacing any union type
  16770. * definition in the `explicit members` with the members of their
  16771. * {member type definitions}, in order.
  16772. *
  16773. * TODO: There's a bug entry at
  16774. * "http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0287.html"
  16775. * which indicates that we'll keep the union types the future.
  16776. */
  16777. link = type->memberTypes;
  16778. while (link != NULL) {
  16779. if (WXS_IS_TYPE_NOT_FIXED(link->type))
  16780. xmlSchemaTypeFixup(link->type, ACTXT_CAST pctxt);
  16781. if (WXS_IS_UNION(link->type)) {
  16782. subLink = xmlSchemaGetUnionSimpleTypeMemberTypes(link->type);
  16783. if (subLink != NULL) {
  16784. link->type = subLink->type;
  16785. if (subLink->next != NULL) {
  16786. lastLink = link->next;
  16787. subLink = subLink->next;
  16788. prevLink = link;
  16789. while (subLink != NULL) {
  16790. newLink = (xmlSchemaTypeLinkPtr)
  16791. xmlMalloc(sizeof(xmlSchemaTypeLink));
  16792. if (newLink == NULL) {
  16793. xmlSchemaPErrMemory(pctxt, "allocating a type link",
  16794. NULL);
  16795. return (-1);
  16796. }
  16797. newLink->type = subLink->type;
  16798. prevLink->next = newLink;
  16799. prevLink = newLink;
  16800. newLink->next = lastLink;
  16801. subLink = subLink->next;
  16802. }
  16803. }
  16804. }
  16805. }
  16806. link = link->next;
  16807. }
  16808. return (0);
  16809. }
  16810. static void
  16811. xmlSchemaTypeFixupOptimFacets(xmlSchemaTypePtr type)
  16812. {
  16813. int has = 0, needVal = 0, normVal = 0;
  16814. has = (type->baseType->flags & XML_SCHEMAS_TYPE_HAS_FACETS) ? 1 : 0;
  16815. if (has) {
  16816. needVal = (type->baseType->flags &
  16817. XML_SCHEMAS_TYPE_FACETSNEEDVALUE) ? 1 : 0;
  16818. normVal = (type->baseType->flags &
  16819. XML_SCHEMAS_TYPE_NORMVALUENEEDED) ? 1 : 0;
  16820. }
  16821. if (type->facets != NULL) {
  16822. xmlSchemaFacetPtr fac;
  16823. for (fac = type->facets; fac != NULL; fac = fac->next) {
  16824. switch (fac->type) {
  16825. case XML_SCHEMA_FACET_WHITESPACE:
  16826. break;
  16827. case XML_SCHEMA_FACET_PATTERN:
  16828. normVal = 1;
  16829. has = 1;
  16830. break;
  16831. case XML_SCHEMA_FACET_ENUMERATION:
  16832. needVal = 1;
  16833. normVal = 1;
  16834. has = 1;
  16835. break;
  16836. default:
  16837. has = 1;
  16838. break;
  16839. }
  16840. }
  16841. }
  16842. if (normVal)
  16843. type->flags |= XML_SCHEMAS_TYPE_NORMVALUENEEDED;
  16844. if (needVal)
  16845. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16846. if (has)
  16847. type->flags |= XML_SCHEMAS_TYPE_HAS_FACETS;
  16848. if (has && (! needVal) && WXS_IS_ATOMIC(type)) {
  16849. xmlSchemaTypePtr prim = xmlSchemaGetPrimitiveType(type);
  16850. /*
  16851. * OPTIMIZE VAL TODO: Some facets need a computed value.
  16852. */
  16853. if ((prim->builtInType != XML_SCHEMAS_ANYSIMPLETYPE) &&
  16854. (prim->builtInType != XML_SCHEMAS_STRING)) {
  16855. type->flags |= XML_SCHEMAS_TYPE_FACETSNEEDVALUE;
  16856. }
  16857. }
  16858. }
  16859. static int
  16860. xmlSchemaTypeFixupWhitespace(xmlSchemaTypePtr type)
  16861. {
  16862. /*
  16863. * Evaluate the whitespace-facet value.
  16864. */
  16865. if (WXS_IS_LIST(type)) {
  16866. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16867. return (0);
  16868. } else if (WXS_IS_UNION(type))
  16869. return (0);
  16870. if (type->facetSet != NULL) {
  16871. xmlSchemaFacetLinkPtr lin;
  16872. for (lin = type->facetSet; lin != NULL; lin = lin->next) {
  16873. if (lin->facet->type == XML_SCHEMA_FACET_WHITESPACE) {
  16874. switch (lin->facet->whitespace) {
  16875. case XML_SCHEMAS_FACET_PRESERVE:
  16876. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16877. break;
  16878. case XML_SCHEMAS_FACET_REPLACE:
  16879. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16880. break;
  16881. case XML_SCHEMAS_FACET_COLLAPSE:
  16882. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16883. break;
  16884. default:
  16885. return (-1);
  16886. }
  16887. return (0);
  16888. }
  16889. }
  16890. }
  16891. /*
  16892. * For all `atomic` datatypes other than string (and types `derived`
  16893. * by `restriction` from it) the value of whiteSpace is fixed to
  16894. * collapse
  16895. */
  16896. {
  16897. xmlSchemaTypePtr anc;
  16898. for (anc = type->baseType; anc != NULL &&
  16899. anc->builtInType != XML_SCHEMAS_ANYTYPE;
  16900. anc = anc->baseType) {
  16901. if (anc->type == XML_SCHEMA_TYPE_BASIC) {
  16902. if (anc->builtInType == XML_SCHEMAS_NORMSTRING) {
  16903. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_REPLACE;
  16904. } else if ((anc->builtInType == XML_SCHEMAS_STRING) ||
  16905. (anc->builtInType == XML_SCHEMAS_ANYSIMPLETYPE)) {
  16906. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE;
  16907. } else
  16908. type->flags |= XML_SCHEMAS_TYPE_WHITESPACE_COLLAPSE;
  16909. break;
  16910. }
  16911. }
  16912. }
  16913. return (0);
  16914. }
  16915. static int
  16916. xmlSchemaFixupSimpleTypeStageOne(xmlSchemaParserCtxtPtr pctxt,
  16917. xmlSchemaTypePtr type)
  16918. {
  16919. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  16920. return(0);
  16921. if (! WXS_IS_TYPE_NOT_FIXED_1(type))
  16922. return(0);
  16923. type->flags |= XML_SCHEMAS_TYPE_FIXUP_1;
  16924. if (WXS_IS_LIST(type)) {
  16925. /*
  16926. * Corresponds to <simpleType><list>...
  16927. */
  16928. if (type->subtypes == NULL) {
  16929. /*
  16930. * This one is really needed, so get out.
  16931. */
  16932. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16933. "list type has no item-type assigned");
  16934. return(-1);
  16935. }
  16936. } else if (WXS_IS_UNION(type)) {
  16937. /*
  16938. * Corresponds to <simpleType><union>...
  16939. */
  16940. if (type->memberTypes == NULL) {
  16941. /*
  16942. * This one is really needed, so get out.
  16943. */
  16944. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16945. "union type has no member-types assigned");
  16946. return(-1);
  16947. }
  16948. } else {
  16949. /*
  16950. * Corresponds to <simpleType><restriction>...
  16951. */
  16952. if (type->baseType == NULL) {
  16953. PERROR_INT("xmlSchemaFixupSimpleTypeStageOne",
  16954. "type has no base-type assigned");
  16955. return(-1);
  16956. }
  16957. if (WXS_IS_TYPE_NOT_FIXED_1(type->baseType))
  16958. if (xmlSchemaFixupSimpleTypeStageOne(pctxt, type->baseType) == -1)
  16959. return(-1);
  16960. /*
  16961. * Variety
  16962. * If the <restriction> alternative is chosen, then the
  16963. * {variety} of the {base type definition}.
  16964. */
  16965. if (WXS_IS_ATOMIC(type->baseType))
  16966. type->flags |= XML_SCHEMAS_TYPE_VARIETY_ATOMIC;
  16967. else if (WXS_IS_LIST(type->baseType)) {
  16968. type->flags |= XML_SCHEMAS_TYPE_VARIETY_LIST;
  16969. /*
  16970. * Inherit the itemType.
  16971. */
  16972. type->subtypes = type->baseType->subtypes;
  16973. } else if (WXS_IS_UNION(type->baseType)) {
  16974. type->flags |= XML_SCHEMAS_TYPE_VARIETY_UNION;
  16975. /*
  16976. * NOTE that we won't assign the memberTypes of the base,
  16977. * since this will make trouble when freeing them; we will
  16978. * use a lookup function to access them instead.
  16979. */
  16980. }
  16981. }
  16982. return(0);
  16983. }
  16984. #ifdef DEBUG_TYPE
  16985. static void
  16986. xmlSchemaDebugFixedType(xmlSchemaParserCtxtPtr pctxt,
  16987. xmlSchemaTypePtr type)
  16988. {
  16989. if (type->node != NULL) {
  16990. xmlGenericError(xmlGenericErrorContext,
  16991. "Type of %s : %s:%d :", name,
  16992. type->node->doc->URL,
  16993. xmlGetLineNo(type->node));
  16994. } else {
  16995. xmlGenericError(xmlGenericErrorContext, "Type of %s :", name);
  16996. }
  16997. if ((WXS_IS_SIMPLE(type)) || (WXS_IS_COMPLEX(type))) {
  16998. switch (type->contentType) {
  16999. case XML_SCHEMA_CONTENT_SIMPLE:
  17000. xmlGenericError(xmlGenericErrorContext, "simple\n");
  17001. break;
  17002. case XML_SCHEMA_CONTENT_ELEMENTS:
  17003. xmlGenericError(xmlGenericErrorContext, "elements\n");
  17004. break;
  17005. case XML_SCHEMA_CONTENT_UNKNOWN:
  17006. xmlGenericError(xmlGenericErrorContext, "unknown !!!\n");
  17007. break;
  17008. case XML_SCHEMA_CONTENT_EMPTY:
  17009. xmlGenericError(xmlGenericErrorContext, "empty\n");
  17010. break;
  17011. case XML_SCHEMA_CONTENT_MIXED:
  17012. if (xmlSchemaIsParticleEmptiable((xmlSchemaParticlePtr)
  17013. type->subtypes))
  17014. xmlGenericError(xmlGenericErrorContext,
  17015. "mixed as emptiable particle\n");
  17016. else
  17017. xmlGenericError(xmlGenericErrorContext, "mixed\n");
  17018. break;
  17019. /* Removed, since not used. */
  17020. /*
  17021. case XML_SCHEMA_CONTENT_MIXED_OR_ELEMENTS:
  17022. xmlGenericError(xmlGenericErrorContext, "mixed or elems\n");
  17023. break;
  17024. */
  17025. case XML_SCHEMA_CONTENT_BASIC:
  17026. xmlGenericError(xmlGenericErrorContext, "basic\n");
  17027. break;
  17028. default:
  17029. xmlGenericError(xmlGenericErrorContext,
  17030. "not registered !!!\n");
  17031. break;
  17032. }
  17033. }
  17034. }
  17035. #endif
  17036. /*
  17037. * 3.14.6 Constraints on Simple Type Definition Schema Components
  17038. */
  17039. static int
  17040. xmlSchemaFixupSimpleTypeStageTwo(xmlSchemaParserCtxtPtr pctxt,
  17041. xmlSchemaTypePtr type)
  17042. {
  17043. int res, olderrs = pctxt->nberrors;
  17044. if (type->type != XML_SCHEMA_TYPE_SIMPLE)
  17045. return(-1);
  17046. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17047. return(0);
  17048. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17049. type->contentType = XML_SCHEMA_CONTENT_SIMPLE;
  17050. if (type->baseType == NULL) {
  17051. PERROR_INT("xmlSchemaFixupSimpleTypeStageTwo",
  17052. "missing baseType");
  17053. goto exit_failure;
  17054. }
  17055. if (WXS_IS_TYPE_NOT_FIXED(type->baseType))
  17056. xmlSchemaTypeFixup(type->baseType, ACTXT_CAST pctxt);
  17057. /*
  17058. * If a member type of a union is a union itself, we need to substitute
  17059. * that member type for its member types.
  17060. * NOTE that this might change in WXS 1.1; i.e. we will keep the union
  17061. * types in WXS 1.1.
  17062. */
  17063. if ((type->memberTypes != NULL) &&
  17064. (xmlSchemaFinishMemberTypeDefinitionsProperty(pctxt, type) == -1))
  17065. return(-1);
  17066. /*
  17067. * SPEC src-simple-type 1
  17068. * "The corresponding simple type definition, if any, must satisfy
  17069. * the conditions set out in Constraints on Simple Type Definition
  17070. * Schema Components ($3.14.6)."
  17071. */
  17072. /*
  17073. * Schema Component Constraint: Simple Type Definition Properties Correct
  17074. * (st-props-correct)
  17075. */
  17076. res = xmlSchemaCheckSTPropsCorrect(pctxt, type);
  17077. HFAILURE HERROR
  17078. /*
  17079. * Schema Component Constraint: Derivation Valid (Restriction, Simple)
  17080. * (cos-st-restricts)
  17081. */
  17082. res = xmlSchemaCheckCOSSTRestricts(pctxt, type);
  17083. HFAILURE HERROR
  17084. /*
  17085. * TODO: Removed the error report, since it got annoying to get an
  17086. * extra error report, if anything failed until now.
  17087. * Enable this if needed.
  17088. *
  17089. * xmlSchemaPErr(ctxt, type->node,
  17090. * XML_SCHEMAP_SRC_SIMPLE_TYPE_1,
  17091. * "Simple type '%s' does not satisfy the constraints "
  17092. * "on simple type definitions.\n",
  17093. * type->name, NULL);
  17094. */
  17095. /*
  17096. * Schema Component Constraint: Simple Type Restriction (Facets)
  17097. * (st-restrict-facets)
  17098. */
  17099. res = xmlSchemaCheckFacetValues(type, pctxt);
  17100. HFAILURE HERROR
  17101. if ((type->facetSet != NULL) ||
  17102. (type->baseType->facetSet != NULL)) {
  17103. res = xmlSchemaDeriveAndValidateFacets(pctxt, type);
  17104. HFAILURE HERROR
  17105. }
  17106. /*
  17107. * Whitespace value.
  17108. */
  17109. res = xmlSchemaTypeFixupWhitespace(type);
  17110. HFAILURE HERROR
  17111. xmlSchemaTypeFixupOptimFacets(type);
  17112. exit_error:
  17113. #ifdef DEBUG_TYPE
  17114. xmlSchemaDebugFixedType(pctxt, type);
  17115. #endif
  17116. if (olderrs != pctxt->nberrors)
  17117. return(pctxt->err);
  17118. return(0);
  17119. exit_failure:
  17120. #ifdef DEBUG_TYPE
  17121. xmlSchemaDebugFixedType(pctxt, type);
  17122. #endif
  17123. return(-1);
  17124. }
  17125. static int
  17126. xmlSchemaFixupComplexType(xmlSchemaParserCtxtPtr pctxt,
  17127. xmlSchemaTypePtr type)
  17128. {
  17129. int res = 0, olderrs = pctxt->nberrors;
  17130. xmlSchemaTypePtr baseType = type->baseType;
  17131. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17132. return(0);
  17133. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_RESOLVED;
  17134. if (baseType == NULL) {
  17135. PERROR_INT("xmlSchemaFixupComplexType",
  17136. "missing baseType");
  17137. goto exit_failure;
  17138. }
  17139. /*
  17140. * Fixup the base type.
  17141. */
  17142. if (WXS_IS_TYPE_NOT_FIXED(baseType))
  17143. xmlSchemaTypeFixup(baseType, ACTXT_CAST pctxt);
  17144. if (baseType->flags & XML_SCHEMAS_TYPE_INTERNAL_INVALID) {
  17145. /*
  17146. * Skip fixup if the base type is invalid.
  17147. * TODO: Generate a warning!
  17148. */
  17149. return(0);
  17150. }
  17151. /*
  17152. * This basically checks if the base type can be derived.
  17153. */
  17154. res = xmlSchemaCheckSRCCT(pctxt, type);
  17155. HFAILURE HERROR
  17156. /*
  17157. * Fixup the content type.
  17158. */
  17159. if (type->contentType == XML_SCHEMA_CONTENT_SIMPLE) {
  17160. /*
  17161. * Corresponds to <complexType><simpleContent>...
  17162. */
  17163. if ((WXS_IS_COMPLEX(baseType)) &&
  17164. (baseType->contentTypeDef != NULL) &&
  17165. (WXS_IS_RESTRICTION(type))) {
  17166. xmlSchemaTypePtr contentBase, content;
  17167. #ifdef ENABLE_NAMED_LOCALS
  17168. char buf[30];
  17169. const xmlChar *tmpname;
  17170. #endif
  17171. /*
  17172. * SPEC (1) If <restriction> + base type is <complexType>,
  17173. * "whose own {content type} is a simple type..."
  17174. */
  17175. if (type->contentTypeDef != NULL) {
  17176. /*
  17177. * SPEC (1.1) "the simple type definition corresponding to the
  17178. * <simpleType> among the [children] of <restriction> if there
  17179. * is one;"
  17180. * Note that this "<simpleType> among the [children]" was put
  17181. * into ->contentTypeDef during parsing.
  17182. */
  17183. contentBase = type->contentTypeDef;
  17184. type->contentTypeDef = NULL;
  17185. } else {
  17186. /*
  17187. * (1.2) "...otherwise (<restriction> has no <simpleType>
  17188. * among its [children]), the simple type definition which
  17189. * is the {content type} of the ... base type."
  17190. */
  17191. contentBase = baseType->contentTypeDef;
  17192. }
  17193. /*
  17194. * SPEC
  17195. * "... a simple type definition which restricts the simple
  17196. * type definition identified in clause 1.1 or clause 1.2
  17197. * with a set of facet components"
  17198. *
  17199. * Create the anonymous simple type, which will be the content
  17200. * type of the complex type.
  17201. */
  17202. #ifdef ENABLE_NAMED_LOCALS
  17203. snprintf(buf, 29, "#scST%d", ++(pctxt->counter));
  17204. tmpname = xmlDictLookup(pctxt->dict, BAD_CAST buf, -1);
  17205. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17206. XML_SCHEMA_TYPE_SIMPLE, tmpname, type->targetNamespace,
  17207. type->node, 0);
  17208. #else
  17209. content = xmlSchemaAddType(pctxt, pctxt->schema,
  17210. XML_SCHEMA_TYPE_SIMPLE, NULL, type->targetNamespace,
  17211. type->node, 0);
  17212. #endif
  17213. if (content == NULL)
  17214. goto exit_failure;
  17215. /*
  17216. * We will use the same node as for the <complexType>
  17217. * to have it somehow anchored in the schema doc.
  17218. */
  17219. content->type = XML_SCHEMA_TYPE_SIMPLE;
  17220. content->baseType = contentBase;
  17221. /*
  17222. * Move the facets, previously anchored on the
  17223. * complexType during parsing.
  17224. */
  17225. content->facets = type->facets;
  17226. type->facets = NULL;
  17227. content->facetSet = type->facetSet;
  17228. type->facetSet = NULL;
  17229. type->contentTypeDef = content;
  17230. if (WXS_IS_TYPE_NOT_FIXED(contentBase))
  17231. xmlSchemaTypeFixup(contentBase, ACTXT_CAST pctxt);
  17232. /*
  17233. * Fixup the newly created type. We don't need to check
  17234. * for circularity here.
  17235. */
  17236. res = xmlSchemaFixupSimpleTypeStageOne(pctxt, content);
  17237. HFAILURE HERROR
  17238. res = xmlSchemaFixupSimpleTypeStageTwo(pctxt, content);
  17239. HFAILURE HERROR
  17240. } else if ((WXS_IS_COMPLEX(baseType)) &&
  17241. (baseType->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  17242. (WXS_IS_RESTRICTION(type))) {
  17243. /*
  17244. * SPEC (2) If <restriction> + base is a mixed <complexType> with
  17245. * an emptiable particle, then a simple type definition which
  17246. * restricts the <restriction>'s <simpleType> child.
  17247. */
  17248. if ((type->contentTypeDef == NULL) ||
  17249. (type->contentTypeDef->baseType == NULL)) {
  17250. /*
  17251. * TODO: Check if this ever happens.
  17252. */
  17253. xmlSchemaPCustomErr(pctxt,
  17254. XML_SCHEMAP_INTERNAL,
  17255. WXS_BASIC_CAST type, NULL,
  17256. "Internal error: xmlSchemaTypeFixup, "
  17257. "complex type '%s': the <simpleContent><restriction> "
  17258. "is missing a <simpleType> child, but was not caught "
  17259. "by xmlSchemaCheckSRCCT()", type->name);
  17260. goto exit_failure;
  17261. }
  17262. } else if ((WXS_IS_COMPLEX(baseType)) && WXS_IS_EXTENSION(type)) {
  17263. /*
  17264. * SPEC (3) If <extension> + base is <complexType> with
  17265. * <simpleType> content, "...then the {content type} of that
  17266. * complex type definition"
  17267. */
  17268. if (baseType->contentTypeDef == NULL) {
  17269. /*
  17270. * TODO: Check if this ever happens. xmlSchemaCheckSRCCT
  17271. * should have caught this already.
  17272. */
  17273. xmlSchemaPCustomErr(pctxt,
  17274. XML_SCHEMAP_INTERNAL,
  17275. WXS_BASIC_CAST type, NULL,
  17276. "Internal error: xmlSchemaTypeFixup, "
  17277. "complex type '%s': the <extension>ed base type is "
  17278. "a complex type with no simple content type",
  17279. type->name);
  17280. goto exit_failure;
  17281. }
  17282. type->contentTypeDef = baseType->contentTypeDef;
  17283. } else if ((WXS_IS_SIMPLE(baseType)) && WXS_IS_EXTENSION(type)) {
  17284. /*
  17285. * SPEC (4) <extension> + base is <simpleType>
  17286. * "... then that simple type definition"
  17287. */
  17288. type->contentTypeDef = baseType;
  17289. } else {
  17290. /*
  17291. * TODO: Check if this ever happens.
  17292. */
  17293. xmlSchemaPCustomErr(pctxt,
  17294. XML_SCHEMAP_INTERNAL,
  17295. WXS_BASIC_CAST type, NULL,
  17296. "Internal error: xmlSchemaTypeFixup, "
  17297. "complex type '%s' with <simpleContent>: unhandled "
  17298. "derivation case", type->name);
  17299. goto exit_failure;
  17300. }
  17301. } else {
  17302. int dummySequence = 0;
  17303. xmlSchemaParticlePtr particle =
  17304. (xmlSchemaParticlePtr) type->subtypes;
  17305. /*
  17306. * Corresponds to <complexType><complexContent>...
  17307. *
  17308. * NOTE that the effective mixed was already set during parsing of
  17309. * <complexType> and <complexContent>; its flag value is
  17310. * XML_SCHEMAS_TYPE_MIXED.
  17311. *
  17312. * Compute the "effective content":
  17313. * (2.1.1) + (2.1.2) + (2.1.3)
  17314. */
  17315. if ((particle == NULL) ||
  17316. ((particle->type == XML_SCHEMA_TYPE_PARTICLE) &&
  17317. ((particle->children->type == XML_SCHEMA_TYPE_ALL) ||
  17318. (particle->children->type == XML_SCHEMA_TYPE_SEQUENCE) ||
  17319. ((particle->children->type == XML_SCHEMA_TYPE_CHOICE) &&
  17320. (particle->minOccurs == 0))) &&
  17321. ( ((xmlSchemaTreeItemPtr) particle->children)->children == NULL))) {
  17322. if (type->flags & XML_SCHEMAS_TYPE_MIXED) {
  17323. /*
  17324. * SPEC (2.1.4) "If the `effective mixed` is true, then
  17325. * a particle whose properties are as follows:..."
  17326. *
  17327. * Empty sequence model group with
  17328. * minOccurs/maxOccurs = 1 (i.e. a "particle emptiable").
  17329. * NOTE that we sill assign it the <complexType> node to
  17330. * somehow anchor it in the doc.
  17331. */
  17332. if ((particle == NULL) ||
  17333. (particle->children->type != XML_SCHEMA_TYPE_SEQUENCE)) {
  17334. /*
  17335. * Create the particle.
  17336. */
  17337. particle = xmlSchemaAddParticle(pctxt,
  17338. type->node, 1, 1);
  17339. if (particle == NULL)
  17340. goto exit_failure;
  17341. /*
  17342. * Create the model group.
  17343. */ /* URGENT TODO: avoid adding to pending items. */
  17344. particle->children = (xmlSchemaTreeItemPtr)
  17345. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17346. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17347. if (particle->children == NULL)
  17348. goto exit_failure;
  17349. type->subtypes = (xmlSchemaTypePtr) particle;
  17350. }
  17351. dummySequence = 1;
  17352. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17353. } else {
  17354. /*
  17355. * SPEC (2.1.5) "otherwise empty"
  17356. */
  17357. type->contentType = XML_SCHEMA_CONTENT_EMPTY;
  17358. }
  17359. } else {
  17360. /*
  17361. * SPEC (2.2) "otherwise the particle corresponding to the
  17362. * <all>, <choice>, <group> or <sequence> among the
  17363. * [children]."
  17364. */
  17365. type->contentType = XML_SCHEMA_CONTENT_ELEMENTS;
  17366. }
  17367. /*
  17368. * Compute the "content type".
  17369. */
  17370. if (WXS_IS_RESTRICTION(type)) {
  17371. /*
  17372. * SPEC (3.1) "If <restriction>..."
  17373. * (3.1.1) + (3.1.2) */
  17374. if (type->contentType != XML_SCHEMA_CONTENT_EMPTY) {
  17375. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17376. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17377. }
  17378. } else {
  17379. /*
  17380. * SPEC (3.2) "If <extension>..."
  17381. */
  17382. if (type->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17383. /*
  17384. * SPEC (3.2.1)
  17385. * "If the `effective content` is empty, then the
  17386. * {content type} of the [...] base ..."
  17387. */
  17388. type->contentType = baseType->contentType;
  17389. type->subtypes = baseType->subtypes;
  17390. /*
  17391. * Fixes bug #347316:
  17392. * This is the case when the base type has a simple
  17393. * type definition as content.
  17394. */
  17395. type->contentTypeDef = baseType->contentTypeDef;
  17396. /*
  17397. * NOTE that the effective mixed is ignored here.
  17398. */
  17399. } else if (baseType->contentType == XML_SCHEMA_CONTENT_EMPTY) {
  17400. /*
  17401. * SPEC (3.2.2)
  17402. */
  17403. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17404. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17405. } else {
  17406. /*
  17407. * SPEC (3.2.3)
  17408. */
  17409. if (type->flags & XML_SCHEMAS_TYPE_MIXED)
  17410. type->contentType = XML_SCHEMA_CONTENT_MIXED;
  17411. /*
  17412. * "A model group whose {compositor} is sequence and whose
  17413. * {particles} are..."
  17414. */
  17415. if ((WXS_TYPE_PARTICLE(type) != NULL) &&
  17416. (WXS_TYPE_PARTICLE_TERM(type) != NULL) &&
  17417. ((WXS_TYPE_PARTICLE_TERM(type))->type ==
  17418. XML_SCHEMA_TYPE_ALL))
  17419. {
  17420. /*
  17421. * SPEC cos-all-limited (1)
  17422. */
  17423. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17424. /* TODO: error code */
  17425. XML_SCHEMAP_COS_ALL_LIMITED,
  17426. WXS_ITEM_NODE(type), NULL,
  17427. "The type has an 'all' model group in its "
  17428. "{content type} and thus cannot be derived from "
  17429. "a non-empty type, since this would produce a "
  17430. "'sequence' model group containing the 'all' "
  17431. "model group; 'all' model groups are not "
  17432. "allowed to appear inside other model groups",
  17433. NULL, NULL);
  17434. } else if ((WXS_TYPE_PARTICLE(baseType) != NULL) &&
  17435. (WXS_TYPE_PARTICLE_TERM(baseType) != NULL) &&
  17436. ((WXS_TYPE_PARTICLE_TERM(baseType))->type ==
  17437. XML_SCHEMA_TYPE_ALL))
  17438. {
  17439. /*
  17440. * SPEC cos-all-limited (1)
  17441. */
  17442. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17443. /* TODO: error code */
  17444. XML_SCHEMAP_COS_ALL_LIMITED,
  17445. WXS_ITEM_NODE(type), NULL,
  17446. "A type cannot be derived by extension from a type "
  17447. "which has an 'all' model group in its "
  17448. "{content type}, since this would produce a "
  17449. "'sequence' model group containing the 'all' "
  17450. "model group; 'all' model groups are not "
  17451. "allowed to appear inside other model groups",
  17452. NULL, NULL);
  17453. } else if (! dummySequence) {
  17454. xmlSchemaTreeItemPtr effectiveContent =
  17455. (xmlSchemaTreeItemPtr) type->subtypes;
  17456. /*
  17457. * Create the particle.
  17458. */
  17459. particle = xmlSchemaAddParticle(pctxt,
  17460. type->node, 1, 1);
  17461. if (particle == NULL)
  17462. goto exit_failure;
  17463. /*
  17464. * Create the "sequence" model group.
  17465. */
  17466. particle->children = (xmlSchemaTreeItemPtr)
  17467. xmlSchemaAddModelGroup(pctxt, pctxt->schema,
  17468. XML_SCHEMA_TYPE_SEQUENCE, type->node);
  17469. if (particle->children == NULL)
  17470. goto exit_failure;
  17471. WXS_TYPE_CONTENTTYPE(type) = (xmlSchemaTypePtr) particle;
  17472. /*
  17473. * SPEC "the particle of the {content type} of
  17474. * the ... base ..."
  17475. * Create a duplicate of the base type's particle
  17476. * and assign its "term" to it.
  17477. */
  17478. particle->children->children =
  17479. (xmlSchemaTreeItemPtr) xmlSchemaAddParticle(pctxt,
  17480. type->node,
  17481. ((xmlSchemaParticlePtr) baseType->subtypes)->minOccurs,
  17482. ((xmlSchemaParticlePtr) baseType->subtypes)->maxOccurs);
  17483. if (particle->children->children == NULL)
  17484. goto exit_failure;
  17485. particle = (xmlSchemaParticlePtr)
  17486. particle->children->children;
  17487. particle->children =
  17488. ((xmlSchemaParticlePtr) baseType->subtypes)->children;
  17489. /*
  17490. * SPEC "followed by the `effective content`."
  17491. */
  17492. particle->next = effectiveContent;
  17493. /*
  17494. * This all will result in:
  17495. * new-particle
  17496. * --> new-sequence(
  17497. * new-particle
  17498. * --> base-model,
  17499. * this-particle
  17500. * --> this-model
  17501. * )
  17502. */
  17503. } else {
  17504. /*
  17505. * This is the case when there is already an empty
  17506. * <sequence> with minOccurs==maxOccurs==1.
  17507. * Just add the base types's content type.
  17508. * NOTE that, although we miss to add an intermediate
  17509. * <sequence>, this should produce no difference to
  17510. * neither the regex compilation of the content model,
  17511. * nor to the complex type constraints.
  17512. */
  17513. particle->children->children =
  17514. (xmlSchemaTreeItemPtr) baseType->subtypes;
  17515. }
  17516. }
  17517. }
  17518. }
  17519. /*
  17520. * Now fixup attribute uses:
  17521. * - expand attr. group references
  17522. * - intersect attribute wildcards
  17523. * - inherit attribute uses of the base type
  17524. * - inherit or union attr. wildcards if extending
  17525. * - apply attr. use prohibitions if restricting
  17526. */
  17527. res = xmlSchemaFixupTypeAttributeUses(pctxt, type);
  17528. HFAILURE HERROR
  17529. /*
  17530. * Apply the complex type component constraints; this will not
  17531. * check attributes, since this is done in
  17532. * xmlSchemaFixupTypeAttributeUses().
  17533. */
  17534. res = xmlSchemaCheckCTComponent(pctxt, type);
  17535. HFAILURE HERROR
  17536. #ifdef DEBUG_TYPE
  17537. xmlSchemaDebugFixedType(pctxt, type);
  17538. #endif
  17539. if (olderrs != pctxt->nberrors)
  17540. return(pctxt->err);
  17541. else
  17542. return(0);
  17543. exit_error:
  17544. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17545. #ifdef DEBUG_TYPE
  17546. xmlSchemaDebugFixedType(pctxt, type);
  17547. #endif
  17548. return(pctxt->err);
  17549. exit_failure:
  17550. type->flags |= XML_SCHEMAS_TYPE_INTERNAL_INVALID;
  17551. #ifdef DEBUG_TYPE
  17552. xmlSchemaDebugFixedType(pctxt, type);
  17553. #endif
  17554. return(-1);
  17555. }
  17556. /**
  17557. * xmlSchemaTypeFixup:
  17558. * @typeDecl: the schema type definition
  17559. * @ctxt: the schema parser context
  17560. *
  17561. * Fixes the content model of the type.
  17562. * URGENT TODO: We need an int result!
  17563. */
  17564. static int
  17565. xmlSchemaTypeFixup(xmlSchemaTypePtr type,
  17566. xmlSchemaAbstractCtxtPtr actxt)
  17567. {
  17568. if (type == NULL)
  17569. return(0);
  17570. if (actxt->type != XML_SCHEMA_CTXT_PARSER) {
  17571. AERROR_INT("xmlSchemaTypeFixup",
  17572. "this function needs a parser context");
  17573. return(-1);
  17574. }
  17575. if (! WXS_IS_TYPE_NOT_FIXED(type))
  17576. return(0);
  17577. if (type->type == XML_SCHEMA_TYPE_COMPLEX)
  17578. return(xmlSchemaFixupComplexType(PCTXT_CAST actxt, type));
  17579. else if (type->type == XML_SCHEMA_TYPE_SIMPLE)
  17580. return(xmlSchemaFixupSimpleTypeStageTwo(PCTXT_CAST actxt, type));
  17581. return(0);
  17582. }
  17583. /**
  17584. * xmlSchemaCheckFacet:
  17585. * @facet: the facet
  17586. * @typeDecl: the schema type definition
  17587. * @pctxt: the schema parser context or NULL
  17588. * @name: the optional name of the type
  17589. *
  17590. * Checks and computes the values of facets.
  17591. *
  17592. * Returns 0 if valid, a positive error code if not valid and
  17593. * -1 in case of an internal or API error.
  17594. */
  17595. int
  17596. xmlSchemaCheckFacet(xmlSchemaFacetPtr facet,
  17597. xmlSchemaTypePtr typeDecl,
  17598. xmlSchemaParserCtxtPtr pctxt,
  17599. const xmlChar * name ATTRIBUTE_UNUSED)
  17600. {
  17601. int ret = 0, ctxtGiven;
  17602. if ((facet == NULL) || (typeDecl == NULL))
  17603. return(-1);
  17604. /*
  17605. * TODO: will the parser context be given if used from
  17606. * the relaxNG module?
  17607. */
  17608. if (pctxt == NULL)
  17609. ctxtGiven = 0;
  17610. else
  17611. ctxtGiven = 1;
  17612. switch (facet->type) {
  17613. case XML_SCHEMA_FACET_MININCLUSIVE:
  17614. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  17615. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  17616. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  17617. case XML_SCHEMA_FACET_ENUMERATION: {
  17618. /*
  17619. * Okay we need to validate the value
  17620. * at that point.
  17621. */
  17622. xmlSchemaTypePtr base;
  17623. /* 4.3.5.5 Constraints on enumeration Schema Components
  17624. * Schema Component Constraint: enumeration valid restriction
  17625. * It is an `error` if any member of {value} is not in the
  17626. * `value space` of {base type definition}.
  17627. *
  17628. * minInclusive, maxInclusive, minExclusive, maxExclusive:
  17629. * The value `must` be in the
  17630. * `value space` of the `base type`.
  17631. */
  17632. /*
  17633. * This function is intended to deliver a compiled value
  17634. * on the facet. In this implementation of XML Schemata the
  17635. * type holding a facet, won't be a built-in type.
  17636. * Thus to ensure that other API
  17637. * calls (relaxng) do work, if the given type is a built-in
  17638. * type, we will assume that the given built-in type *is
  17639. * already* the base type.
  17640. */
  17641. if (typeDecl->type != XML_SCHEMA_TYPE_BASIC) {
  17642. base = typeDecl->baseType;
  17643. if (base == NULL) {
  17644. PERROR_INT("xmlSchemaCheckFacet",
  17645. "a type user derived type has no base type");
  17646. return (-1);
  17647. }
  17648. } else
  17649. base = typeDecl;
  17650. if (! ctxtGiven) {
  17651. /*
  17652. * A context is needed if called from RelaxNG.
  17653. */
  17654. pctxt = xmlSchemaNewParserCtxt("*");
  17655. if (pctxt == NULL)
  17656. return (-1);
  17657. }
  17658. /*
  17659. * NOTE: This call does not check the content nodes,
  17660. * since they are not available:
  17661. * facet->node is just the node holding the facet
  17662. * definition, *not* the attribute holding the *value*
  17663. * of the facet.
  17664. */
  17665. ret = xmlSchemaVCheckCVCSimpleType(
  17666. ACTXT_CAST pctxt, facet->node, base,
  17667. facet->value, &(facet->val), 1, 1, 0);
  17668. if (ret != 0) {
  17669. if (ret < 0) {
  17670. /* No error message for RelaxNG. */
  17671. if (ctxtGiven) {
  17672. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17673. XML_SCHEMAP_INTERNAL, facet->node, NULL,
  17674. "Internal error: xmlSchemaCheckFacet, "
  17675. "failed to validate the value '%s' of the "
  17676. "facet '%s' against the base type",
  17677. facet->value, xmlSchemaFacetTypeToString(facet->type));
  17678. }
  17679. goto internal_error;
  17680. }
  17681. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17682. /* No error message for RelaxNG. */
  17683. if (ctxtGiven) {
  17684. xmlChar *str = NULL;
  17685. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17686. ret, facet->node, WXS_BASIC_CAST facet,
  17687. "The value '%s' of the facet does not validate "
  17688. "against the base type '%s'",
  17689. facet->value,
  17690. xmlSchemaFormatQName(&str,
  17691. base->targetNamespace, base->name));
  17692. FREE_AND_NULL(str);
  17693. }
  17694. goto exit;
  17695. } else if (facet->val == NULL) {
  17696. if (ctxtGiven) {
  17697. PERROR_INT("xmlSchemaCheckFacet",
  17698. "value was not computed");
  17699. }
  17700. TODO
  17701. }
  17702. break;
  17703. }
  17704. case XML_SCHEMA_FACET_PATTERN:
  17705. facet->regexp = xmlRegexpCompile(facet->value);
  17706. if (facet->regexp == NULL) {
  17707. ret = XML_SCHEMAP_REGEXP_INVALID;
  17708. /* No error message for RelaxNG. */
  17709. if (ctxtGiven) {
  17710. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17711. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17712. "The value '%s' of the facet 'pattern' is not a "
  17713. "valid regular expression",
  17714. facet->value, NULL);
  17715. }
  17716. }
  17717. break;
  17718. case XML_SCHEMA_FACET_TOTALDIGITS:
  17719. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  17720. case XML_SCHEMA_FACET_LENGTH:
  17721. case XML_SCHEMA_FACET_MAXLENGTH:
  17722. case XML_SCHEMA_FACET_MINLENGTH:
  17723. if (facet->type == XML_SCHEMA_FACET_TOTALDIGITS) {
  17724. ret = xmlSchemaValidatePredefinedType(
  17725. xmlSchemaGetBuiltInType(XML_SCHEMAS_PINTEGER),
  17726. facet->value, &(facet->val));
  17727. } else {
  17728. ret = xmlSchemaValidatePredefinedType(
  17729. xmlSchemaGetBuiltInType(XML_SCHEMAS_NNINTEGER),
  17730. facet->value, &(facet->val));
  17731. }
  17732. if (ret != 0) {
  17733. if (ret < 0) {
  17734. /* No error message for RelaxNG. */
  17735. if (ctxtGiven) {
  17736. PERROR_INT("xmlSchemaCheckFacet",
  17737. "validating facet value");
  17738. }
  17739. goto internal_error;
  17740. }
  17741. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17742. /* No error message for RelaxNG. */
  17743. if (ctxtGiven) {
  17744. /* error code */
  17745. xmlSchemaCustomErr4(ACTXT_CAST pctxt,
  17746. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17747. "The value '%s' of the facet '%s' is not a valid '%s'",
  17748. facet->value,
  17749. xmlSchemaFacetTypeToString(facet->type),
  17750. (facet->type != XML_SCHEMA_FACET_TOTALDIGITS) ?
  17751. BAD_CAST "nonNegativeInteger" :
  17752. BAD_CAST "positiveInteger",
  17753. NULL);
  17754. }
  17755. }
  17756. break;
  17757. case XML_SCHEMA_FACET_WHITESPACE:{
  17758. if (xmlStrEqual(facet->value, BAD_CAST "preserve")) {
  17759. facet->whitespace = XML_SCHEMAS_FACET_PRESERVE;
  17760. } else if (xmlStrEqual(facet->value, BAD_CAST "replace")) {
  17761. facet->whitespace = XML_SCHEMAS_FACET_REPLACE;
  17762. } else if (xmlStrEqual(facet->value, BAD_CAST "collapse")) {
  17763. facet->whitespace = XML_SCHEMAS_FACET_COLLAPSE;
  17764. } else {
  17765. ret = XML_SCHEMAP_INVALID_FACET_VALUE;
  17766. /* No error message for RelaxNG. */
  17767. if (ctxtGiven) {
  17768. /* error was previously: XML_SCHEMAP_INVALID_WHITE_SPACE */
  17769. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  17770. ret, facet->node, WXS_BASIC_CAST typeDecl,
  17771. "The value '%s' of the facet 'whitespace' is not "
  17772. "valid", facet->value, NULL);
  17773. }
  17774. }
  17775. }
  17776. default:
  17777. break;
  17778. }
  17779. exit:
  17780. if ((! ctxtGiven) && (pctxt != NULL))
  17781. xmlSchemaFreeParserCtxt(pctxt);
  17782. return (ret);
  17783. internal_error:
  17784. if ((! ctxtGiven) && (pctxt != NULL))
  17785. xmlSchemaFreeParserCtxt(pctxt);
  17786. return (-1);
  17787. }
  17788. /**
  17789. * xmlSchemaCheckFacetValues:
  17790. * @typeDecl: the schema type definition
  17791. * @ctxt: the schema parser context
  17792. *
  17793. * Checks the default values types, especially for facets
  17794. */
  17795. static int
  17796. xmlSchemaCheckFacetValues(xmlSchemaTypePtr typeDecl,
  17797. xmlSchemaParserCtxtPtr pctxt)
  17798. {
  17799. int res, olderrs = pctxt->nberrors;
  17800. const xmlChar *name = typeDecl->name;
  17801. /*
  17802. * NOTE: It is intended to use the facets list, instead
  17803. * of facetSet.
  17804. */
  17805. if (typeDecl->facets != NULL) {
  17806. xmlSchemaFacetPtr facet = typeDecl->facets;
  17807. /*
  17808. * Temporarily assign the "schema" to the validation context
  17809. * of the parser context. This is needed for NOTATION validation.
  17810. */
  17811. if (pctxt->vctxt == NULL) {
  17812. if (xmlSchemaCreateVCtxtOnPCtxt(pctxt) == -1)
  17813. return(-1);
  17814. }
  17815. pctxt->vctxt->schema = pctxt->schema;
  17816. while (facet != NULL) {
  17817. res = xmlSchemaCheckFacet(facet, typeDecl, pctxt, name);
  17818. HFAILURE
  17819. facet = facet->next;
  17820. }
  17821. pctxt->vctxt->schema = NULL;
  17822. }
  17823. if (olderrs != pctxt->nberrors)
  17824. return(pctxt->err);
  17825. return(0);
  17826. exit_failure:
  17827. return(-1);
  17828. }
  17829. /**
  17830. * xmlSchemaGetCircModelGrDefRef:
  17831. * @ctxtMGroup: the searched model group
  17832. * @selfMGroup: the second searched model group
  17833. * @particle: the first particle
  17834. *
  17835. * This one is intended to be used by
  17836. * xmlSchemaCheckGroupDefCircular only.
  17837. *
  17838. * Returns the particle with the circular model group definition reference,
  17839. * otherwise NULL.
  17840. */
  17841. static xmlSchemaTreeItemPtr
  17842. xmlSchemaGetCircModelGrDefRef(xmlSchemaModelGroupDefPtr groupDef,
  17843. xmlSchemaTreeItemPtr particle)
  17844. {
  17845. xmlSchemaTreeItemPtr circ = NULL;
  17846. xmlSchemaTreeItemPtr term;
  17847. xmlSchemaModelGroupDefPtr gdef;
  17848. for (; particle != NULL; particle = particle->next) {
  17849. term = particle->children;
  17850. if (term == NULL)
  17851. continue;
  17852. switch (term->type) {
  17853. case XML_SCHEMA_TYPE_GROUP:
  17854. gdef = (xmlSchemaModelGroupDefPtr) term;
  17855. if (gdef == groupDef)
  17856. return (particle);
  17857. /*
  17858. * Mark this model group definition to avoid infinite
  17859. * recursion on circular references not yet examined.
  17860. */
  17861. if (gdef->flags & XML_SCHEMA_MODEL_GROUP_DEF_MARKED)
  17862. continue;
  17863. if (gdef->children != NULL) {
  17864. gdef->flags |= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17865. circ = xmlSchemaGetCircModelGrDefRef(groupDef,
  17866. gdef->children->children);
  17867. gdef->flags ^= XML_SCHEMA_MODEL_GROUP_DEF_MARKED;
  17868. if (circ != NULL)
  17869. return (circ);
  17870. }
  17871. break;
  17872. case XML_SCHEMA_TYPE_SEQUENCE:
  17873. case XML_SCHEMA_TYPE_CHOICE:
  17874. case XML_SCHEMA_TYPE_ALL:
  17875. circ = xmlSchemaGetCircModelGrDefRef(groupDef, term->children);
  17876. if (circ != NULL)
  17877. return (circ);
  17878. break;
  17879. default:
  17880. break;
  17881. }
  17882. }
  17883. return (NULL);
  17884. }
  17885. /**
  17886. * xmlSchemaCheckGroupDefCircular:
  17887. * @item: the model group definition
  17888. * @ctxt: the parser context
  17889. * @name: the name
  17890. *
  17891. * Checks for circular references to model group definitions.
  17892. */
  17893. static void
  17894. xmlSchemaCheckGroupDefCircular(xmlSchemaModelGroupDefPtr item,
  17895. xmlSchemaParserCtxtPtr ctxt)
  17896. {
  17897. /*
  17898. * Schema Component Constraint: Model Group Correct
  17899. * 2 Circular groups are disallowed. That is, within the {particles}
  17900. * of a group there must not be at any depth a particle whose {term}
  17901. * is the group itself.
  17902. */
  17903. if ((item == NULL) ||
  17904. (item->type != XML_SCHEMA_TYPE_GROUP) ||
  17905. (item->children == NULL))
  17906. return;
  17907. {
  17908. xmlSchemaTreeItemPtr circ;
  17909. circ = xmlSchemaGetCircModelGrDefRef(item, item->children->children);
  17910. if (circ != NULL) {
  17911. xmlChar *str = NULL;
  17912. /*
  17913. * TODO: The error report is not adequate: this constraint
  17914. * is defined for model groups but not definitions, but since
  17915. * there cannot be any circular model groups without a model group
  17916. * definition (if not using a construction API), we check those
  17917. * definitions only.
  17918. */
  17919. xmlSchemaPCustomErr(ctxt,
  17920. XML_SCHEMAP_MG_PROPS_CORRECT_2,
  17921. NULL, WXS_ITEM_NODE(circ),
  17922. "Circular reference to the model group definition '%s' "
  17923. "defined", xmlSchemaFormatQName(&str,
  17924. item->targetNamespace, item->name));
  17925. FREE_AND_NULL(str)
  17926. /*
  17927. * NOTE: We will cut the reference to avoid further
  17928. * confusion of the processor. This is a fatal error.
  17929. */
  17930. circ->children = NULL;
  17931. }
  17932. }
  17933. }
  17934. /**
  17935. * xmlSchemaModelGroupToModelGroupDefFixup:
  17936. * @ctxt: the parser context
  17937. * @mg: the model group
  17938. *
  17939. * Assigns the model group of model group definitions to the "term"
  17940. * of the referencing particle.
  17941. * In xmlSchemaResolveModelGroupParticleReferences the model group
  17942. * definitions were assigned to the "term", since needed for the
  17943. * circularity check.
  17944. *
  17945. * Schema Component Constraint:
  17946. * All Group Limited (cos-all-limited) (1.2)
  17947. */
  17948. static void
  17949. xmlSchemaModelGroupToModelGroupDefFixup(
  17950. xmlSchemaParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  17951. xmlSchemaModelGroupPtr mg)
  17952. {
  17953. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  17954. while (particle != NULL) {
  17955. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  17956. ((WXS_PARTICLE_TERM(particle))->type !=
  17957. XML_SCHEMA_TYPE_GROUP))
  17958. {
  17959. particle = WXS_PTC_CAST particle->next;
  17960. continue;
  17961. }
  17962. if (WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle)) == NULL) {
  17963. /*
  17964. * TODO: Remove the particle.
  17965. */
  17966. WXS_PARTICLE_TERM(particle) = NULL;
  17967. particle = WXS_PTC_CAST particle->next;
  17968. continue;
  17969. }
  17970. /*
  17971. * Assign the model group to the {term} of the particle.
  17972. */
  17973. WXS_PARTICLE_TERM(particle) =
  17974. WXS_TREE_CAST WXS_MODELGROUPDEF_MODEL(WXS_PARTICLE_TERM(particle));
  17975. particle = WXS_PTC_CAST particle->next;
  17976. }
  17977. }
  17978. /**
  17979. * xmlSchemaCheckAttrGroupCircularRecur:
  17980. * @ctxtGr: the searched attribute group
  17981. * @attr: the current attribute list to be processed
  17982. *
  17983. * This one is intended to be used by
  17984. * xmlSchemaCheckAttrGroupCircular only.
  17985. *
  17986. * Returns the circular attribute group reference, otherwise NULL.
  17987. */
  17988. static xmlSchemaQNameRefPtr
  17989. xmlSchemaCheckAttrGroupCircularRecur(xmlSchemaAttributeGroupPtr ctxtGr,
  17990. xmlSchemaItemListPtr list)
  17991. {
  17992. xmlSchemaAttributeGroupPtr gr;
  17993. xmlSchemaQNameRefPtr ref, circ;
  17994. int i;
  17995. /*
  17996. * We will search for an attribute group reference which
  17997. * references the context attribute group.
  17998. */
  17999. for (i = 0; i < list->nbItems; i++) {
  18000. ref = list->items[i];
  18001. if ((ref->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18002. (ref->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP) &&
  18003. (ref->item != NULL))
  18004. {
  18005. gr = WXS_ATTR_GROUP_CAST ref->item;
  18006. if (gr == ctxtGr)
  18007. return(ref);
  18008. if (gr->flags & XML_SCHEMAS_ATTRGROUP_MARKED)
  18009. continue;
  18010. /*
  18011. * Mark as visited to avoid infinite recursion on
  18012. * circular references not yet examined.
  18013. */
  18014. if ((gr->attrUses) &&
  18015. (gr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS))
  18016. {
  18017. gr->flags |= XML_SCHEMAS_ATTRGROUP_MARKED;
  18018. circ = xmlSchemaCheckAttrGroupCircularRecur(ctxtGr,
  18019. (xmlSchemaItemListPtr) gr->attrUses);
  18020. gr->flags ^= XML_SCHEMAS_ATTRGROUP_MARKED;
  18021. if (circ != NULL)
  18022. return (circ);
  18023. }
  18024. }
  18025. }
  18026. return (NULL);
  18027. }
  18028. /**
  18029. * xmlSchemaCheckAttrGroupCircular:
  18030. * attrGr: the attribute group definition
  18031. * @ctxt: the parser context
  18032. * @name: the name
  18033. *
  18034. * Checks for circular references of attribute groups.
  18035. */
  18036. static int
  18037. xmlSchemaCheckAttrGroupCircular(xmlSchemaAttributeGroupPtr attrGr,
  18038. xmlSchemaParserCtxtPtr ctxt)
  18039. {
  18040. /*
  18041. * Schema Representation Constraint:
  18042. * Attribute Group Definition Representation OK
  18043. * 3 Circular group reference is disallowed outside <redefine>.
  18044. * That is, unless this element information item's parent is
  18045. * <redefine>, then among the [children], if any, there must
  18046. * not be an <attributeGroup> with ref [attribute] which resolves
  18047. * to the component corresponding to this <attributeGroup>. Indirect
  18048. * circularity is also ruled out. That is, when QName resolution
  18049. * (Schema Document) ($3.15.3) is applied to a `QName` arising from
  18050. * any <attributeGroup>s with a ref [attribute] among the [children],
  18051. * it must not be the case that a `QName` is encountered at any depth
  18052. * which resolves to the component corresponding to this <attributeGroup>.
  18053. */
  18054. if (attrGr->attrUses == NULL)
  18055. return(0);
  18056. else if ((attrGr->flags & XML_SCHEMAS_ATTRGROUP_HAS_REFS) == 0)
  18057. return(0);
  18058. else {
  18059. xmlSchemaQNameRefPtr circ;
  18060. circ = xmlSchemaCheckAttrGroupCircularRecur(attrGr,
  18061. (xmlSchemaItemListPtr) attrGr->attrUses);
  18062. if (circ != NULL) {
  18063. xmlChar *str = NULL;
  18064. /*
  18065. * TODO: Report the referenced attr group as QName.
  18066. */
  18067. xmlSchemaPCustomErr(ctxt,
  18068. XML_SCHEMAP_SRC_ATTRIBUTE_GROUP_3,
  18069. NULL, WXS_ITEM_NODE(WXS_BASIC_CAST circ),
  18070. "Circular reference to the attribute group '%s' "
  18071. "defined", xmlSchemaGetComponentQName(&str, attrGr));
  18072. FREE_AND_NULL(str);
  18073. /*
  18074. * NOTE: We will cut the reference to avoid further
  18075. * confusion of the processor.
  18076. * BADSPEC TODO: The spec should define how to process in this case.
  18077. */
  18078. circ->item = NULL;
  18079. return(ctxt->err);
  18080. }
  18081. }
  18082. return(0);
  18083. }
  18084. static int
  18085. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18086. xmlSchemaAttributeGroupPtr attrGr);
  18087. /**
  18088. * xmlSchemaExpandAttributeGroupRefs:
  18089. * @pctxt: the parser context
  18090. * @node: the node of the component holding the attribute uses
  18091. * @completeWild: the intersected wildcard to be returned
  18092. * @list: the attribute uses
  18093. *
  18094. * Substitutes contained attribute group references
  18095. * for their attribute uses. Wildcards are intersected.
  18096. * Attribute use prohibitions are removed from the list
  18097. * and returned via the @prohibs list.
  18098. * Pointlessness of attr. prohibs, if a matching attr. decl
  18099. * is existent a well, are checked.
  18100. */
  18101. static int
  18102. xmlSchemaExpandAttributeGroupRefs(xmlSchemaParserCtxtPtr pctxt,
  18103. xmlSchemaBasicItemPtr item,
  18104. xmlSchemaWildcardPtr *completeWild,
  18105. xmlSchemaItemListPtr list,
  18106. xmlSchemaItemListPtr prohibs)
  18107. {
  18108. xmlSchemaAttributeGroupPtr gr;
  18109. xmlSchemaAttributeUsePtr use;
  18110. xmlSchemaItemListPtr sublist;
  18111. int i, j;
  18112. int created = (*completeWild == NULL) ? 0 : 1;
  18113. if (prohibs)
  18114. prohibs->nbItems = 0;
  18115. for (i = 0; i < list->nbItems; i++) {
  18116. use = list->items[i];
  18117. if (use->type == XML_SCHEMA_EXTRA_ATTR_USE_PROHIB) {
  18118. if (prohibs == NULL) {
  18119. PERROR_INT("xmlSchemaExpandAttributeGroupRefs",
  18120. "unexpected attr prohibition found");
  18121. return(-1);
  18122. }
  18123. /*
  18124. * Remove from attribute uses.
  18125. */
  18126. if (xmlSchemaItemListRemove(list, i) == -1)
  18127. return(-1);
  18128. i--;
  18129. /*
  18130. * Note that duplicate prohibitions were already
  18131. * handled at parsing time.
  18132. */
  18133. /*
  18134. * Add to list of prohibitions.
  18135. */
  18136. xmlSchemaItemListAddSize(prohibs, 2, use);
  18137. continue;
  18138. }
  18139. if ((use->type == XML_SCHEMA_EXTRA_QNAMEREF) &&
  18140. ((WXS_QNAME_CAST use)->itemType == XML_SCHEMA_TYPE_ATTRIBUTEGROUP))
  18141. {
  18142. if ((WXS_QNAME_CAST use)->item == NULL)
  18143. return(-1);
  18144. gr = WXS_ATTR_GROUP_CAST (WXS_QNAME_CAST use)->item;
  18145. /*
  18146. * Expand the referenced attr. group.
  18147. * TODO: remove this, this is done in a previous step, so
  18148. * already done here.
  18149. */
  18150. if ((gr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED) == 0) {
  18151. if (xmlSchemaAttributeGroupExpandRefs(pctxt, gr) == -1)
  18152. return(-1);
  18153. }
  18154. /*
  18155. * Build the 'complete' wildcard; i.e. intersect multiple
  18156. * wildcards.
  18157. */
  18158. if (gr->attributeWildcard != NULL) {
  18159. if (*completeWild == NULL) {
  18160. *completeWild = gr->attributeWildcard;
  18161. } else {
  18162. if (! created) {
  18163. xmlSchemaWildcardPtr tmpWild;
  18164. /*
  18165. * Copy the first encountered wildcard as context,
  18166. * except for the annotation.
  18167. *
  18168. * Although the complete wildcard might not correspond
  18169. * to any node in the schema, we will anchor it on
  18170. * the node of the owner component.
  18171. */
  18172. tmpWild = xmlSchemaAddWildcard(pctxt, pctxt->schema,
  18173. XML_SCHEMA_TYPE_ANY_ATTRIBUTE,
  18174. WXS_ITEM_NODE(item));
  18175. if (tmpWild == NULL)
  18176. return(-1);
  18177. if (xmlSchemaCloneWildcardNsConstraints(pctxt,
  18178. tmpWild, *completeWild) == -1)
  18179. return (-1);
  18180. tmpWild->processContents = (*completeWild)->processContents;
  18181. *completeWild = tmpWild;
  18182. created = 1;
  18183. }
  18184. if (xmlSchemaIntersectWildcards(pctxt, *completeWild,
  18185. gr->attributeWildcard) == -1)
  18186. return(-1);
  18187. }
  18188. }
  18189. /*
  18190. * Just remove the reference if the referenced group does not
  18191. * contain any attribute uses.
  18192. */
  18193. sublist = ((xmlSchemaItemListPtr) gr->attrUses);
  18194. if ((sublist == NULL) || sublist->nbItems == 0) {
  18195. if (xmlSchemaItemListRemove(list, i) == -1)
  18196. return(-1);
  18197. i--;
  18198. continue;
  18199. }
  18200. /*
  18201. * Add the attribute uses.
  18202. */
  18203. list->items[i] = sublist->items[0];
  18204. if (sublist->nbItems != 1) {
  18205. for (j = 1; j < sublist->nbItems; j++) {
  18206. i++;
  18207. if (xmlSchemaItemListInsert(list,
  18208. sublist->items[j], i) == -1)
  18209. return(-1);
  18210. }
  18211. }
  18212. }
  18213. }
  18214. /*
  18215. * Handle pointless prohibitions of declared attributes.
  18216. */
  18217. if (prohibs && (prohibs->nbItems != 0) && (list->nbItems != 0)) {
  18218. xmlSchemaAttributeUseProhibPtr prohib;
  18219. for (i = prohibs->nbItems -1; i >= 0; i--) {
  18220. prohib = prohibs->items[i];
  18221. for (j = 0; j < list->nbItems; j++) {
  18222. use = list->items[j];
  18223. if ((prohib->name == WXS_ATTRUSE_DECL_NAME(use)) &&
  18224. (prohib->targetNamespace == WXS_ATTRUSE_DECL_TNS(use)))
  18225. {
  18226. xmlChar *str = NULL;
  18227. xmlSchemaCustomWarning(ACTXT_CAST pctxt,
  18228. XML_SCHEMAP_WARN_ATTR_POINTLESS_PROH,
  18229. prohib->node, NULL,
  18230. "Skipping pointless attribute use prohibition "
  18231. "'%s', since a corresponding attribute use "
  18232. "exists already in the type definition",
  18233. xmlSchemaFormatQName(&str,
  18234. prohib->targetNamespace, prohib->name),
  18235. NULL, NULL);
  18236. FREE_AND_NULL(str);
  18237. /*
  18238. * Remove the prohibition.
  18239. */
  18240. if (xmlSchemaItemListRemove(prohibs, i) == -1)
  18241. return(-1);
  18242. break;
  18243. }
  18244. }
  18245. }
  18246. }
  18247. return(0);
  18248. }
  18249. /**
  18250. * xmlSchemaAttributeGroupExpandRefs:
  18251. * @pctxt: the parser context
  18252. * @attrGr: the attribute group definition
  18253. *
  18254. * Computation of:
  18255. * {attribute uses} property
  18256. * {attribute wildcard} property
  18257. *
  18258. * Substitutes contained attribute group references
  18259. * for their attribute uses. Wildcards are intersected.
  18260. */
  18261. static int
  18262. xmlSchemaAttributeGroupExpandRefs(xmlSchemaParserCtxtPtr pctxt,
  18263. xmlSchemaAttributeGroupPtr attrGr)
  18264. {
  18265. if ((attrGr->attrUses == NULL) ||
  18266. (attrGr->flags & XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED))
  18267. return(0);
  18268. attrGr->flags |= XML_SCHEMAS_ATTRGROUP_WILDCARD_BUILDED;
  18269. if (xmlSchemaExpandAttributeGroupRefs(pctxt, WXS_BASIC_CAST attrGr,
  18270. &(attrGr->attributeWildcard), attrGr->attrUses, NULL) == -1)
  18271. return(-1);
  18272. return(0);
  18273. }
  18274. /**
  18275. * xmlSchemaAttributeGroupExpandRefs:
  18276. * @pctxt: the parser context
  18277. * @attrGr: the attribute group definition
  18278. *
  18279. * Substitutes contained attribute group references
  18280. * for their attribute uses. Wildcards are intersected.
  18281. *
  18282. * Schema Component Constraint:
  18283. * Attribute Group Definition Properties Correct (ag-props-correct)
  18284. */
  18285. static int
  18286. xmlSchemaCheckAGPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18287. xmlSchemaAttributeGroupPtr attrGr)
  18288. {
  18289. /*
  18290. * SPEC ag-props-correct
  18291. * (1) "The values of the properties of an attribute group definition
  18292. * must be as described in the property tableau in The Attribute
  18293. * Group Definition Schema Component ($3.6.1), modulo the impact of
  18294. * Missing Sub-components ($5.3);"
  18295. */
  18296. if ((attrGr->attrUses != NULL) &&
  18297. (WXS_LIST_CAST attrGr->attrUses)->nbItems > 1)
  18298. {
  18299. xmlSchemaItemListPtr uses = WXS_LIST_CAST attrGr->attrUses;
  18300. xmlSchemaAttributeUsePtr use, tmp;
  18301. int i, j, hasId = 0;
  18302. for (i = uses->nbItems -1; i >= 0; i--) {
  18303. use = uses->items[i];
  18304. /*
  18305. * SPEC ag-props-correct
  18306. * (2) "Two distinct members of the {attribute uses} must not have
  18307. * {attribute declaration}s both of whose {name}s match and whose
  18308. * {target namespace}s are identical."
  18309. */
  18310. if (i > 0) {
  18311. for (j = i -1; j >= 0; j--) {
  18312. tmp = uses->items[j];
  18313. if ((WXS_ATTRUSE_DECL_NAME(use) ==
  18314. WXS_ATTRUSE_DECL_NAME(tmp)) &&
  18315. (WXS_ATTRUSE_DECL_TNS(use) ==
  18316. WXS_ATTRUSE_DECL_TNS(tmp)))
  18317. {
  18318. xmlChar *str = NULL;
  18319. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18320. XML_SCHEMAP_AG_PROPS_CORRECT,
  18321. attrGr->node, WXS_BASIC_CAST attrGr,
  18322. "Duplicate %s",
  18323. xmlSchemaGetComponentDesignation(&str, use),
  18324. NULL);
  18325. FREE_AND_NULL(str);
  18326. /*
  18327. * Remove the duplicate.
  18328. */
  18329. if (xmlSchemaItemListRemove(uses, i) == -1)
  18330. return(-1);
  18331. goto next_use;
  18332. }
  18333. }
  18334. }
  18335. /*
  18336. * SPEC ag-props-correct
  18337. * (3) "Two distinct members of the {attribute uses} must not have
  18338. * {attribute declaration}s both of whose {type definition}s are or
  18339. * are derived from ID."
  18340. * TODO: Does 'derived' include member-types of unions?
  18341. */
  18342. if (WXS_ATTRUSE_TYPEDEF(use) != NULL) {
  18343. if (xmlSchemaIsDerivedFromBuiltInType(
  18344. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  18345. {
  18346. if (hasId) {
  18347. xmlChar *str = NULL;
  18348. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18349. XML_SCHEMAP_AG_PROPS_CORRECT,
  18350. attrGr->node, WXS_BASIC_CAST attrGr,
  18351. "There must not exist more than one attribute "
  18352. "declaration of type 'xs:ID' "
  18353. "(or derived from 'xs:ID'). The %s violates this "
  18354. "constraint",
  18355. xmlSchemaGetComponentDesignation(&str, use),
  18356. NULL);
  18357. FREE_AND_NULL(str);
  18358. if (xmlSchemaItemListRemove(uses, i) == -1)
  18359. return(-1);
  18360. }
  18361. hasId = 1;
  18362. }
  18363. }
  18364. next_use: {}
  18365. }
  18366. }
  18367. return(0);
  18368. }
  18369. /**
  18370. * xmlSchemaResolveAttrGroupReferences:
  18371. * @attrgrpDecl: the schema attribute definition
  18372. * @ctxt: the schema parser context
  18373. * @name: the attribute name
  18374. *
  18375. * Resolves references to attribute group definitions.
  18376. */
  18377. static int
  18378. xmlSchemaResolveAttrGroupReferences(xmlSchemaQNameRefPtr ref,
  18379. xmlSchemaParserCtxtPtr ctxt)
  18380. {
  18381. xmlSchemaAttributeGroupPtr group;
  18382. if (ref->item != NULL)
  18383. return(0);
  18384. group = xmlSchemaGetAttributeGroup(ctxt->schema,
  18385. ref->name,
  18386. ref->targetNamespace);
  18387. if (group == NULL) {
  18388. xmlSchemaPResCompAttrErr(ctxt,
  18389. XML_SCHEMAP_SRC_RESOLVE,
  18390. NULL, ref->node,
  18391. "ref", ref->name, ref->targetNamespace,
  18392. ref->itemType, NULL);
  18393. return(ctxt->err);
  18394. }
  18395. ref->item = WXS_BASIC_CAST group;
  18396. return(0);
  18397. }
  18398. /**
  18399. * xmlSchemaCheckAttrPropsCorrect:
  18400. * @item: an schema attribute declaration/use
  18401. * @ctxt: a schema parser context
  18402. * @name: the name of the attribute
  18403. *
  18404. *
  18405. * Schema Component Constraint:
  18406. * Attribute Declaration Properties Correct (a-props-correct)
  18407. *
  18408. * Validates the value constraints of an attribute declaration/use.
  18409. * NOTE that this needs the simple type definitions to be already
  18410. * built and checked.
  18411. */
  18412. static int
  18413. xmlSchemaCheckAttrPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18414. xmlSchemaAttributePtr attr)
  18415. {
  18416. /*
  18417. * SPEC a-props-correct (1)
  18418. * "The values of the properties of an attribute declaration must
  18419. * be as described in the property tableau in The Attribute
  18420. * Declaration Schema Component ($3.2.1), modulo the impact of
  18421. * Missing Sub-components ($5.3)."
  18422. */
  18423. if (WXS_ATTR_TYPEDEF(attr) == NULL)
  18424. return(0);
  18425. if (attr->defValue != NULL) {
  18426. int ret;
  18427. /*
  18428. * SPEC a-props-correct (3)
  18429. * "If the {type definition} is or is derived from ID then there
  18430. * must not be a {value constraint}."
  18431. */
  18432. if (xmlSchemaIsDerivedFromBuiltInType(
  18433. WXS_ATTR_TYPEDEF(attr), XML_SCHEMAS_ID))
  18434. {
  18435. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18436. XML_SCHEMAP_A_PROPS_CORRECT_3,
  18437. NULL, WXS_BASIC_CAST attr,
  18438. "Value constraints are not allowed if the type definition "
  18439. "is or is derived from xs:ID",
  18440. NULL, NULL);
  18441. return(pctxt->err);
  18442. }
  18443. /*
  18444. * SPEC a-props-correct (2)
  18445. * "if there is a {value constraint}, the canonical lexical
  18446. * representation of its value must be `valid` with respect
  18447. * to the {type definition} as defined in String Valid ($3.14.4)."
  18448. * TODO: Don't care about the *canonical* stuff here, this requirement
  18449. * will be removed in WXS 1.1 anyway.
  18450. */
  18451. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST pctxt,
  18452. attr->node, WXS_ATTR_TYPEDEF(attr),
  18453. attr->defValue, &(attr->defVal),
  18454. 1, 1, 0);
  18455. if (ret != 0) {
  18456. if (ret < 0) {
  18457. PERROR_INT("xmlSchemaCheckAttrPropsCorrect",
  18458. "calling xmlSchemaVCheckCVCSimpleType()");
  18459. return(-1);
  18460. }
  18461. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18462. XML_SCHEMAP_A_PROPS_CORRECT_2,
  18463. NULL, WXS_BASIC_CAST attr,
  18464. "The value of the value constraint is not valid",
  18465. NULL, NULL);
  18466. return(pctxt->err);
  18467. }
  18468. }
  18469. return(0);
  18470. }
  18471. static xmlSchemaElementPtr
  18472. xmlSchemaCheckSubstGroupCircular(xmlSchemaElementPtr elemDecl,
  18473. xmlSchemaElementPtr ancestor)
  18474. {
  18475. xmlSchemaElementPtr ret;
  18476. if (WXS_SUBST_HEAD(ancestor) == NULL)
  18477. return (NULL);
  18478. if (WXS_SUBST_HEAD(ancestor) == elemDecl)
  18479. return (ancestor);
  18480. if (WXS_SUBST_HEAD(ancestor)->flags & XML_SCHEMAS_ELEM_CIRCULAR)
  18481. return (NULL);
  18482. WXS_SUBST_HEAD(ancestor)->flags |= XML_SCHEMAS_ELEM_CIRCULAR;
  18483. ret = xmlSchemaCheckSubstGroupCircular(elemDecl,
  18484. WXS_SUBST_HEAD(ancestor));
  18485. WXS_SUBST_HEAD(ancestor)->flags ^= XML_SCHEMAS_ELEM_CIRCULAR;
  18486. return (ret);
  18487. }
  18488. /**
  18489. * xmlSchemaCheckElemPropsCorrect:
  18490. * @ctxt: a schema parser context
  18491. * @decl: the element declaration
  18492. * @name: the name of the attribute
  18493. *
  18494. * Schema Component Constraint:
  18495. * Element Declaration Properties Correct (e-props-correct)
  18496. *
  18497. * STATUS:
  18498. * missing: (6)
  18499. */
  18500. static int
  18501. xmlSchemaCheckElemPropsCorrect(xmlSchemaParserCtxtPtr pctxt,
  18502. xmlSchemaElementPtr elemDecl)
  18503. {
  18504. int ret = 0;
  18505. xmlSchemaTypePtr typeDef = WXS_ELEM_TYPEDEF(elemDecl);
  18506. /*
  18507. * SPEC (1) "The values of the properties of an element declaration
  18508. * must be as described in the property tableau in The Element
  18509. * Declaration Schema Component ($3.3.1), modulo the impact of Missing
  18510. * Sub-components ($5.3)."
  18511. */
  18512. if (WXS_SUBST_HEAD(elemDecl) != NULL) {
  18513. xmlSchemaElementPtr head = WXS_SUBST_HEAD(elemDecl), circ;
  18514. xmlSchemaCheckElementDeclComponent(head, pctxt);
  18515. /*
  18516. * SPEC (3) "If there is a non-`absent` {substitution group
  18517. * affiliation}, then {scope} must be global."
  18518. */
  18519. if ((elemDecl->flags & XML_SCHEMAS_ELEM_GLOBAL) == 0) {
  18520. xmlSchemaPCustomErr(pctxt,
  18521. XML_SCHEMAP_E_PROPS_CORRECT_3,
  18522. WXS_BASIC_CAST elemDecl, NULL,
  18523. "Only global element declarations can have a "
  18524. "substitution group affiliation", NULL);
  18525. ret = XML_SCHEMAP_E_PROPS_CORRECT_3;
  18526. }
  18527. /*
  18528. * TODO: SPEC (6) "Circular substitution groups are disallowed.
  18529. * That is, it must not be possible to return to an element declaration
  18530. * by repeatedly following the {substitution group affiliation}
  18531. * property."
  18532. */
  18533. if (head == elemDecl)
  18534. circ = head;
  18535. else if (WXS_SUBST_HEAD(head) != NULL)
  18536. circ = xmlSchemaCheckSubstGroupCircular(head, head);
  18537. else
  18538. circ = NULL;
  18539. if (circ != NULL) {
  18540. xmlChar *strA = NULL, *strB = NULL;
  18541. xmlSchemaPCustomErrExt(pctxt,
  18542. XML_SCHEMAP_E_PROPS_CORRECT_6,
  18543. WXS_BASIC_CAST circ, NULL,
  18544. "The element declaration '%s' defines a circular "
  18545. "substitution group to element declaration '%s'",
  18546. xmlSchemaGetComponentQName(&strA, circ),
  18547. xmlSchemaGetComponentQName(&strB, head),
  18548. NULL);
  18549. FREE_AND_NULL(strA)
  18550. FREE_AND_NULL(strB)
  18551. ret = XML_SCHEMAP_E_PROPS_CORRECT_6;
  18552. }
  18553. /*
  18554. * SPEC (4) "If there is a {substitution group affiliation},
  18555. * the {type definition}
  18556. * of the element declaration must be validly derived from the {type
  18557. * definition} of the {substitution group affiliation}, given the value
  18558. * of the {substitution group exclusions} of the {substitution group
  18559. * affiliation}, as defined in Type Derivation OK (Complex) ($3.4.6)
  18560. * (if the {type definition} is complex) or as defined in
  18561. * Type Derivation OK (Simple) ($3.14.6) (if the {type definition} is
  18562. * simple)."
  18563. *
  18564. * NOTE: {substitution group exclusions} means the values of the
  18565. * attribute "final".
  18566. */
  18567. if (typeDef != WXS_ELEM_TYPEDEF(WXS_SUBST_HEAD(elemDecl))) {
  18568. int set = 0;
  18569. if (head->flags & XML_SCHEMAS_ELEM_FINAL_EXTENSION)
  18570. set |= SUBSET_EXTENSION;
  18571. if (head->flags & XML_SCHEMAS_ELEM_FINAL_RESTRICTION)
  18572. set |= SUBSET_RESTRICTION;
  18573. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST pctxt, typeDef,
  18574. WXS_ELEM_TYPEDEF(head), set) != 0) {
  18575. xmlChar *strA = NULL, *strB = NULL, *strC = NULL;
  18576. ret = XML_SCHEMAP_E_PROPS_CORRECT_4;
  18577. xmlSchemaPCustomErrExt(pctxt,
  18578. XML_SCHEMAP_E_PROPS_CORRECT_4,
  18579. WXS_BASIC_CAST elemDecl, NULL,
  18580. "The type definition '%s' was "
  18581. "either rejected by the substitution group "
  18582. "affiliation '%s', or not validly derived from its type "
  18583. "definition '%s'",
  18584. xmlSchemaGetComponentQName(&strA, typeDef),
  18585. xmlSchemaGetComponentQName(&strB, head),
  18586. xmlSchemaGetComponentQName(&strC, WXS_ELEM_TYPEDEF(head)));
  18587. FREE_AND_NULL(strA)
  18588. FREE_AND_NULL(strB)
  18589. FREE_AND_NULL(strC)
  18590. }
  18591. }
  18592. }
  18593. /*
  18594. * SPEC (5) "If the {type definition} or {type definition}'s
  18595. * {content type}
  18596. * is or is derived from ID then there must not be a {value constraint}.
  18597. * Note: The use of ID as a type definition for elements goes beyond
  18598. * XML 1.0, and should be avoided if backwards compatibility is desired"
  18599. */
  18600. if ((elemDecl->value != NULL) &&
  18601. ((WXS_IS_SIMPLE(typeDef) &&
  18602. xmlSchemaIsDerivedFromBuiltInType(typeDef, XML_SCHEMAS_ID)) ||
  18603. (WXS_IS_COMPLEX(typeDef) &&
  18604. WXS_HAS_SIMPLE_CONTENT(typeDef) &&
  18605. xmlSchemaIsDerivedFromBuiltInType(typeDef->contentTypeDef,
  18606. XML_SCHEMAS_ID)))) {
  18607. ret = XML_SCHEMAP_E_PROPS_CORRECT_5;
  18608. xmlSchemaPCustomErr(pctxt,
  18609. XML_SCHEMAP_E_PROPS_CORRECT_5,
  18610. WXS_BASIC_CAST elemDecl, NULL,
  18611. "The type definition (or type definition's content type) is or "
  18612. "is derived from ID; value constraints are not allowed in "
  18613. "conjunction with such a type definition", NULL);
  18614. } else if (elemDecl->value != NULL) {
  18615. int vcret;
  18616. xmlNodePtr node = NULL;
  18617. /*
  18618. * SPEC (2) "If there is a {value constraint}, the canonical lexical
  18619. * representation of its value must be `valid` with respect to the
  18620. * {type definition} as defined in Element Default Valid (Immediate)
  18621. * ($3.3.6)."
  18622. */
  18623. if (typeDef == NULL) {
  18624. xmlSchemaPErr(pctxt, elemDecl->node,
  18625. XML_SCHEMAP_INTERNAL,
  18626. "Internal error: xmlSchemaCheckElemPropsCorrect, "
  18627. "type is missing... skipping validation of "
  18628. "the value constraint", NULL, NULL);
  18629. return (-1);
  18630. }
  18631. if (elemDecl->node != NULL) {
  18632. if (elemDecl->flags & XML_SCHEMAS_ELEM_FIXED)
  18633. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18634. BAD_CAST "fixed");
  18635. else
  18636. node = (xmlNodePtr) xmlHasProp(elemDecl->node,
  18637. BAD_CAST "default");
  18638. }
  18639. vcret = xmlSchemaParseCheckCOSValidDefault(pctxt, node,
  18640. typeDef, elemDecl->value, &(elemDecl->defVal));
  18641. if (vcret != 0) {
  18642. if (vcret < 0) {
  18643. PERROR_INT("xmlSchemaElemCheckValConstr",
  18644. "failed to validate the value constraint of an "
  18645. "element declaration");
  18646. return (-1);
  18647. }
  18648. return (vcret);
  18649. }
  18650. }
  18651. return (ret);
  18652. }
  18653. /**
  18654. * xmlSchemaCheckElemSubstGroup:
  18655. * @ctxt: a schema parser context
  18656. * @decl: the element declaration
  18657. * @name: the name of the attribute
  18658. *
  18659. * Schema Component Constraint:
  18660. * Substitution Group (cos-equiv-class)
  18661. *
  18662. * In Libxml2 the subst. groups will be precomputed, in terms of that
  18663. * a list will be built for each subst. group head, holding all direct
  18664. * referents to this head.
  18665. * NOTE that this function needs:
  18666. * 1. circular subst. groups to be checked beforehand
  18667. * 2. the declaration's type to be derived from the head's type
  18668. *
  18669. * STATUS:
  18670. *
  18671. */
  18672. static void
  18673. xmlSchemaCheckElemSubstGroup(xmlSchemaParserCtxtPtr ctxt,
  18674. xmlSchemaElementPtr elemDecl)
  18675. {
  18676. if ((WXS_SUBST_HEAD(elemDecl) == NULL) ||
  18677. /* SPEC (1) "Its {abstract} is false." */
  18678. (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT))
  18679. return;
  18680. {
  18681. xmlSchemaElementPtr head;
  18682. xmlSchemaTypePtr headType, type;
  18683. int set, methSet;
  18684. /*
  18685. * SPEC (2) "It is validly substitutable for HEAD subject to HEAD's
  18686. * {disallowed substitutions} as the blocking constraint, as defined in
  18687. * Substitution Group OK (Transitive) ($3.3.6)."
  18688. */
  18689. for (head = WXS_SUBST_HEAD(elemDecl); head != NULL;
  18690. head = WXS_SUBST_HEAD(head)) {
  18691. set = 0;
  18692. methSet = 0;
  18693. /*
  18694. * The blocking constraints.
  18695. */
  18696. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_SUBSTITUTION)
  18697. continue;
  18698. headType = head->subtypes;
  18699. type = elemDecl->subtypes;
  18700. if (headType == type)
  18701. goto add_member;
  18702. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION)
  18703. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18704. if (head->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION)
  18705. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18706. /*
  18707. * SPEC: Substitution Group OK (Transitive) (2.3)
  18708. * "The set of all {derivation method}s involved in the
  18709. * derivation of D's {type definition} from C's {type definition}
  18710. * does not intersect with the union of the blocking constraint,
  18711. * C's {prohibited substitutions} (if C is complex, otherwise the
  18712. * empty set) and the {prohibited substitutions} (respectively the
  18713. * empty set) of any intermediate {type definition}s in the
  18714. * derivation of D's {type definition} from C's {type definition}."
  18715. */
  18716. /*
  18717. * OPTIMIZE TODO: Optimize this a bit, since, if traversing the
  18718. * subst.head axis, the methSet does not need to be computed for
  18719. * the full depth over and over.
  18720. */
  18721. /*
  18722. * The set of all {derivation method}s involved in the derivation
  18723. */
  18724. while ((type != NULL) && (type != headType)) {
  18725. if ((WXS_IS_EXTENSION(type)) &&
  18726. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18727. methSet |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18728. if (WXS_IS_RESTRICTION(type) &&
  18729. ((methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18730. methSet |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18731. type = type->baseType;
  18732. }
  18733. /*
  18734. * The {prohibited substitutions} of all intermediate types +
  18735. * the head's type.
  18736. */
  18737. type = elemDecl->subtypes->baseType;
  18738. while (type != NULL) {
  18739. if (WXS_IS_COMPLEX(type)) {
  18740. if ((type->flags &
  18741. XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18742. ((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) == 0))
  18743. set |= XML_SCHEMAS_TYPE_BLOCK_EXTENSION;
  18744. if ((type->flags &
  18745. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18746. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) == 0))
  18747. set |= XML_SCHEMAS_TYPE_BLOCK_RESTRICTION;
  18748. } else
  18749. break;
  18750. if (type == headType)
  18751. break;
  18752. type = type->baseType;
  18753. }
  18754. if ((set != 0) &&
  18755. (((set & XML_SCHEMAS_TYPE_BLOCK_EXTENSION) &&
  18756. (methSet & XML_SCHEMAS_TYPE_BLOCK_EXTENSION)) ||
  18757. ((set & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION) &&
  18758. (methSet & XML_SCHEMAS_TYPE_BLOCK_RESTRICTION)))) {
  18759. continue;
  18760. }
  18761. add_member:
  18762. xmlSchemaAddElementSubstitutionMember(ctxt, head, elemDecl);
  18763. if ((head->flags & XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD) == 0)
  18764. head->flags |= XML_SCHEMAS_ELEM_SUBST_GROUP_HEAD;
  18765. }
  18766. }
  18767. }
  18768. #ifdef WXS_ELEM_DECL_CONS_ENABLED /* enable when finished */
  18769. /**
  18770. * xmlSchemaCheckElementDeclComponent
  18771. * @pctxt: the schema parser context
  18772. * @ctxtComponent: the context component (an element declaration)
  18773. * @ctxtParticle: the first particle of the context component
  18774. * @searchParticle: the element declaration particle to be analysed
  18775. *
  18776. * Schema Component Constraint: Element Declarations Consistent
  18777. */
  18778. static int
  18779. xmlSchemaCheckElementDeclConsistent(xmlSchemaParserCtxtPtr pctxt,
  18780. xmlSchemaBasicItemPtr ctxtComponent,
  18781. xmlSchemaParticlePtr ctxtParticle,
  18782. xmlSchemaParticlePtr searchParticle,
  18783. xmlSchemaParticlePtr curParticle,
  18784. int search)
  18785. {
  18786. return(0);
  18787. int ret = 0;
  18788. xmlSchemaParticlePtr cur = curParticle;
  18789. if (curParticle == NULL) {
  18790. return(0);
  18791. }
  18792. if (WXS_PARTICLE_TERM(curParticle) == NULL) {
  18793. /*
  18794. * Just return in this case. A missing "term" of the particle
  18795. * might arise due to an invalid "term" component.
  18796. */
  18797. return(0);
  18798. }
  18799. while (cur != NULL) {
  18800. switch (WXS_PARTICLE_TERM(cur)->type) {
  18801. case XML_SCHEMA_TYPE_ANY:
  18802. break;
  18803. case XML_SCHEMA_TYPE_ELEMENT:
  18804. if (search == 0) {
  18805. ret = xmlSchemaCheckElementDeclConsistent(pctxt,
  18806. ctxtComponent, ctxtParticle, cur, ctxtParticle, 1);
  18807. if (ret != 0)
  18808. return(ret);
  18809. } else {
  18810. xmlSchemaElementPtr elem =
  18811. WXS_ELEM_CAST(WXS_PARTICLE_TERM(cur));
  18812. /*
  18813. * SPEC Element Declarations Consistent:
  18814. * "If the {particles} contains, either directly,
  18815. * indirectly (that is, within the {particles} of a
  18816. * contained model group, recursively) or `implicitly`
  18817. * two or more element declaration particles with
  18818. * the same {name} and {target namespace}, then
  18819. * all their type definitions must be the same
  18820. * top-level definition [...]"
  18821. */
  18822. if (xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->name,
  18823. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->name) &&
  18824. xmlStrEqual(WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18825. WXS_PARTICLE_TERM_AS_ELEM(searchParticle)->targetNamespace))
  18826. {
  18827. xmlChar *strA = NULL, *strB = NULL;
  18828. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  18829. /* TODO: error code */
  18830. XML_SCHEMAP_COS_NONAMBIG,
  18831. WXS_ITEM_NODE(cur), NULL,
  18832. "In the content model of %s, there are multiple "
  18833. "element declarations for '%s' with different "
  18834. "type definitions",
  18835. xmlSchemaGetComponentDesignation(&strA,
  18836. ctxtComponent),
  18837. xmlSchemaFormatQName(&strB,
  18838. WXS_PARTICLE_TERM_AS_ELEM(cur)->targetNamespace,
  18839. WXS_PARTICLE_TERM_AS_ELEM(cur)->name));
  18840. FREE_AND_NULL(strA);
  18841. FREE_AND_NULL(strB);
  18842. return(XML_SCHEMAP_COS_NONAMBIG);
  18843. }
  18844. }
  18845. break;
  18846. case XML_SCHEMA_TYPE_SEQUENCE: {
  18847. break;
  18848. }
  18849. case XML_SCHEMA_TYPE_CHOICE:{
  18850. /*
  18851. xmlSchemaTreeItemPtr sub;
  18852. sub = WXS_PARTICLE_TERM(particle)->children; (xmlSchemaParticlePtr)
  18853. while (sub != NULL) {
  18854. ret = xmlSchemaCheckElementDeclConsistent(pctxt, ctxtComponent,
  18855. ctxtParticle, ctxtElem);
  18856. if (ret != 0)
  18857. return(ret);
  18858. sub = sub->next;
  18859. }
  18860. */
  18861. break;
  18862. }
  18863. case XML_SCHEMA_TYPE_ALL:
  18864. break;
  18865. case XML_SCHEMA_TYPE_GROUP:
  18866. break;
  18867. default:
  18868. xmlSchemaInternalErr2(ACTXT_CAST pctxt,
  18869. "xmlSchemaCheckElementDeclConsistent",
  18870. "found unexpected term of type '%s' in content model",
  18871. WXS_ITEM_TYPE_NAME(WXS_PARTICLE_TERM(cur)), NULL);
  18872. return(-1);
  18873. }
  18874. cur = (xmlSchemaParticlePtr) cur->next;
  18875. }
  18876. exit:
  18877. return(ret);
  18878. }
  18879. #endif
  18880. /**
  18881. * xmlSchemaCheckElementDeclComponent
  18882. * @item: an schema element declaration/particle
  18883. * @ctxt: a schema parser context
  18884. * @name: the name of the attribute
  18885. *
  18886. * Validates the value constraints of an element declaration.
  18887. * Adds substitution group members.
  18888. */
  18889. static void
  18890. xmlSchemaCheckElementDeclComponent(xmlSchemaElementPtr elemDecl,
  18891. xmlSchemaParserCtxtPtr ctxt)
  18892. {
  18893. if (elemDecl == NULL)
  18894. return;
  18895. if (elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED)
  18896. return;
  18897. elemDecl->flags |= XML_SCHEMAS_ELEM_INTERNAL_CHECKED;
  18898. if (xmlSchemaCheckElemPropsCorrect(ctxt, elemDecl) == 0) {
  18899. /*
  18900. * Adds substitution group members.
  18901. */
  18902. xmlSchemaCheckElemSubstGroup(ctxt, elemDecl);
  18903. }
  18904. }
  18905. /**
  18906. * xmlSchemaResolveModelGroupParticleReferences:
  18907. * @particle: a particle component
  18908. * @ctxt: a parser context
  18909. *
  18910. * Resolves references of a model group's {particles} to
  18911. * model group definitions and to element declarations.
  18912. */
  18913. static void
  18914. xmlSchemaResolveModelGroupParticleReferences(
  18915. xmlSchemaParserCtxtPtr ctxt,
  18916. xmlSchemaModelGroupPtr mg)
  18917. {
  18918. xmlSchemaParticlePtr particle = WXS_MODELGROUP_PARTICLE(mg);
  18919. xmlSchemaQNameRefPtr ref;
  18920. xmlSchemaBasicItemPtr refItem;
  18921. /*
  18922. * URGENT TODO: Test this.
  18923. */
  18924. while (particle != NULL) {
  18925. if ((WXS_PARTICLE_TERM(particle) == NULL) ||
  18926. ((WXS_PARTICLE_TERM(particle))->type !=
  18927. XML_SCHEMA_EXTRA_QNAMEREF))
  18928. {
  18929. goto next_particle;
  18930. }
  18931. ref = WXS_QNAME_CAST WXS_PARTICLE_TERM(particle);
  18932. /*
  18933. * Resolve the reference.
  18934. * NULL the {term} by default.
  18935. */
  18936. particle->children = NULL;
  18937. refItem = xmlSchemaGetNamedComponent(ctxt->schema,
  18938. ref->itemType, ref->name, ref->targetNamespace);
  18939. if (refItem == NULL) {
  18940. xmlSchemaPResCompAttrErr(ctxt, XML_SCHEMAP_SRC_RESOLVE,
  18941. NULL, WXS_ITEM_NODE(particle), "ref", ref->name,
  18942. ref->targetNamespace, ref->itemType, NULL);
  18943. /* TODO: remove the particle. */
  18944. goto next_particle;
  18945. }
  18946. if (refItem->type == XML_SCHEMA_TYPE_GROUP) {
  18947. if (WXS_MODELGROUPDEF_MODEL(refItem) == NULL)
  18948. /* TODO: remove the particle. */
  18949. goto next_particle;
  18950. /*
  18951. * NOTE that we will assign the model group definition
  18952. * itself to the "term" of the particle. This will ease
  18953. * the check for circular model group definitions. After
  18954. * that the "term" will be assigned the model group of the
  18955. * model group definition.
  18956. */
  18957. if ((WXS_MODELGROUPDEF_MODEL(refItem))->type ==
  18958. XML_SCHEMA_TYPE_ALL) {
  18959. /*
  18960. * SPEC cos-all-limited (1)
  18961. * SPEC cos-all-limited (1.2)
  18962. * "It appears only as the value of one or both of the
  18963. * following properties:"
  18964. * (1.1) "the {model group} property of a model group
  18965. * definition."
  18966. * (1.2) "the {term} property of a particle [... of] the "
  18967. * {content type} of a complex type definition."
  18968. */
  18969. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  18970. /* TODO: error code */
  18971. XML_SCHEMAP_COS_ALL_LIMITED,
  18972. WXS_ITEM_NODE(particle), NULL,
  18973. "A model group definition is referenced, but "
  18974. "it contains an 'all' model group, which "
  18975. "cannot be contained by model groups",
  18976. NULL, NULL);
  18977. /* TODO: remove the particle. */
  18978. goto next_particle;
  18979. }
  18980. particle->children = (xmlSchemaTreeItemPtr) refItem;
  18981. } else {
  18982. /*
  18983. * TODO: Are referenced element declarations the only
  18984. * other components we expect here?
  18985. */
  18986. particle->children = (xmlSchemaTreeItemPtr) refItem;
  18987. }
  18988. next_particle:
  18989. particle = WXS_PTC_CAST particle->next;
  18990. }
  18991. }
  18992. static int
  18993. xmlSchemaAreValuesEqual(xmlSchemaValPtr x,
  18994. xmlSchemaValPtr y)
  18995. {
  18996. xmlSchemaTypePtr tx, ty, ptx, pty;
  18997. int ret;
  18998. while (x != NULL) {
  18999. /* Same types. */
  19000. tx = xmlSchemaGetBuiltInType(xmlSchemaGetValType(x));
  19001. ty = xmlSchemaGetBuiltInType(xmlSchemaGetValType(y));
  19002. ptx = xmlSchemaGetPrimitiveType(tx);
  19003. pty = xmlSchemaGetPrimitiveType(ty);
  19004. /*
  19005. * (1) if a datatype T' is `derived` by `restriction` from an
  19006. * atomic datatype T then the `value space` of T' is a subset of
  19007. * the `value space` of T. */
  19008. /*
  19009. * (2) if datatypes T' and T'' are `derived` by `restriction`
  19010. * from a common atomic ancestor T then the `value space`s of T'
  19011. * and T'' may overlap.
  19012. */
  19013. if (ptx != pty)
  19014. return(0);
  19015. /*
  19016. * We assume computed values to be normalized, so do a fast
  19017. * string comparison for string based types.
  19018. */
  19019. if ((ptx->builtInType == XML_SCHEMAS_STRING) ||
  19020. WXS_IS_ANY_SIMPLE_TYPE(ptx)) {
  19021. if (! xmlStrEqual(
  19022. xmlSchemaValueGetAsString(x),
  19023. xmlSchemaValueGetAsString(y)))
  19024. return (0);
  19025. } else {
  19026. ret = xmlSchemaCompareValuesWhtsp(
  19027. x, XML_SCHEMA_WHITESPACE_PRESERVE,
  19028. y, XML_SCHEMA_WHITESPACE_PRESERVE);
  19029. if (ret == -2)
  19030. return(-1);
  19031. if (ret != 0)
  19032. return(0);
  19033. }
  19034. /*
  19035. * Lists.
  19036. */
  19037. x = xmlSchemaValueGetNext(x);
  19038. if (x != NULL) {
  19039. y = xmlSchemaValueGetNext(y);
  19040. if (y == NULL)
  19041. return (0);
  19042. } else if (xmlSchemaValueGetNext(y) != NULL)
  19043. return (0);
  19044. else
  19045. return (1);
  19046. }
  19047. return (0);
  19048. }
  19049. /**
  19050. * xmlSchemaResolveAttrUseReferences:
  19051. * @item: an attribute use
  19052. * @ctxt: a parser context
  19053. *
  19054. * Resolves the referenced attribute declaration.
  19055. */
  19056. static int
  19057. xmlSchemaResolveAttrUseReferences(xmlSchemaAttributeUsePtr ause,
  19058. xmlSchemaParserCtxtPtr ctxt)
  19059. {
  19060. if ((ctxt == NULL) || (ause == NULL))
  19061. return(-1);
  19062. if ((ause->attrDecl == NULL) ||
  19063. (ause->attrDecl->type != XML_SCHEMA_EXTRA_QNAMEREF))
  19064. return(0);
  19065. {
  19066. xmlSchemaQNameRefPtr ref = WXS_QNAME_CAST ause->attrDecl;
  19067. /*
  19068. * TODO: Evaluate, what errors could occur if the declaration is not
  19069. * found.
  19070. */
  19071. ause->attrDecl = xmlSchemaGetAttributeDecl(ctxt->schema,
  19072. ref->name, ref->targetNamespace);
  19073. if (ause->attrDecl == NULL) {
  19074. xmlSchemaPResCompAttrErr(ctxt,
  19075. XML_SCHEMAP_SRC_RESOLVE,
  19076. WXS_BASIC_CAST ause, ause->node,
  19077. "ref", ref->name, ref->targetNamespace,
  19078. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19079. return(ctxt->err);;
  19080. }
  19081. }
  19082. return(0);
  19083. }
  19084. /**
  19085. * xmlSchemaCheckAttrUsePropsCorrect:
  19086. * @ctxt: a parser context
  19087. * @use: an attribute use
  19088. *
  19089. * Schema Component Constraint:
  19090. * Attribute Use Correct (au-props-correct)
  19091. *
  19092. */
  19093. static int
  19094. xmlSchemaCheckAttrUsePropsCorrect(xmlSchemaParserCtxtPtr ctxt,
  19095. xmlSchemaAttributeUsePtr use)
  19096. {
  19097. if ((ctxt == NULL) || (use == NULL))
  19098. return(-1);
  19099. if ((use->defValue == NULL) || (WXS_ATTRUSE_DECL(use) == NULL) ||
  19100. ((WXS_ATTRUSE_DECL(use))->type != XML_SCHEMA_TYPE_ATTRIBUTE))
  19101. return(0);
  19102. /*
  19103. * SPEC au-props-correct (1)
  19104. * "The values of the properties of an attribute use must be as
  19105. * described in the property tableau in The Attribute Use Schema
  19106. * Component ($3.5.1), modulo the impact of Missing
  19107. * Sub-components ($5.3)."
  19108. */
  19109. if (((WXS_ATTRUSE_DECL(use))->defValue != NULL) &&
  19110. ((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMAS_ATTR_FIXED) &&
  19111. ((use->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19112. {
  19113. xmlSchemaPCustomErr(ctxt,
  19114. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19115. WXS_BASIC_CAST use, NULL,
  19116. "The attribute declaration has a 'fixed' value constraint "
  19117. ", thus the attribute use must also have a 'fixed' value "
  19118. "constraint",
  19119. NULL);
  19120. return(ctxt->err);
  19121. }
  19122. /*
  19123. * Compute and check the value constraint's value.
  19124. */
  19125. if ((use->defVal != NULL) && (WXS_ATTRUSE_TYPEDEF(use) != NULL)) {
  19126. int ret;
  19127. /*
  19128. * TODO: The spec seems to be missing a check of the
  19129. * value constraint of the attribute use. We will do it here.
  19130. */
  19131. /*
  19132. * SPEC a-props-correct (3)
  19133. */
  19134. if (xmlSchemaIsDerivedFromBuiltInType(
  19135. WXS_ATTRUSE_TYPEDEF(use), XML_SCHEMAS_ID))
  19136. {
  19137. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19138. XML_SCHEMAP_AU_PROPS_CORRECT,
  19139. NULL, WXS_BASIC_CAST use,
  19140. "Value constraints are not allowed if the type definition "
  19141. "is or is derived from xs:ID",
  19142. NULL, NULL);
  19143. return(ctxt->err);
  19144. }
  19145. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST ctxt,
  19146. use->node, WXS_ATTRUSE_TYPEDEF(use),
  19147. use->defValue, &(use->defVal),
  19148. 1, 1, 0);
  19149. if (ret != 0) {
  19150. if (ret < 0) {
  19151. PERROR_INT2("xmlSchemaCheckAttrUsePropsCorrect",
  19152. "calling xmlSchemaVCheckCVCSimpleType()");
  19153. return(-1);
  19154. }
  19155. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  19156. XML_SCHEMAP_AU_PROPS_CORRECT,
  19157. NULL, WXS_BASIC_CAST use,
  19158. "The value of the value constraint is not valid",
  19159. NULL, NULL);
  19160. return(ctxt->err);
  19161. }
  19162. }
  19163. /*
  19164. * SPEC au-props-correct (2)
  19165. * "If the {attribute declaration} has a fixed
  19166. * {value constraint}, then if the attribute use itself has a
  19167. * {value constraint}, it must also be fixed and its value must match
  19168. * that of the {attribute declaration}'s {value constraint}."
  19169. */
  19170. if (((WXS_ATTRUSE_DECL(use))->defVal != NULL) &&
  19171. (((WXS_ATTRUSE_DECL(use))->flags & XML_SCHEMA_ATTR_USE_FIXED) == 0))
  19172. {
  19173. if (! xmlSchemaAreValuesEqual(use->defVal,
  19174. (WXS_ATTRUSE_DECL(use))->defVal))
  19175. {
  19176. xmlSchemaPCustomErr(ctxt,
  19177. XML_SCHEMAP_AU_PROPS_CORRECT_2,
  19178. WXS_BASIC_CAST use, NULL,
  19179. "The 'fixed' value constraint of the attribute use "
  19180. "must match the attribute declaration's value "
  19181. "constraint '%s'",
  19182. (WXS_ATTRUSE_DECL(use))->defValue);
  19183. }
  19184. return(ctxt->err);
  19185. }
  19186. return(0);
  19187. }
  19188. /**
  19189. * xmlSchemaResolveAttrTypeReferences:
  19190. * @item: an attribute declaration
  19191. * @ctxt: a parser context
  19192. *
  19193. * Resolves the referenced type definition component.
  19194. */
  19195. static int
  19196. xmlSchemaResolveAttrTypeReferences(xmlSchemaAttributePtr item,
  19197. xmlSchemaParserCtxtPtr ctxt)
  19198. {
  19199. /*
  19200. * The simple type definition corresponding to the <simpleType> element
  19201. * information item in the [children], if present, otherwise the simple
  19202. * type definition `resolved` to by the `actual value` of the type
  19203. * [attribute], if present, otherwise the `simple ur-type definition`.
  19204. */
  19205. if (item->flags & XML_SCHEMAS_ATTR_INTERNAL_RESOLVED)
  19206. return(0);
  19207. item->flags |= XML_SCHEMAS_ATTR_INTERNAL_RESOLVED;
  19208. if (item->subtypes != NULL)
  19209. return(0);
  19210. if (item->typeName != NULL) {
  19211. xmlSchemaTypePtr type;
  19212. type = xmlSchemaGetType(ctxt->schema, item->typeName,
  19213. item->typeNs);
  19214. if ((type == NULL) || (! WXS_IS_SIMPLE(type))) {
  19215. xmlSchemaPResCompAttrErr(ctxt,
  19216. XML_SCHEMAP_SRC_RESOLVE,
  19217. WXS_BASIC_CAST item, item->node,
  19218. "type", item->typeName, item->typeNs,
  19219. XML_SCHEMA_TYPE_SIMPLE, NULL);
  19220. return(ctxt->err);
  19221. } else
  19222. item->subtypes = type;
  19223. } else {
  19224. /*
  19225. * The type defaults to the xs:anySimpleType.
  19226. */
  19227. item->subtypes = xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYSIMPLETYPE);
  19228. }
  19229. return(0);
  19230. }
  19231. /**
  19232. * xmlSchemaResolveIDCKeyReferences:
  19233. * @idc: the identity-constraint definition
  19234. * @ctxt: the schema parser context
  19235. * @name: the attribute name
  19236. *
  19237. * Resolve keyRef references to key/unique IDCs.
  19238. * Schema Component Constraint:
  19239. * Identity-constraint Definition Properties Correct (c-props-correct)
  19240. */
  19241. static int
  19242. xmlSchemaResolveIDCKeyReferences(xmlSchemaIDCPtr idc,
  19243. xmlSchemaParserCtxtPtr pctxt)
  19244. {
  19245. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF)
  19246. return(0);
  19247. if (idc->ref->name != NULL) {
  19248. idc->ref->item = (xmlSchemaBasicItemPtr)
  19249. xmlSchemaGetIDC(pctxt->schema, idc->ref->name,
  19250. idc->ref->targetNamespace);
  19251. if (idc->ref->item == NULL) {
  19252. /*
  19253. * TODO: It is actually not an error to fail to resolve
  19254. * at this stage. BUT we need to be that strict!
  19255. */
  19256. xmlSchemaPResCompAttrErr(pctxt,
  19257. XML_SCHEMAP_SRC_RESOLVE,
  19258. WXS_BASIC_CAST idc, idc->node,
  19259. "refer", idc->ref->name,
  19260. idc->ref->targetNamespace,
  19261. XML_SCHEMA_TYPE_IDC_KEY, NULL);
  19262. return(pctxt->err);
  19263. } else if (idc->ref->item->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  19264. /*
  19265. * SPEC c-props-correct (1)
  19266. */
  19267. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19268. XML_SCHEMAP_C_PROPS_CORRECT,
  19269. NULL, WXS_BASIC_CAST idc,
  19270. "The keyref references a keyref",
  19271. NULL, NULL);
  19272. idc->ref->item = NULL;
  19273. return(pctxt->err);
  19274. } else {
  19275. if (idc->nbFields !=
  19276. ((xmlSchemaIDCPtr) idc->ref->item)->nbFields) {
  19277. xmlChar *str = NULL;
  19278. xmlSchemaIDCPtr refer;
  19279. refer = (xmlSchemaIDCPtr) idc->ref->item;
  19280. /*
  19281. * SPEC c-props-correct(2)
  19282. * "If the {identity-constraint category} is keyref,
  19283. * the cardinality of the {fields} must equal that of
  19284. * the {fields} of the {referenced key}.
  19285. */
  19286. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19287. XML_SCHEMAP_C_PROPS_CORRECT,
  19288. NULL, WXS_BASIC_CAST idc,
  19289. "The cardinality of the keyref differs from the "
  19290. "cardinality of the referenced key/unique '%s'",
  19291. xmlSchemaFormatQName(&str, refer->targetNamespace,
  19292. refer->name),
  19293. NULL);
  19294. FREE_AND_NULL(str)
  19295. return(pctxt->err);
  19296. }
  19297. }
  19298. }
  19299. return(0);
  19300. }
  19301. static int
  19302. xmlSchemaResolveAttrUseProhibReferences(xmlSchemaAttributeUseProhibPtr prohib,
  19303. xmlSchemaParserCtxtPtr pctxt)
  19304. {
  19305. if (xmlSchemaGetAttributeDecl(pctxt->schema, prohib->name,
  19306. prohib->targetNamespace) == NULL) {
  19307. xmlSchemaPResCompAttrErr(pctxt,
  19308. XML_SCHEMAP_SRC_RESOLVE,
  19309. NULL, prohib->node,
  19310. "ref", prohib->name, prohib->targetNamespace,
  19311. XML_SCHEMA_TYPE_ATTRIBUTE, NULL);
  19312. return(XML_SCHEMAP_SRC_RESOLVE);
  19313. }
  19314. return(0);
  19315. }
  19316. #define WXS_REDEFINED_TYPE(c) \
  19317. (((xmlSchemaTypePtr) item)->flags & XML_SCHEMAS_TYPE_REDEFINED)
  19318. #define WXS_REDEFINED_MODEL_GROUP_DEF(c) \
  19319. (((xmlSchemaModelGroupDefPtr) item)->flags & XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19320. #define WXS_REDEFINED_ATTR_GROUP(c) \
  19321. (((xmlSchemaAttributeGroupPtr) item)->flags & XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19322. static int
  19323. xmlSchemaCheckSRCRedefineFirst(xmlSchemaParserCtxtPtr pctxt)
  19324. {
  19325. int err = 0;
  19326. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19327. xmlSchemaBasicItemPtr prev, item;
  19328. int wasRedefined;
  19329. if (redef == NULL)
  19330. return(0);
  19331. do {
  19332. item = redef->item;
  19333. /*
  19334. * First try to locate the redefined component in the
  19335. * schema graph starting with the redefined schema.
  19336. * NOTE: According to this schema bug entry:
  19337. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005OctDec/0019.html
  19338. * it's not clear if the referenced component needs to originate
  19339. * from the <redefine>d schema _document_ or the schema; the latter
  19340. * would include all imported and included sub-schemas of the
  19341. * <redefine>d schema. Currently the latter approach is used.
  19342. * SUPPLEMENT: It seems that the WG moves towards the latter
  19343. * approach, so we are doing it right.
  19344. *
  19345. */
  19346. prev = xmlSchemaFindRedefCompInGraph(
  19347. redef->targetBucket, item->type,
  19348. redef->refName, redef->refTargetNs);
  19349. if (prev == NULL) {
  19350. xmlChar *str = NULL;
  19351. xmlNodePtr node;
  19352. /*
  19353. * SPEC src-redefine:
  19354. * (6.2.1) "The `actual value` of its own name attribute plus
  19355. * target namespace must successfully `resolve` to a model
  19356. * group definition in I."
  19357. * (7.2.1) "The `actual value` of its own name attribute plus
  19358. * target namespace must successfully `resolve` to an attribute
  19359. * group definition in I."
  19360. *
  19361. * Note that, if we are redefining with the use of references
  19362. * to components, the spec assumes the src-resolve to be used;
  19363. * but this won't assure that we search only *inside* the
  19364. * redefined schema.
  19365. */
  19366. if (redef->reference)
  19367. node = WXS_ITEM_NODE(redef->reference);
  19368. else
  19369. node = WXS_ITEM_NODE(item);
  19370. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19371. /*
  19372. * TODO: error code.
  19373. * Probably XML_SCHEMAP_SRC_RESOLVE, if this is using the
  19374. * reference kind.
  19375. */
  19376. XML_SCHEMAP_SRC_REDEFINE, node, NULL,
  19377. "The %s '%s' to be redefined could not be found in "
  19378. "the redefined schema",
  19379. WXS_ITEM_TYPE_NAME(item),
  19380. xmlSchemaFormatQName(&str, redef->refTargetNs,
  19381. redef->refName));
  19382. FREE_AND_NULL(str);
  19383. err = pctxt->err;
  19384. redef = redef->next;
  19385. continue;
  19386. }
  19387. /*
  19388. * TODO: Obtaining and setting the redefinition state is really
  19389. * clumsy.
  19390. */
  19391. wasRedefined = 0;
  19392. switch (item->type) {
  19393. case XML_SCHEMA_TYPE_COMPLEX:
  19394. case XML_SCHEMA_TYPE_SIMPLE:
  19395. if ((WXS_TYPE_CAST prev)->flags &
  19396. XML_SCHEMAS_TYPE_REDEFINED)
  19397. {
  19398. wasRedefined = 1;
  19399. break;
  19400. }
  19401. /* Mark it as redefined. */
  19402. (WXS_TYPE_CAST prev)->flags |= XML_SCHEMAS_TYPE_REDEFINED;
  19403. /*
  19404. * Assign the redefined type to the
  19405. * base type of the redefining type.
  19406. * TODO: How
  19407. */
  19408. ((xmlSchemaTypePtr) item)->baseType =
  19409. (xmlSchemaTypePtr) prev;
  19410. break;
  19411. case XML_SCHEMA_TYPE_GROUP:
  19412. if ((WXS_MODEL_GROUPDEF_CAST prev)->flags &
  19413. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED)
  19414. {
  19415. wasRedefined = 1;
  19416. break;
  19417. }
  19418. /* Mark it as redefined. */
  19419. (WXS_MODEL_GROUPDEF_CAST prev)->flags |=
  19420. XML_SCHEMA_MODEL_GROUP_DEF_REDEFINED;
  19421. if (redef->reference != NULL) {
  19422. /*
  19423. * Overwrite the QName-reference with the
  19424. * referenced model group def.
  19425. */
  19426. (WXS_PTC_CAST redef->reference)->children =
  19427. WXS_TREE_CAST prev;
  19428. }
  19429. redef->target = prev;
  19430. break;
  19431. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19432. if ((WXS_ATTR_GROUP_CAST prev)->flags &
  19433. XML_SCHEMAS_ATTRGROUP_REDEFINED)
  19434. {
  19435. wasRedefined = 1;
  19436. break;
  19437. }
  19438. (WXS_ATTR_GROUP_CAST prev)->flags |=
  19439. XML_SCHEMAS_ATTRGROUP_REDEFINED;
  19440. if (redef->reference != NULL) {
  19441. /*
  19442. * Assign the redefined attribute group to the
  19443. * QName-reference component.
  19444. * This is the easy case, since we will just
  19445. * expand the redefined group.
  19446. */
  19447. (WXS_QNAME_CAST redef->reference)->item = prev;
  19448. redef->target = NULL;
  19449. } else {
  19450. /*
  19451. * This is the complicated case: we need
  19452. * to apply src-redefine (7.2.2) at a later
  19453. * stage, i.e. when attribute group references
  19454. * have been expanded and simple types have
  19455. * been fixed.
  19456. */
  19457. redef->target = prev;
  19458. }
  19459. break;
  19460. default:
  19461. PERROR_INT("xmlSchemaResolveRedefReferences",
  19462. "Unexpected redefined component type");
  19463. return(-1);
  19464. }
  19465. if (wasRedefined) {
  19466. xmlChar *str = NULL;
  19467. xmlNodePtr node;
  19468. if (redef->reference)
  19469. node = WXS_ITEM_NODE(redef->reference);
  19470. else
  19471. node = WXS_ITEM_NODE(redef->item);
  19472. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19473. /* TODO: error code. */
  19474. XML_SCHEMAP_SRC_REDEFINE,
  19475. node, NULL,
  19476. "The referenced %s was already redefined. Multiple "
  19477. "redefinition of the same component is not supported",
  19478. xmlSchemaGetComponentDesignation(&str, prev),
  19479. NULL);
  19480. FREE_AND_NULL(str)
  19481. err = pctxt->err;
  19482. redef = redef->next;
  19483. continue;
  19484. }
  19485. redef = redef->next;
  19486. } while (redef != NULL);
  19487. return(err);
  19488. }
  19489. static int
  19490. xmlSchemaCheckSRCRedefineSecond(xmlSchemaParserCtxtPtr pctxt)
  19491. {
  19492. int err = 0;
  19493. xmlSchemaRedefPtr redef = WXS_CONSTRUCTOR(pctxt)->redefs;
  19494. xmlSchemaBasicItemPtr item;
  19495. if (redef == NULL)
  19496. return(0);
  19497. do {
  19498. if (redef->target == NULL) {
  19499. redef = redef->next;
  19500. continue;
  19501. }
  19502. item = redef->item;
  19503. switch (item->type) {
  19504. case XML_SCHEMA_TYPE_SIMPLE:
  19505. case XML_SCHEMA_TYPE_COMPLEX:
  19506. /*
  19507. * Since the spec wants the {name} of the redefined
  19508. * type to be 'absent', we'll NULL it.
  19509. */
  19510. (WXS_TYPE_CAST redef->target)->name = NULL;
  19511. /*
  19512. * TODO: Seems like there's nothing more to do. The normal
  19513. * inheritance mechanism is used. But not 100% sure.
  19514. */
  19515. break;
  19516. case XML_SCHEMA_TYPE_GROUP:
  19517. /*
  19518. * URGENT TODO:
  19519. * SPEC src-redefine:
  19520. * (6.2.2) "The {model group} of the model group definition
  19521. * which corresponds to it per XML Representation of Model
  19522. * Group Definition Schema Components ($3.7.2) must be a
  19523. * `valid restriction` of the {model group} of that model
  19524. * group definition in I, as defined in Particle Valid
  19525. * (Restriction) ($3.9.6)."
  19526. */
  19527. break;
  19528. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19529. /*
  19530. * SPEC src-redefine:
  19531. * (7.2.2) "The {attribute uses} and {attribute wildcard} of
  19532. * the attribute group definition which corresponds to it
  19533. * per XML Representation of Attribute Group Definition Schema
  19534. * Components ($3.6.2) must be `valid restrictions` of the
  19535. * {attribute uses} and {attribute wildcard} of that attribute
  19536. * group definition in I, as defined in clause 2, clause 3 and
  19537. * clause 4 of Derivation Valid (Restriction, Complex)
  19538. * ($3.4.6) (where references to the base type definition are
  19539. * understood as references to the attribute group definition
  19540. * in I)."
  19541. */
  19542. err = xmlSchemaCheckDerivationOKRestriction2to4(pctxt,
  19543. XML_SCHEMA_ACTION_REDEFINE,
  19544. item, redef->target,
  19545. (WXS_ATTR_GROUP_CAST item)->attrUses,
  19546. (WXS_ATTR_GROUP_CAST redef->target)->attrUses,
  19547. (WXS_ATTR_GROUP_CAST item)->attributeWildcard,
  19548. (WXS_ATTR_GROUP_CAST redef->target)->attributeWildcard);
  19549. if (err == -1)
  19550. return(-1);
  19551. break;
  19552. default:
  19553. break;
  19554. }
  19555. redef = redef->next;
  19556. } while (redef != NULL);
  19557. return(0);
  19558. }
  19559. static int
  19560. xmlSchemaAddComponents(xmlSchemaParserCtxtPtr pctxt,
  19561. xmlSchemaBucketPtr bucket)
  19562. {
  19563. xmlSchemaBasicItemPtr item;
  19564. int err;
  19565. xmlHashTablePtr *table;
  19566. const xmlChar *name;
  19567. int i;
  19568. #define WXS_GET_GLOBAL_HASH(c, slot) { \
  19569. if (WXS_IS_BUCKET_IMPMAIN((c)->type)) \
  19570. table = &(WXS_IMPBUCKET((c))->schema->slot); \
  19571. else \
  19572. table = &(WXS_INCBUCKET((c))->ownerImport->schema->slot); }
  19573. /*
  19574. * Add global components to the schema's hash tables.
  19575. * This is the place where duplicate components will be
  19576. * detected.
  19577. * TODO: I think normally we should support imports of the
  19578. * same namespace from multiple locations. We don't do currently,
  19579. * but if we do then according to:
  19580. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2224
  19581. * we would need, if imported directly, to import redefined
  19582. * components as well to be able to catch clashing components.
  19583. * (I hope I'll still know what this means after some months :-()
  19584. */
  19585. if (bucket == NULL)
  19586. return(-1);
  19587. if (bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED)
  19588. return(0);
  19589. bucket->flags |= XML_SCHEMA_BUCKET_COMPS_ADDED;
  19590. for (i = 0; i < bucket->globals->nbItems; i++) {
  19591. item = bucket->globals->items[i];
  19592. table = NULL;
  19593. switch (item->type) {
  19594. case XML_SCHEMA_TYPE_COMPLEX:
  19595. case XML_SCHEMA_TYPE_SIMPLE:
  19596. if (WXS_REDEFINED_TYPE(item))
  19597. continue;
  19598. name = (WXS_TYPE_CAST item)->name;
  19599. WXS_GET_GLOBAL_HASH(bucket, typeDecl)
  19600. break;
  19601. case XML_SCHEMA_TYPE_ELEMENT:
  19602. name = (WXS_ELEM_CAST item)->name;
  19603. WXS_GET_GLOBAL_HASH(bucket, elemDecl)
  19604. break;
  19605. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19606. name = (WXS_ATTR_CAST item)->name;
  19607. WXS_GET_GLOBAL_HASH(bucket, attrDecl)
  19608. break;
  19609. case XML_SCHEMA_TYPE_GROUP:
  19610. if (WXS_REDEFINED_MODEL_GROUP_DEF(item))
  19611. continue;
  19612. name = (WXS_MODEL_GROUPDEF_CAST item)->name;
  19613. WXS_GET_GLOBAL_HASH(bucket, groupDecl)
  19614. break;
  19615. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19616. if (WXS_REDEFINED_ATTR_GROUP(item))
  19617. continue;
  19618. name = (WXS_ATTR_GROUP_CAST item)->name;
  19619. WXS_GET_GLOBAL_HASH(bucket, attrgrpDecl)
  19620. break;
  19621. case XML_SCHEMA_TYPE_IDC_KEY:
  19622. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19623. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19624. name = (WXS_IDC_CAST item)->name;
  19625. WXS_GET_GLOBAL_HASH(bucket, idcDef)
  19626. break;
  19627. case XML_SCHEMA_TYPE_NOTATION:
  19628. name = ((xmlSchemaNotationPtr) item)->name;
  19629. WXS_GET_GLOBAL_HASH(bucket, notaDecl)
  19630. break;
  19631. default:
  19632. PERROR_INT("xmlSchemaAddComponents",
  19633. "Unexpected global component type");
  19634. continue;
  19635. }
  19636. if (*table == NULL) {
  19637. *table = xmlHashCreateDict(10, pctxt->dict);
  19638. if (*table == NULL) {
  19639. PERROR_INT("xmlSchemaAddComponents",
  19640. "failed to create a component hash table");
  19641. return(-1);
  19642. }
  19643. }
  19644. err = xmlHashAddEntry(*table, name, item);
  19645. if (err != 0) {
  19646. xmlChar *str = NULL;
  19647. xmlSchemaCustomErr(ACTXT_CAST pctxt,
  19648. XML_SCHEMAP_REDEFINED_TYPE,
  19649. WXS_ITEM_NODE(item),
  19650. WXS_BASIC_CAST item,
  19651. "A global %s '%s' does already exist",
  19652. WXS_ITEM_TYPE_NAME(item),
  19653. xmlSchemaGetComponentQName(&str, item));
  19654. FREE_AND_NULL(str);
  19655. }
  19656. }
  19657. /*
  19658. * Process imported/included schemas.
  19659. */
  19660. if (bucket->relations != NULL) {
  19661. xmlSchemaSchemaRelationPtr rel = bucket->relations;
  19662. do {
  19663. if ((rel->bucket != NULL) &&
  19664. ((rel->bucket->flags & XML_SCHEMA_BUCKET_COMPS_ADDED) == 0)) {
  19665. if (xmlSchemaAddComponents(pctxt, rel->bucket) == -1)
  19666. return(-1);
  19667. }
  19668. rel = rel->next;
  19669. } while (rel != NULL);
  19670. }
  19671. return(0);
  19672. }
  19673. static int
  19674. xmlSchemaFixupComponents(xmlSchemaParserCtxtPtr pctxt,
  19675. xmlSchemaBucketPtr rootBucket)
  19676. {
  19677. xmlSchemaConstructionCtxtPtr con = pctxt->constructor;
  19678. xmlSchemaTreeItemPtr item, *items;
  19679. int nbItems, i, ret = 0;
  19680. xmlSchemaBucketPtr oldbucket = con->bucket;
  19681. xmlSchemaElementPtr elemDecl;
  19682. #define FIXHFAILURE if (pctxt->err == XML_SCHEMAP_INTERNAL) goto exit_failure;
  19683. if ((con->pending == NULL) ||
  19684. (con->pending->nbItems == 0))
  19685. return(0);
  19686. /*
  19687. * Since xmlSchemaFixupComplexType() will create new particles
  19688. * (local components), and those particle components need a bucket
  19689. * on the constructor, we'll assure here that the constructor has
  19690. * a bucket.
  19691. * TODO: Think about storing locals _only_ on the main bucket.
  19692. */
  19693. if (con->bucket == NULL)
  19694. con->bucket = rootBucket;
  19695. /* TODO:
  19696. * SPEC (src-redefine):
  19697. * (6.2) "If it has no such self-reference, then all of the
  19698. * following must be true:"
  19699. * (6.2.2) The {model group} of the model group definition which
  19700. * corresponds to it per XML Representation of Model Group
  19701. * Definition Schema Components ($3.7.2) must be a `valid
  19702. * restriction` of the {model group} of that model group definition
  19703. * in I, as defined in Particle Valid (Restriction) ($3.9.6)."
  19704. */
  19705. xmlSchemaCheckSRCRedefineFirst(pctxt);
  19706. /*
  19707. * Add global components to the schemata's hash tables.
  19708. */
  19709. xmlSchemaAddComponents(pctxt, rootBucket);
  19710. pctxt->ctxtType = NULL;
  19711. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  19712. nbItems = con->pending->nbItems;
  19713. /*
  19714. * Now that we have parsed *all* the schema document(s) and converted
  19715. * them to schema components, we can resolve references, apply component
  19716. * constraints, create the FSA from the content model, etc.
  19717. */
  19718. /*
  19719. * Resolve references of..
  19720. *
  19721. * 1. element declarations:
  19722. * - the type definition
  19723. * - the substitution group affiliation
  19724. * 2. simple/complex types:
  19725. * - the base type definition
  19726. * - the memberTypes of union types
  19727. * - the itemType of list types
  19728. * 3. attributes declarations and attribute uses:
  19729. * - the type definition
  19730. * - if an attribute use, then the attribute declaration
  19731. * 4. attribute group references:
  19732. * - the attribute group definition
  19733. * 5. particles:
  19734. * - the term of the particle (e.g. a model group)
  19735. * 6. IDC key-references:
  19736. * - the referenced IDC 'key' or 'unique' definition
  19737. * 7. Attribute prohibitions which had a "ref" attribute.
  19738. */
  19739. for (i = 0; i < nbItems; i++) {
  19740. item = items[i];
  19741. switch (item->type) {
  19742. case XML_SCHEMA_TYPE_ELEMENT:
  19743. xmlSchemaResolveElementReferences(
  19744. (xmlSchemaElementPtr) item, pctxt);
  19745. FIXHFAILURE;
  19746. break;
  19747. case XML_SCHEMA_TYPE_COMPLEX:
  19748. case XML_SCHEMA_TYPE_SIMPLE:
  19749. xmlSchemaResolveTypeReferences(
  19750. (xmlSchemaTypePtr) item, pctxt);
  19751. FIXHFAILURE;
  19752. break;
  19753. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19754. xmlSchemaResolveAttrTypeReferences(
  19755. (xmlSchemaAttributePtr) item, pctxt);
  19756. FIXHFAILURE;
  19757. break;
  19758. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19759. xmlSchemaResolveAttrUseReferences(
  19760. (xmlSchemaAttributeUsePtr) item, pctxt);
  19761. FIXHFAILURE;
  19762. break;
  19763. case XML_SCHEMA_EXTRA_QNAMEREF:
  19764. if ((WXS_QNAME_CAST item)->itemType ==
  19765. XML_SCHEMA_TYPE_ATTRIBUTEGROUP)
  19766. {
  19767. xmlSchemaResolveAttrGroupReferences(
  19768. WXS_QNAME_CAST item, pctxt);
  19769. }
  19770. FIXHFAILURE;
  19771. break;
  19772. case XML_SCHEMA_TYPE_SEQUENCE:
  19773. case XML_SCHEMA_TYPE_CHOICE:
  19774. case XML_SCHEMA_TYPE_ALL:
  19775. xmlSchemaResolveModelGroupParticleReferences(pctxt,
  19776. WXS_MODEL_GROUP_CAST item);
  19777. FIXHFAILURE;
  19778. break;
  19779. case XML_SCHEMA_TYPE_IDC_KEY:
  19780. case XML_SCHEMA_TYPE_IDC_UNIQUE:
  19781. case XML_SCHEMA_TYPE_IDC_KEYREF:
  19782. xmlSchemaResolveIDCKeyReferences(
  19783. (xmlSchemaIDCPtr) item, pctxt);
  19784. FIXHFAILURE;
  19785. break;
  19786. case XML_SCHEMA_EXTRA_ATTR_USE_PROHIB:
  19787. /*
  19788. * Handle attribue prohibition which had a
  19789. * "ref" attribute.
  19790. */
  19791. xmlSchemaResolveAttrUseProhibReferences(
  19792. WXS_ATTR_PROHIB_CAST item, pctxt);
  19793. FIXHFAILURE;
  19794. break;
  19795. default:
  19796. break;
  19797. }
  19798. }
  19799. if (pctxt->nberrors != 0)
  19800. goto exit_error;
  19801. /*
  19802. * Now that all references are resolved we
  19803. * can check for circularity of...
  19804. * 1. the base axis of type definitions
  19805. * 2. nested model group definitions
  19806. * 3. nested attribute group definitions
  19807. * TODO: check for circular substitution groups.
  19808. */
  19809. for (i = 0; i < nbItems; i++) {
  19810. item = items[i];
  19811. /*
  19812. * Let's better stop on the first error here.
  19813. */
  19814. switch (item->type) {
  19815. case XML_SCHEMA_TYPE_COMPLEX:
  19816. case XML_SCHEMA_TYPE_SIMPLE:
  19817. xmlSchemaCheckTypeDefCircular(
  19818. (xmlSchemaTypePtr) item, pctxt);
  19819. FIXHFAILURE;
  19820. if (pctxt->nberrors != 0)
  19821. goto exit_error;
  19822. break;
  19823. case XML_SCHEMA_TYPE_GROUP:
  19824. xmlSchemaCheckGroupDefCircular(
  19825. (xmlSchemaModelGroupDefPtr) item, pctxt);
  19826. FIXHFAILURE;
  19827. if (pctxt->nberrors != 0)
  19828. goto exit_error;
  19829. break;
  19830. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19831. xmlSchemaCheckAttrGroupCircular(
  19832. (xmlSchemaAttributeGroupPtr) item, pctxt);
  19833. FIXHFAILURE;
  19834. if (pctxt->nberrors != 0)
  19835. goto exit_error;
  19836. break;
  19837. default:
  19838. break;
  19839. }
  19840. }
  19841. if (pctxt->nberrors != 0)
  19842. goto exit_error;
  19843. /*
  19844. * Model group definition references:
  19845. * Such a reference is reflected by a particle at the component
  19846. * level. Until now the 'term' of such particles pointed
  19847. * to the model group definition; this was done, in order to
  19848. * ease circularity checks. Now we need to set the 'term' of
  19849. * such particles to the model group of the model group definition.
  19850. */
  19851. for (i = 0; i < nbItems; i++) {
  19852. item = items[i];
  19853. switch (item->type) {
  19854. case XML_SCHEMA_TYPE_SEQUENCE:
  19855. case XML_SCHEMA_TYPE_CHOICE:
  19856. xmlSchemaModelGroupToModelGroupDefFixup(pctxt,
  19857. WXS_MODEL_GROUP_CAST item);
  19858. break;
  19859. default:
  19860. break;
  19861. }
  19862. }
  19863. if (pctxt->nberrors != 0)
  19864. goto exit_error;
  19865. /*
  19866. * Expand attribute group references of attribute group definitions.
  19867. */
  19868. for (i = 0; i < nbItems; i++) {
  19869. item = items[i];
  19870. switch (item->type) {
  19871. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19872. if ((! WXS_ATTR_GROUP_EXPANDED(item)) &&
  19873. WXS_ATTR_GROUP_HAS_REFS(item))
  19874. {
  19875. xmlSchemaAttributeGroupExpandRefs(pctxt,
  19876. WXS_ATTR_GROUP_CAST item);
  19877. FIXHFAILURE;
  19878. }
  19879. break;
  19880. default:
  19881. break;
  19882. }
  19883. }
  19884. if (pctxt->nberrors != 0)
  19885. goto exit_error;
  19886. /*
  19887. * First compute the variety of simple types. This is needed as
  19888. * a separate step, since otherwise we won't be able to detect
  19889. * circular union types in all cases.
  19890. */
  19891. for (i = 0; i < nbItems; i++) {
  19892. item = items[i];
  19893. switch (item->type) {
  19894. case XML_SCHEMA_TYPE_SIMPLE:
  19895. if (WXS_IS_TYPE_NOT_FIXED_1((xmlSchemaTypePtr) item)) {
  19896. xmlSchemaFixupSimpleTypeStageOne(pctxt,
  19897. (xmlSchemaTypePtr) item);
  19898. FIXHFAILURE;
  19899. }
  19900. break;
  19901. default:
  19902. break;
  19903. }
  19904. }
  19905. if (pctxt->nberrors != 0)
  19906. goto exit_error;
  19907. /*
  19908. * Detect circular union types. Note that this needs the variety to
  19909. * be already computed.
  19910. */
  19911. for (i = 0; i < nbItems; i++) {
  19912. item = items[i];
  19913. switch (item->type) {
  19914. case XML_SCHEMA_TYPE_SIMPLE:
  19915. if (((xmlSchemaTypePtr) item)->memberTypes != NULL) {
  19916. xmlSchemaCheckUnionTypeDefCircular(pctxt,
  19917. (xmlSchemaTypePtr) item);
  19918. FIXHFAILURE;
  19919. }
  19920. break;
  19921. default:
  19922. break;
  19923. }
  19924. }
  19925. if (pctxt->nberrors != 0)
  19926. goto exit_error;
  19927. /*
  19928. * Do the complete type fixup for simple types.
  19929. */
  19930. for (i = 0; i < nbItems; i++) {
  19931. item = items[i];
  19932. switch (item->type) {
  19933. case XML_SCHEMA_TYPE_SIMPLE:
  19934. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  19935. xmlSchemaFixupSimpleTypeStageTwo(pctxt, WXS_TYPE_CAST item);
  19936. FIXHFAILURE;
  19937. }
  19938. break;
  19939. default:
  19940. break;
  19941. }
  19942. }
  19943. if (pctxt->nberrors != 0)
  19944. goto exit_error;
  19945. /*
  19946. * At this point we need build and check all simple types.
  19947. */
  19948. /*
  19949. * Apply constraints for attribute declarations.
  19950. */
  19951. for (i = 0; i < nbItems; i++) {
  19952. item = items[i];
  19953. switch (item->type) {
  19954. case XML_SCHEMA_TYPE_ATTRIBUTE:
  19955. xmlSchemaCheckAttrPropsCorrect(pctxt, WXS_ATTR_CAST item);
  19956. FIXHFAILURE;
  19957. break;
  19958. default:
  19959. break;
  19960. }
  19961. }
  19962. if (pctxt->nberrors != 0)
  19963. goto exit_error;
  19964. /*
  19965. * Apply constraints for attribute uses.
  19966. */
  19967. for (i = 0; i < nbItems; i++) {
  19968. item = items[i];
  19969. switch (item->type) {
  19970. case XML_SCHEMA_TYPE_ATTRIBUTE_USE:
  19971. if (((xmlSchemaAttributeUsePtr)item)->defValue != NULL) {
  19972. xmlSchemaCheckAttrUsePropsCorrect(pctxt,
  19973. WXS_ATTR_USE_CAST item);
  19974. FIXHFAILURE;
  19975. }
  19976. break;
  19977. default:
  19978. break;
  19979. }
  19980. }
  19981. if (pctxt->nberrors != 0)
  19982. goto exit_error;
  19983. /*
  19984. * Apply constraints for attribute group definitions.
  19985. */
  19986. for (i = 0; i < nbItems; i++) {
  19987. item = items[i];
  19988. switch (item->type) {
  19989. case XML_SCHEMA_TYPE_ATTRIBUTEGROUP:
  19990. if (( (WXS_ATTR_GROUP_CAST item)->attrUses != NULL) &&
  19991. ( (WXS_LIST_CAST (WXS_ATTR_GROUP_CAST item)->attrUses)->nbItems > 1))
  19992. {
  19993. xmlSchemaCheckAGPropsCorrect(pctxt, WXS_ATTR_GROUP_CAST item);
  19994. FIXHFAILURE;
  19995. }
  19996. break;
  19997. default:
  19998. break;
  19999. }
  20000. }
  20001. if (pctxt->nberrors != 0)
  20002. goto exit_error;
  20003. /*
  20004. * Apply constraints for redefinitions.
  20005. */
  20006. if (WXS_CONSTRUCTOR(pctxt)->redefs != NULL)
  20007. xmlSchemaCheckSRCRedefineSecond(pctxt);
  20008. if (pctxt->nberrors != 0)
  20009. goto exit_error;
  20010. /*
  20011. * Complex types are built and checked.
  20012. */
  20013. for (i = 0; i < nbItems; i++) {
  20014. item = con->pending->items[i];
  20015. switch (item->type) {
  20016. case XML_SCHEMA_TYPE_COMPLEX:
  20017. if (WXS_IS_TYPE_NOT_FIXED(WXS_TYPE_CAST item)) {
  20018. xmlSchemaFixupComplexType(pctxt, WXS_TYPE_CAST item);
  20019. FIXHFAILURE;
  20020. }
  20021. break;
  20022. default:
  20023. break;
  20024. }
  20025. }
  20026. if (pctxt->nberrors != 0)
  20027. goto exit_error;
  20028. /*
  20029. * The list could have changed, since xmlSchemaFixupComplexType()
  20030. * will create particles and model groups in some cases.
  20031. */
  20032. items = (xmlSchemaTreeItemPtr *) con->pending->items;
  20033. nbItems = con->pending->nbItems;
  20034. /*
  20035. * Apply some constraints for element declarations.
  20036. */
  20037. for (i = 0; i < nbItems; i++) {
  20038. item = items[i];
  20039. switch (item->type) {
  20040. case XML_SCHEMA_TYPE_ELEMENT:
  20041. elemDecl = (xmlSchemaElementPtr) item;
  20042. if ((elemDecl->flags & XML_SCHEMAS_ELEM_INTERNAL_CHECKED) == 0)
  20043. {
  20044. xmlSchemaCheckElementDeclComponent(
  20045. (xmlSchemaElementPtr) elemDecl, pctxt);
  20046. FIXHFAILURE;
  20047. }
  20048. #ifdef WXS_ELEM_DECL_CONS_ENABLED
  20049. /*
  20050. * Schema Component Constraint: Element Declarations Consistent
  20051. * Apply this constraint to local types of element declarations.
  20052. */
  20053. if ((WXS_ELEM_TYPEDEF(elemDecl) != NULL) &&
  20054. (WXS_IS_COMPLEX(WXS_ELEM_TYPEDEF(elemDecl))) &&
  20055. (WXS_TYPE_IS_LOCAL(WXS_ELEM_TYPEDEF(elemDecl))))
  20056. {
  20057. xmlSchemaCheckElementDeclConsistent(pctxt,
  20058. WXS_BASIC_CAST elemDecl,
  20059. WXS_TYPE_PARTICLE(WXS_ELEM_TYPEDEF(elemDecl)),
  20060. NULL, NULL, 0);
  20061. }
  20062. #endif
  20063. break;
  20064. default:
  20065. break;
  20066. }
  20067. }
  20068. if (pctxt->nberrors != 0)
  20069. goto exit_error;
  20070. /*
  20071. * Finally we can build the automaton from the content model of
  20072. * complex types.
  20073. */
  20074. for (i = 0; i < nbItems; i++) {
  20075. item = items[i];
  20076. switch (item->type) {
  20077. case XML_SCHEMA_TYPE_COMPLEX:
  20078. xmlSchemaBuildContentModel((xmlSchemaTypePtr) item, pctxt);
  20079. /* FIXHFAILURE; */
  20080. break;
  20081. default:
  20082. break;
  20083. }
  20084. }
  20085. if (pctxt->nberrors != 0)
  20086. goto exit_error;
  20087. /*
  20088. * URGENT TODO: cos-element-consistent
  20089. */
  20090. goto exit;
  20091. exit_error:
  20092. ret = pctxt->err;
  20093. goto exit;
  20094. exit_failure:
  20095. ret = -1;
  20096. exit:
  20097. /*
  20098. * Reset the constructor. This is needed for XSI acquisition, since
  20099. * those items will be processed over and over again for every XSI
  20100. * if not cleared here.
  20101. */
  20102. con->bucket = oldbucket;
  20103. con->pending->nbItems = 0;
  20104. if (con->substGroups != NULL) {
  20105. xmlHashFree(con->substGroups, xmlSchemaSubstGroupFreeEntry);
  20106. con->substGroups = NULL;
  20107. }
  20108. if (con->redefs != NULL) {
  20109. xmlSchemaRedefListFree(con->redefs);
  20110. con->redefs = NULL;
  20111. }
  20112. return(ret);
  20113. }
  20114. /**
  20115. * xmlSchemaParse:
  20116. * @ctxt: a schema validation context
  20117. *
  20118. * parse a schema definition resource and build an internal
  20119. * XML Schema structure which can be used to validate instances.
  20120. *
  20121. * Returns the internal XML Schema structure built from the resource or
  20122. * NULL in case of error
  20123. */
  20124. xmlSchemaPtr
  20125. xmlSchemaParse(xmlSchemaParserCtxtPtr ctxt)
  20126. {
  20127. xmlSchemaPtr mainSchema = NULL;
  20128. xmlSchemaBucketPtr bucket = NULL;
  20129. int res;
  20130. /*
  20131. * This one is used if the schema to be parsed was specified via
  20132. * the API; i.e. not automatically by the validated instance document.
  20133. */
  20134. xmlSchemaInitTypes();
  20135. if (ctxt == NULL)
  20136. return (NULL);
  20137. /* TODO: Init the context. Is this all we need?*/
  20138. ctxt->nberrors = 0;
  20139. ctxt->err = 0;
  20140. ctxt->counter = 0;
  20141. /* Create the *main* schema. */
  20142. mainSchema = xmlSchemaNewSchema(ctxt);
  20143. if (mainSchema == NULL)
  20144. goto exit_failure;
  20145. /*
  20146. * Create the schema constructor.
  20147. */
  20148. if (ctxt->constructor == NULL) {
  20149. ctxt->constructor = xmlSchemaConstructionCtxtCreate(ctxt->dict);
  20150. if (ctxt->constructor == NULL)
  20151. return(NULL);
  20152. /* Take ownership of the constructor to be able to free it. */
  20153. ctxt->ownsConstructor = 1;
  20154. }
  20155. ctxt->constructor->mainSchema = mainSchema;
  20156. /*
  20157. * Locate and add the schema document.
  20158. */
  20159. res = xmlSchemaAddSchemaDoc(ctxt, XML_SCHEMA_SCHEMA_MAIN,
  20160. ctxt->URL, ctxt->doc, ctxt->buffer, ctxt->size, NULL,
  20161. NULL, NULL, &bucket);
  20162. if (res == -1)
  20163. goto exit_failure;
  20164. if (res != 0)
  20165. goto exit;
  20166. if (bucket == NULL) {
  20167. /* TODO: Error code, actually we failed to *locate* the schema. */
  20168. if (ctxt->URL)
  20169. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20170. NULL, NULL,
  20171. "Failed to locate the main schema resource at '%s'",
  20172. ctxt->URL, NULL);
  20173. else
  20174. xmlSchemaCustomErr(ACTXT_CAST ctxt, XML_SCHEMAP_FAILED_LOAD,
  20175. NULL, NULL,
  20176. "Failed to locate the main schema resource",
  20177. NULL, NULL);
  20178. goto exit;
  20179. }
  20180. /* Then do the parsing for good. */
  20181. if (xmlSchemaParseNewDocWithContext(ctxt, mainSchema, bucket) == -1)
  20182. goto exit_failure;
  20183. if (ctxt->nberrors != 0)
  20184. goto exit;
  20185. mainSchema->doc = bucket->doc;
  20186. mainSchema->preserve = ctxt->preserve;
  20187. ctxt->schema = mainSchema;
  20188. if (xmlSchemaFixupComponents(ctxt, WXS_CONSTRUCTOR(ctxt)->mainBucket) == -1)
  20189. goto exit_failure;
  20190. /*
  20191. * TODO: This is not nice, since we cannot distinguish from the
  20192. * result if there was an internal error or not.
  20193. */
  20194. exit:
  20195. if (ctxt->nberrors != 0) {
  20196. if (mainSchema) {
  20197. xmlSchemaFree(mainSchema);
  20198. mainSchema = NULL;
  20199. }
  20200. if (ctxt->constructor) {
  20201. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20202. ctxt->constructor = NULL;
  20203. ctxt->ownsConstructor = 0;
  20204. }
  20205. }
  20206. ctxt->schema = NULL;
  20207. return(mainSchema);
  20208. exit_failure:
  20209. /*
  20210. * Quite verbose, but should catch internal errors, which were
  20211. * not communicated.
  20212. */
  20213. if (mainSchema) {
  20214. xmlSchemaFree(mainSchema);
  20215. mainSchema = NULL;
  20216. }
  20217. if (ctxt->constructor) {
  20218. xmlSchemaConstructionCtxtFree(ctxt->constructor);
  20219. ctxt->constructor = NULL;
  20220. ctxt->ownsConstructor = 0;
  20221. }
  20222. PERROR_INT2("xmlSchemaParse",
  20223. "An internal error occurred");
  20224. ctxt->schema = NULL;
  20225. return(NULL);
  20226. }
  20227. /**
  20228. * xmlSchemaSetParserErrors:
  20229. * @ctxt: a schema validation context
  20230. * @err: the error callback
  20231. * @warn: the warning callback
  20232. * @ctx: contextual data for the callbacks
  20233. *
  20234. * Set the callback functions used to handle errors for a validation context
  20235. */
  20236. void
  20237. xmlSchemaSetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20238. xmlSchemaValidityErrorFunc err,
  20239. xmlSchemaValidityWarningFunc warn, void *ctx)
  20240. {
  20241. if (ctxt == NULL)
  20242. return;
  20243. ctxt->error = err;
  20244. ctxt->warning = warn;
  20245. ctxt->errCtxt = ctx;
  20246. if (ctxt->vctxt != NULL)
  20247. xmlSchemaSetValidErrors(ctxt->vctxt, err, warn, ctx);
  20248. }
  20249. /**
  20250. * xmlSchemaSetParserStructuredErrors:
  20251. * @ctxt: a schema parser context
  20252. * @serror: the structured error function
  20253. * @ctx: the functions context
  20254. *
  20255. * Set the structured error callback
  20256. */
  20257. void
  20258. xmlSchemaSetParserStructuredErrors(xmlSchemaParserCtxtPtr ctxt,
  20259. xmlStructuredErrorFunc serror,
  20260. void *ctx)
  20261. {
  20262. if (ctxt == NULL)
  20263. return;
  20264. ctxt->serror = serror;
  20265. ctxt->errCtxt = ctx;
  20266. if (ctxt->vctxt != NULL)
  20267. xmlSchemaSetValidStructuredErrors(ctxt->vctxt, serror, ctx);
  20268. }
  20269. /**
  20270. * xmlSchemaGetParserErrors:
  20271. * @ctxt: a XMl-Schema parser context
  20272. * @err: the error callback result
  20273. * @warn: the warning callback result
  20274. * @ctx: contextual data for the callbacks result
  20275. *
  20276. * Get the callback information used to handle errors for a parser context
  20277. *
  20278. * Returns -1 in case of failure, 0 otherwise
  20279. */
  20280. int
  20281. xmlSchemaGetParserErrors(xmlSchemaParserCtxtPtr ctxt,
  20282. xmlSchemaValidityErrorFunc * err,
  20283. xmlSchemaValidityWarningFunc * warn, void **ctx)
  20284. {
  20285. if (ctxt == NULL)
  20286. return(-1);
  20287. if (err != NULL)
  20288. *err = ctxt->error;
  20289. if (warn != NULL)
  20290. *warn = ctxt->warning;
  20291. if (ctx != NULL)
  20292. *ctx = ctxt->errCtxt;
  20293. return(0);
  20294. }
  20295. /**
  20296. * xmlSchemaFacetTypeToString:
  20297. * @type: the facet type
  20298. *
  20299. * Convert the xmlSchemaTypeType to a char string.
  20300. *
  20301. * Returns the char string representation of the facet type if the
  20302. * type is a facet and an "Internal Error" string otherwise.
  20303. */
  20304. static const xmlChar *
  20305. xmlSchemaFacetTypeToString(xmlSchemaTypeType type)
  20306. {
  20307. switch (type) {
  20308. case XML_SCHEMA_FACET_PATTERN:
  20309. return (BAD_CAST "pattern");
  20310. case XML_SCHEMA_FACET_MAXEXCLUSIVE:
  20311. return (BAD_CAST "maxExclusive");
  20312. case XML_SCHEMA_FACET_MAXINCLUSIVE:
  20313. return (BAD_CAST "maxInclusive");
  20314. case XML_SCHEMA_FACET_MINEXCLUSIVE:
  20315. return (BAD_CAST "minExclusive");
  20316. case XML_SCHEMA_FACET_MININCLUSIVE:
  20317. return (BAD_CAST "minInclusive");
  20318. case XML_SCHEMA_FACET_WHITESPACE:
  20319. return (BAD_CAST "whiteSpace");
  20320. case XML_SCHEMA_FACET_ENUMERATION:
  20321. return (BAD_CAST "enumeration");
  20322. case XML_SCHEMA_FACET_LENGTH:
  20323. return (BAD_CAST "length");
  20324. case XML_SCHEMA_FACET_MAXLENGTH:
  20325. return (BAD_CAST "maxLength");
  20326. case XML_SCHEMA_FACET_MINLENGTH:
  20327. return (BAD_CAST "minLength");
  20328. case XML_SCHEMA_FACET_TOTALDIGITS:
  20329. return (BAD_CAST "totalDigits");
  20330. case XML_SCHEMA_FACET_FRACTIONDIGITS:
  20331. return (BAD_CAST "fractionDigits");
  20332. default:
  20333. break;
  20334. }
  20335. return (BAD_CAST "Internal Error");
  20336. }
  20337. static xmlSchemaWhitespaceValueType
  20338. xmlSchemaGetWhiteSpaceFacetValue(xmlSchemaTypePtr type)
  20339. {
  20340. /*
  20341. * The normalization type can be changed only for types which are derived
  20342. * from xsd:string.
  20343. */
  20344. if (type->type == XML_SCHEMA_TYPE_BASIC) {
  20345. /*
  20346. * Note that we assume a whitespace of preserve for anySimpleType.
  20347. */
  20348. if ((type->builtInType == XML_SCHEMAS_STRING) ||
  20349. (type->builtInType == XML_SCHEMAS_ANYSIMPLETYPE))
  20350. return(XML_SCHEMA_WHITESPACE_PRESERVE);
  20351. else if (type->builtInType == XML_SCHEMAS_NORMSTRING)
  20352. return(XML_SCHEMA_WHITESPACE_REPLACE);
  20353. else {
  20354. /*
  20355. * For all `atomic` datatypes other than string (and types `derived`
  20356. * by `restriction` from it) the value of whiteSpace is fixed to
  20357. * collapse
  20358. * Note that this includes built-in list datatypes.
  20359. */
  20360. return(XML_SCHEMA_WHITESPACE_COLLAPSE);
  20361. }
  20362. } else if (WXS_IS_LIST(type)) {
  20363. /*
  20364. * For list types the facet "whiteSpace" is fixed to "collapse".
  20365. */
  20366. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20367. } else if (WXS_IS_UNION(type)) {
  20368. return (XML_SCHEMA_WHITESPACE_UNKNOWN);
  20369. } else if (WXS_IS_ATOMIC(type)) {
  20370. if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_PRESERVE)
  20371. return (XML_SCHEMA_WHITESPACE_PRESERVE);
  20372. else if (type->flags & XML_SCHEMAS_TYPE_WHITESPACE_REPLACE)
  20373. return (XML_SCHEMA_WHITESPACE_REPLACE);
  20374. else
  20375. return (XML_SCHEMA_WHITESPACE_COLLAPSE);
  20376. }
  20377. return (-1);
  20378. }
  20379. /************************************************************************
  20380. * *
  20381. * Simple type validation *
  20382. * *
  20383. ************************************************************************/
  20384. /************************************************************************
  20385. * *
  20386. * DOM Validation code *
  20387. * *
  20388. ************************************************************************/
  20389. /**
  20390. * xmlSchemaAssembleByLocation:
  20391. * @pctxt: a schema parser context
  20392. * @vctxt: a schema validation context
  20393. * @schema: the existing schema
  20394. * @node: the node that fired the assembling
  20395. * @nsName: the namespace name of the new schema
  20396. * @location: the location of the schema
  20397. *
  20398. * Expands an existing schema by an additional schema.
  20399. *
  20400. * Returns 0 if the new schema is correct, a positive error code
  20401. * number otherwise and -1 in case of an internal or API error.
  20402. */
  20403. static int
  20404. xmlSchemaAssembleByLocation(xmlSchemaValidCtxtPtr vctxt,
  20405. xmlSchemaPtr schema,
  20406. xmlNodePtr node,
  20407. const xmlChar *nsName,
  20408. const xmlChar *location)
  20409. {
  20410. int ret = 0;
  20411. xmlSchemaParserCtxtPtr pctxt;
  20412. xmlSchemaBucketPtr bucket = NULL;
  20413. if ((vctxt == NULL) || (schema == NULL))
  20414. return (-1);
  20415. if (vctxt->pctxt == NULL) {
  20416. VERROR_INT("xmlSchemaAssembleByLocation",
  20417. "no parser context available");
  20418. return(-1);
  20419. }
  20420. pctxt = vctxt->pctxt;
  20421. if (pctxt->constructor == NULL) {
  20422. PERROR_INT("xmlSchemaAssembleByLocation",
  20423. "no constructor");
  20424. return(-1);
  20425. }
  20426. /*
  20427. * Acquire the schema document.
  20428. */
  20429. location = xmlSchemaBuildAbsoluteURI(pctxt->dict,
  20430. location, node);
  20431. /*
  20432. * Note that we pass XML_SCHEMA_SCHEMA_IMPORT here;
  20433. * the process will automatically change this to
  20434. * XML_SCHEMA_SCHEMA_MAIN if it is the first schema document.
  20435. */
  20436. ret = xmlSchemaAddSchemaDoc(pctxt, XML_SCHEMA_SCHEMA_IMPORT,
  20437. location, NULL, NULL, 0, node, NULL, nsName,
  20438. &bucket);
  20439. if (ret != 0)
  20440. return(ret);
  20441. if (bucket == NULL) {
  20442. /*
  20443. * Generate a warning that the document could not be located.
  20444. */
  20445. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20446. node, NULL,
  20447. "The document at location '%s' could not be acquired",
  20448. location, NULL, NULL);
  20449. return(ret);
  20450. }
  20451. /*
  20452. * The first located schema will be handled as if all other
  20453. * schemas imported by XSI were imported by this first schema.
  20454. */
  20455. if ((bucket != NULL) &&
  20456. (WXS_CONSTRUCTOR(pctxt)->bucket == NULL))
  20457. WXS_CONSTRUCTOR(pctxt)->bucket = bucket;
  20458. /*
  20459. * TODO: Is this handled like an import? I.e. is it not an error
  20460. * if the schema cannot be located?
  20461. */
  20462. if ((bucket == NULL) || (! CAN_PARSE_SCHEMA(bucket)))
  20463. return(0);
  20464. /*
  20465. * We will reuse the parser context for every schema imported
  20466. * directly via XSI. So reset the context.
  20467. */
  20468. pctxt->nberrors = 0;
  20469. pctxt->err = 0;
  20470. pctxt->doc = bucket->doc;
  20471. ret = xmlSchemaParseNewDocWithContext(pctxt, schema, bucket);
  20472. if (ret == -1) {
  20473. pctxt->doc = NULL;
  20474. goto exit_failure;
  20475. }
  20476. /* Paranoid error channelling. */
  20477. if ((ret == 0) && (pctxt->nberrors != 0))
  20478. ret = pctxt->err;
  20479. if (pctxt->nberrors == 0) {
  20480. /*
  20481. * Only bother to fixup pending components, if there was
  20482. * no error yet.
  20483. * For every XSI acquired schema (and its sub-schemata) we will
  20484. * fixup the components.
  20485. */
  20486. xmlSchemaFixupComponents(pctxt, bucket);
  20487. ret = pctxt->err;
  20488. /*
  20489. * Not nice, but we need somehow to channel the schema parser
  20490. * error to the validation context.
  20491. */
  20492. if ((ret != 0) && (vctxt->err == 0))
  20493. vctxt->err = ret;
  20494. vctxt->nberrors += pctxt->nberrors;
  20495. } else {
  20496. /* Add to validation error sum. */
  20497. vctxt->nberrors += pctxt->nberrors;
  20498. }
  20499. pctxt->doc = NULL;
  20500. return(ret);
  20501. exit_failure:
  20502. pctxt->doc = NULL;
  20503. return (-1);
  20504. }
  20505. static xmlSchemaAttrInfoPtr
  20506. xmlSchemaGetMetaAttrInfo(xmlSchemaValidCtxtPtr vctxt,
  20507. int metaType)
  20508. {
  20509. if (vctxt->nbAttrInfos == 0)
  20510. return (NULL);
  20511. {
  20512. int i;
  20513. xmlSchemaAttrInfoPtr iattr;
  20514. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  20515. iattr = vctxt->attrInfos[i];
  20516. if (iattr->metaType == metaType)
  20517. return (iattr);
  20518. }
  20519. }
  20520. return (NULL);
  20521. }
  20522. /**
  20523. * xmlSchemaAssembleByXSI:
  20524. * @vctxt: a schema validation context
  20525. *
  20526. * Expands an existing schema by an additional schema using
  20527. * the xsi:schemaLocation or xsi:noNamespaceSchemaLocation attribute
  20528. * of an instance. If xsi:noNamespaceSchemaLocation is used, @noNamespace
  20529. * must be set to 1.
  20530. *
  20531. * Returns 0 if the new schema is correct, a positive error code
  20532. * number otherwise and -1 in case of an internal or API error.
  20533. */
  20534. static int
  20535. xmlSchemaAssembleByXSI(xmlSchemaValidCtxtPtr vctxt)
  20536. {
  20537. const xmlChar *cur, *end;
  20538. const xmlChar *nsname = NULL, *location;
  20539. int count = 0;
  20540. int ret = 0;
  20541. xmlSchemaAttrInfoPtr iattr;
  20542. /*
  20543. * Parse the value; we will assume an even number of values
  20544. * to be given (this is how Xerces and XSV work).
  20545. *
  20546. * URGENT TODO: !! This needs to work for both
  20547. * @noNamespaceSchemaLocation AND @schemaLocation on the same
  20548. * element !!
  20549. */
  20550. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20551. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC);
  20552. if (iattr == NULL)
  20553. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  20554. XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC);
  20555. if (iattr == NULL)
  20556. return (0);
  20557. cur = iattr->value;
  20558. do {
  20559. /*
  20560. * TODO: Move the string parsing mechanism away from here.
  20561. */
  20562. if (iattr->metaType == XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC) {
  20563. /*
  20564. * Get the namespace name.
  20565. */
  20566. while (IS_BLANK_CH(*cur))
  20567. cur++;
  20568. end = cur;
  20569. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20570. end++;
  20571. if (end == cur)
  20572. break;
  20573. count++; /* TODO: Don't use the schema's dict. */
  20574. nsname = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20575. cur = end;
  20576. }
  20577. /*
  20578. * Get the URI.
  20579. */
  20580. while (IS_BLANK_CH(*cur))
  20581. cur++;
  20582. end = cur;
  20583. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  20584. end++;
  20585. if (end == cur) {
  20586. if (iattr->metaType ==
  20587. XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC)
  20588. {
  20589. /*
  20590. * If using @schemaLocation then tuples are expected.
  20591. * I.e. the namespace name *and* the document's URI.
  20592. */
  20593. xmlSchemaCustomWarning(ACTXT_CAST vctxt, XML_SCHEMAV_MISC,
  20594. iattr->node, NULL,
  20595. "The value must consist of tuples: the target namespace "
  20596. "name and the document's URI", NULL, NULL, NULL);
  20597. }
  20598. break;
  20599. }
  20600. count++; /* TODO: Don't use the schema's dict. */
  20601. location = xmlDictLookup(vctxt->schema->dict, cur, end - cur);
  20602. cur = end;
  20603. ret = xmlSchemaAssembleByLocation(vctxt, vctxt->schema,
  20604. iattr->node, nsname, location);
  20605. if (ret == -1) {
  20606. VERROR_INT("xmlSchemaAssembleByXSI",
  20607. "assembling schemata");
  20608. return (-1);
  20609. }
  20610. } while (*cur != 0);
  20611. return (ret);
  20612. }
  20613. static const xmlChar *
  20614. xmlSchemaLookupNamespace(xmlSchemaValidCtxtPtr vctxt,
  20615. const xmlChar *prefix)
  20616. {
  20617. if (vctxt->sax != NULL) {
  20618. int i, j;
  20619. xmlSchemaNodeInfoPtr inode;
  20620. for (i = vctxt->depth; i >= 0; i--) {
  20621. if (vctxt->elemInfos[i]->nbNsBindings != 0) {
  20622. inode = vctxt->elemInfos[i];
  20623. for (j = 0; j < inode->nbNsBindings * 2; j += 2) {
  20624. if (((prefix == NULL) &&
  20625. (inode->nsBindings[j] == NULL)) ||
  20626. ((prefix != NULL) && xmlStrEqual(prefix,
  20627. inode->nsBindings[j]))) {
  20628. /*
  20629. * Note that the namespace bindings are already
  20630. * in a string dict.
  20631. */
  20632. return (inode->nsBindings[j+1]);
  20633. }
  20634. }
  20635. }
  20636. }
  20637. return (NULL);
  20638. #ifdef LIBXML_READER_ENABLED
  20639. } else if (vctxt->reader != NULL) {
  20640. xmlChar *nsName;
  20641. nsName = xmlTextReaderLookupNamespace(vctxt->reader, prefix);
  20642. if (nsName != NULL) {
  20643. const xmlChar *ret;
  20644. ret = xmlDictLookup(vctxt->dict, nsName, -1);
  20645. xmlFree(nsName);
  20646. return (ret);
  20647. } else
  20648. return (NULL);
  20649. #endif
  20650. } else {
  20651. xmlNsPtr ns;
  20652. if ((vctxt->inode->node == NULL) ||
  20653. (vctxt->inode->node->doc == NULL)) {
  20654. VERROR_INT("xmlSchemaLookupNamespace",
  20655. "no node or node's doc available");
  20656. return (NULL);
  20657. }
  20658. ns = xmlSearchNs(vctxt->inode->node->doc,
  20659. vctxt->inode->node, prefix);
  20660. if (ns != NULL)
  20661. return (ns->href);
  20662. return (NULL);
  20663. }
  20664. }
  20665. /*
  20666. * This one works on the schema of the validation context.
  20667. */
  20668. static int
  20669. xmlSchemaValidateNotation(xmlSchemaValidCtxtPtr vctxt,
  20670. xmlSchemaPtr schema,
  20671. xmlNodePtr node,
  20672. const xmlChar *value,
  20673. xmlSchemaValPtr *val,
  20674. int valNeeded)
  20675. {
  20676. int ret;
  20677. if (vctxt && (vctxt->schema == NULL)) {
  20678. VERROR_INT("xmlSchemaValidateNotation",
  20679. "a schema is needed on the validation context");
  20680. return (-1);
  20681. }
  20682. ret = xmlValidateQName(value, 1);
  20683. if (ret != 0)
  20684. return (ret);
  20685. {
  20686. xmlChar *localName = NULL;
  20687. xmlChar *prefix = NULL;
  20688. localName = xmlSplitQName2(value, &prefix);
  20689. if (prefix != NULL) {
  20690. const xmlChar *nsName = NULL;
  20691. if (vctxt != NULL)
  20692. nsName = xmlSchemaLookupNamespace(vctxt, BAD_CAST prefix);
  20693. else if (node != NULL) {
  20694. xmlNsPtr ns = xmlSearchNs(node->doc, node, prefix);
  20695. if (ns != NULL)
  20696. nsName = ns->href;
  20697. } else {
  20698. xmlFree(prefix);
  20699. xmlFree(localName);
  20700. return (1);
  20701. }
  20702. if (nsName == NULL) {
  20703. xmlFree(prefix);
  20704. xmlFree(localName);
  20705. return (1);
  20706. }
  20707. if (xmlSchemaGetNotation(schema, localName, nsName) != NULL) {
  20708. if ((valNeeded) && (val != NULL)) {
  20709. (*val) = xmlSchemaNewNOTATIONValue(xmlStrdup(localName),
  20710. xmlStrdup(nsName));
  20711. if (*val == NULL)
  20712. ret = -1;
  20713. }
  20714. } else
  20715. ret = 1;
  20716. xmlFree(prefix);
  20717. xmlFree(localName);
  20718. } else {
  20719. if (xmlSchemaGetNotation(schema, value, NULL) != NULL) {
  20720. if (valNeeded && (val != NULL)) {
  20721. (*val) = xmlSchemaNewNOTATIONValue(
  20722. BAD_CAST xmlStrdup(value), NULL);
  20723. if (*val == NULL)
  20724. ret = -1;
  20725. }
  20726. } else
  20727. return (1);
  20728. }
  20729. }
  20730. return (ret);
  20731. }
  20732. static int
  20733. xmlSchemaVAddNodeQName(xmlSchemaValidCtxtPtr vctxt,
  20734. const xmlChar* lname,
  20735. const xmlChar* nsname)
  20736. {
  20737. int i;
  20738. lname = xmlDictLookup(vctxt->dict, lname, -1);
  20739. if (lname == NULL)
  20740. return(-1);
  20741. if (nsname != NULL) {
  20742. nsname = xmlDictLookup(vctxt->dict, nsname, -1);
  20743. if (nsname == NULL)
  20744. return(-1);
  20745. }
  20746. for (i = 0; i < vctxt->nodeQNames->nbItems; i += 2) {
  20747. if ((vctxt->nodeQNames->items [i] == lname) &&
  20748. (vctxt->nodeQNames->items[i +1] == nsname))
  20749. /* Already there */
  20750. return(i);
  20751. }
  20752. /* Add new entry. */
  20753. i = vctxt->nodeQNames->nbItems;
  20754. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) lname);
  20755. xmlSchemaItemListAdd(vctxt->nodeQNames, (void *) nsname);
  20756. return(i);
  20757. }
  20758. /************************************************************************
  20759. * *
  20760. * Validation of identity-constraints (IDC) *
  20761. * *
  20762. ************************************************************************/
  20763. /**
  20764. * xmlSchemaAugmentIDC:
  20765. * @idcDef: the IDC definition
  20766. *
  20767. * Creates an augmented IDC definition item.
  20768. *
  20769. * Returns the item, or NULL on internal errors.
  20770. */
  20771. static void
  20772. xmlSchemaAugmentIDC(void *payload, void *data,
  20773. const xmlChar *name ATTRIBUTE_UNUSED)
  20774. {
  20775. xmlSchemaIDCPtr idcDef = (xmlSchemaIDCPtr) payload;
  20776. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20777. xmlSchemaIDCAugPtr aidc;
  20778. aidc = (xmlSchemaIDCAugPtr) xmlMalloc(sizeof(xmlSchemaIDCAug));
  20779. if (aidc == NULL) {
  20780. xmlSchemaVErrMemory(vctxt,
  20781. "xmlSchemaAugmentIDC: allocating an augmented IDC definition",
  20782. NULL);
  20783. return;
  20784. }
  20785. aidc->keyrefDepth = -1;
  20786. aidc->def = idcDef;
  20787. aidc->next = NULL;
  20788. if (vctxt->aidcs == NULL)
  20789. vctxt->aidcs = aidc;
  20790. else {
  20791. aidc->next = vctxt->aidcs;
  20792. vctxt->aidcs = aidc;
  20793. }
  20794. /*
  20795. * Save if we have keyrefs at all.
  20796. */
  20797. if ((vctxt->hasKeyrefs == 0) &&
  20798. (idcDef->type == XML_SCHEMA_TYPE_IDC_KEYREF))
  20799. vctxt->hasKeyrefs = 1;
  20800. }
  20801. /**
  20802. * xmlSchemaAugmentImportedIDC:
  20803. * @imported: the imported schema
  20804. *
  20805. * Creates an augmented IDC definition for the imported schema.
  20806. */
  20807. static void
  20808. xmlSchemaAugmentImportedIDC(void *payload, void *data,
  20809. const xmlChar *name ATTRIBUTE_UNUSED) {
  20810. xmlSchemaImportPtr imported = (xmlSchemaImportPtr) payload;
  20811. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) data;
  20812. if (imported->schema->idcDef != NULL) {
  20813. xmlHashScan(imported->schema->idcDef, xmlSchemaAugmentIDC, vctxt);
  20814. }
  20815. }
  20816. /**
  20817. * xmlSchemaIDCNewBinding:
  20818. * @idcDef: the IDC definition of this binding
  20819. *
  20820. * Creates a new IDC binding.
  20821. *
  20822. * Returns the new IDC binding, NULL on internal errors.
  20823. */
  20824. static xmlSchemaPSVIIDCBindingPtr
  20825. xmlSchemaIDCNewBinding(xmlSchemaIDCPtr idcDef)
  20826. {
  20827. xmlSchemaPSVIIDCBindingPtr ret;
  20828. ret = (xmlSchemaPSVIIDCBindingPtr) xmlMalloc(
  20829. sizeof(xmlSchemaPSVIIDCBinding));
  20830. if (ret == NULL) {
  20831. xmlSchemaVErrMemory(NULL,
  20832. "allocating a PSVI IDC binding item", NULL);
  20833. return (NULL);
  20834. }
  20835. memset(ret, 0, sizeof(xmlSchemaPSVIIDCBinding));
  20836. ret->definition = idcDef;
  20837. return (ret);
  20838. }
  20839. /**
  20840. * xmlSchemaIDCStoreNodeTableItem:
  20841. * @vctxt: the WXS validation context
  20842. * @item: the IDC node table item
  20843. *
  20844. * The validation context is used to store IDC node table items.
  20845. * They are stored to avoid copying them if IDC node-tables are merged
  20846. * with corresponding parent IDC node-tables (bubbling).
  20847. *
  20848. * Returns 0 if succeeded, -1 on internal errors.
  20849. */
  20850. static int
  20851. xmlSchemaIDCStoreNodeTableItem(xmlSchemaValidCtxtPtr vctxt,
  20852. xmlSchemaPSVIIDCNodePtr item)
  20853. {
  20854. /*
  20855. * Add to global list.
  20856. */
  20857. if (vctxt->idcNodes == NULL) {
  20858. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20859. xmlMalloc(20 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20860. if (vctxt->idcNodes == NULL) {
  20861. xmlSchemaVErrMemory(vctxt,
  20862. "allocating the IDC node table item list", NULL);
  20863. return (-1);
  20864. }
  20865. vctxt->sizeIdcNodes = 20;
  20866. } else if (vctxt->sizeIdcNodes <= vctxt->nbIdcNodes) {
  20867. vctxt->sizeIdcNodes *= 2;
  20868. vctxt->idcNodes = (xmlSchemaPSVIIDCNodePtr *)
  20869. xmlRealloc(vctxt->idcNodes, vctxt->sizeIdcNodes *
  20870. sizeof(xmlSchemaPSVIIDCNodePtr));
  20871. if (vctxt->idcNodes == NULL) {
  20872. xmlSchemaVErrMemory(vctxt,
  20873. "re-allocating the IDC node table item list", NULL);
  20874. return (-1);
  20875. }
  20876. }
  20877. vctxt->idcNodes[vctxt->nbIdcNodes++] = item;
  20878. return (0);
  20879. }
  20880. /**
  20881. * xmlSchemaIDCStoreKey:
  20882. * @vctxt: the WXS validation context
  20883. * @item: the IDC key
  20884. *
  20885. * The validation context is used to store an IDC key.
  20886. *
  20887. * Returns 0 if succeeded, -1 on internal errors.
  20888. */
  20889. static int
  20890. xmlSchemaIDCStoreKey(xmlSchemaValidCtxtPtr vctxt,
  20891. xmlSchemaPSVIIDCKeyPtr key)
  20892. {
  20893. /*
  20894. * Add to global list.
  20895. */
  20896. if (vctxt->idcKeys == NULL) {
  20897. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20898. xmlMalloc(40 * sizeof(xmlSchemaPSVIIDCKeyPtr));
  20899. if (vctxt->idcKeys == NULL) {
  20900. xmlSchemaVErrMemory(vctxt,
  20901. "allocating the IDC key storage list", NULL);
  20902. return (-1);
  20903. }
  20904. vctxt->sizeIdcKeys = 40;
  20905. } else if (vctxt->sizeIdcKeys <= vctxt->nbIdcKeys) {
  20906. vctxt->sizeIdcKeys *= 2;
  20907. vctxt->idcKeys = (xmlSchemaPSVIIDCKeyPtr *)
  20908. xmlRealloc(vctxt->idcKeys, vctxt->sizeIdcKeys *
  20909. sizeof(xmlSchemaPSVIIDCKeyPtr));
  20910. if (vctxt->idcKeys == NULL) {
  20911. xmlSchemaVErrMemory(vctxt,
  20912. "re-allocating the IDC key storage list", NULL);
  20913. return (-1);
  20914. }
  20915. }
  20916. vctxt->idcKeys[vctxt->nbIdcKeys++] = key;
  20917. return (0);
  20918. }
  20919. /**
  20920. * xmlSchemaIDCAppendNodeTableItem:
  20921. * @bind: the IDC binding
  20922. * @ntItem: the node-table item
  20923. *
  20924. * Appends the IDC node-table item to the binding.
  20925. *
  20926. * Returns 0 on success and -1 on internal errors.
  20927. */
  20928. static int
  20929. xmlSchemaIDCAppendNodeTableItem(xmlSchemaPSVIIDCBindingPtr bind,
  20930. xmlSchemaPSVIIDCNodePtr ntItem)
  20931. {
  20932. if (bind->nodeTable == NULL) {
  20933. bind->sizeNodes = 10;
  20934. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  20935. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  20936. if (bind->nodeTable == NULL) {
  20937. xmlSchemaVErrMemory(NULL,
  20938. "allocating an array of IDC node-table items", NULL);
  20939. return(-1);
  20940. }
  20941. } else if (bind->sizeNodes <= bind->nbNodes) {
  20942. bind->sizeNodes *= 2;
  20943. bind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  20944. xmlRealloc(bind->nodeTable, bind->sizeNodes *
  20945. sizeof(xmlSchemaPSVIIDCNodePtr));
  20946. if (bind->nodeTable == NULL) {
  20947. xmlSchemaVErrMemory(NULL,
  20948. "re-allocating an array of IDC node-table items", NULL);
  20949. return(-1);
  20950. }
  20951. }
  20952. bind->nodeTable[bind->nbNodes++] = ntItem;
  20953. return(0);
  20954. }
  20955. /**
  20956. * xmlSchemaIDCAcquireBinding:
  20957. * @vctxt: the WXS validation context
  20958. * @matcher: the IDC matcher
  20959. *
  20960. * Looks up an PSVI IDC binding, for the IDC definition and
  20961. * of the given matcher. If none found, a new one is created
  20962. * and added to the IDC table.
  20963. *
  20964. * Returns an IDC binding or NULL on internal errors.
  20965. */
  20966. static xmlSchemaPSVIIDCBindingPtr
  20967. xmlSchemaIDCAcquireBinding(xmlSchemaValidCtxtPtr vctxt,
  20968. xmlSchemaIDCMatcherPtr matcher)
  20969. {
  20970. xmlSchemaNodeInfoPtr ielem;
  20971. ielem = vctxt->elemInfos[matcher->depth];
  20972. if (ielem->idcTable == NULL) {
  20973. ielem->idcTable = xmlSchemaIDCNewBinding(matcher->aidc->def);
  20974. if (ielem->idcTable == NULL)
  20975. return (NULL);
  20976. return(ielem->idcTable);
  20977. } else {
  20978. xmlSchemaPSVIIDCBindingPtr bind = NULL;
  20979. bind = ielem->idcTable;
  20980. do {
  20981. if (bind->definition == matcher->aidc->def)
  20982. return(bind);
  20983. if (bind->next == NULL) {
  20984. bind->next = xmlSchemaIDCNewBinding(matcher->aidc->def);
  20985. if (bind->next == NULL)
  20986. return (NULL);
  20987. return(bind->next);
  20988. }
  20989. bind = bind->next;
  20990. } while (bind != NULL);
  20991. }
  20992. return (NULL);
  20993. }
  20994. static xmlSchemaItemListPtr
  20995. xmlSchemaIDCAcquireTargetList(xmlSchemaValidCtxtPtr vctxt ATTRIBUTE_UNUSED,
  20996. xmlSchemaIDCMatcherPtr matcher)
  20997. {
  20998. if (matcher->targets == NULL)
  20999. matcher->targets = xmlSchemaItemListCreate();
  21000. return(matcher->targets);
  21001. }
  21002. /**
  21003. * xmlSchemaIDCFreeKey:
  21004. * @key: the IDC key
  21005. *
  21006. * Frees an IDC key together with its compiled value.
  21007. */
  21008. static void
  21009. xmlSchemaIDCFreeKey(xmlSchemaPSVIIDCKeyPtr key)
  21010. {
  21011. if (key->val != NULL)
  21012. xmlSchemaFreeValue(key->val);
  21013. xmlFree(key);
  21014. }
  21015. /**
  21016. * xmlSchemaIDCFreeBinding:
  21017. *
  21018. * Frees an IDC binding. Note that the node table-items
  21019. * are not freed.
  21020. */
  21021. static void
  21022. xmlSchemaIDCFreeBinding(xmlSchemaPSVIIDCBindingPtr bind)
  21023. {
  21024. if (bind->nodeTable != NULL)
  21025. xmlFree(bind->nodeTable);
  21026. if (bind->dupls != NULL)
  21027. xmlSchemaItemListFree(bind->dupls);
  21028. xmlFree(bind);
  21029. }
  21030. /**
  21031. * xmlSchemaIDCFreeIDCTable:
  21032. * @bind: the first IDC binding in the list
  21033. *
  21034. * Frees an IDC table, i.e. all the IDC bindings in the list.
  21035. */
  21036. static void
  21037. xmlSchemaIDCFreeIDCTable(xmlSchemaPSVIIDCBindingPtr bind)
  21038. {
  21039. xmlSchemaPSVIIDCBindingPtr prev;
  21040. while (bind != NULL) {
  21041. prev = bind;
  21042. bind = bind->next;
  21043. xmlSchemaIDCFreeBinding(prev);
  21044. }
  21045. }
  21046. /**
  21047. * xmlSchemaIDCFreeMatcherList:
  21048. * @matcher: the first IDC matcher in the list
  21049. *
  21050. * Frees a list of IDC matchers.
  21051. */
  21052. static void
  21053. xmlSchemaIDCFreeMatcherList(xmlSchemaIDCMatcherPtr matcher)
  21054. {
  21055. xmlSchemaIDCMatcherPtr next;
  21056. while (matcher != NULL) {
  21057. next = matcher->next;
  21058. if (matcher->keySeqs != NULL) {
  21059. int i;
  21060. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21061. if (matcher->keySeqs[i] != NULL)
  21062. xmlFree(matcher->keySeqs[i]);
  21063. xmlFree(matcher->keySeqs);
  21064. }
  21065. if (matcher->targets != NULL) {
  21066. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21067. int i;
  21068. xmlSchemaPSVIIDCNodePtr idcNode;
  21069. /*
  21070. * Node-table items for keyrefs are not stored globally
  21071. * to the validation context, since they are not bubbled.
  21072. * We need to free them here.
  21073. */
  21074. for (i = 0; i < matcher->targets->nbItems; i++) {
  21075. idcNode =
  21076. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21077. xmlFree(idcNode->keys);
  21078. xmlFree(idcNode);
  21079. }
  21080. }
  21081. xmlSchemaItemListFree(matcher->targets);
  21082. }
  21083. xmlFree(matcher);
  21084. matcher = next;
  21085. }
  21086. }
  21087. /**
  21088. * xmlSchemaIDCReleaseMatcherList:
  21089. * @vctxt: the WXS validation context
  21090. * @matcher: the first IDC matcher in the list
  21091. *
  21092. * Caches a list of IDC matchers for reuse.
  21093. */
  21094. static void
  21095. xmlSchemaIDCReleaseMatcherList(xmlSchemaValidCtxtPtr vctxt,
  21096. xmlSchemaIDCMatcherPtr matcher)
  21097. {
  21098. xmlSchemaIDCMatcherPtr next;
  21099. while (matcher != NULL) {
  21100. next = matcher->next;
  21101. if (matcher->keySeqs != NULL) {
  21102. int i;
  21103. /*
  21104. * Don't free the array, but only the content.
  21105. */
  21106. for (i = 0; i < matcher->sizeKeySeqs; i++)
  21107. if (matcher->keySeqs[i] != NULL) {
  21108. xmlFree(matcher->keySeqs[i]);
  21109. matcher->keySeqs[i] = NULL;
  21110. }
  21111. }
  21112. if (matcher->targets) {
  21113. if (matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21114. int i;
  21115. xmlSchemaPSVIIDCNodePtr idcNode;
  21116. /*
  21117. * Node-table items for keyrefs are not stored globally
  21118. * to the validation context, since they are not bubbled.
  21119. * We need to free them here.
  21120. */
  21121. for (i = 0; i < matcher->targets->nbItems; i++) {
  21122. idcNode =
  21123. (xmlSchemaPSVIIDCNodePtr) matcher->targets->items[i];
  21124. xmlFree(idcNode->keys);
  21125. xmlFree(idcNode);
  21126. }
  21127. }
  21128. xmlSchemaItemListFree(matcher->targets);
  21129. matcher->targets = NULL;
  21130. }
  21131. matcher->next = NULL;
  21132. /*
  21133. * Cache the matcher.
  21134. */
  21135. if (vctxt->idcMatcherCache != NULL)
  21136. matcher->nextCached = vctxt->idcMatcherCache;
  21137. vctxt->idcMatcherCache = matcher;
  21138. matcher = next;
  21139. }
  21140. }
  21141. /**
  21142. * xmlSchemaIDCAddStateObject:
  21143. * @vctxt: the WXS validation context
  21144. * @matcher: the IDC matcher
  21145. * @sel: the XPath information
  21146. * @parent: the parent "selector" state object if any
  21147. * @type: "selector" or "field"
  21148. *
  21149. * Creates/reuses and activates state objects for the given
  21150. * XPath information; if the XPath expression consists of unions,
  21151. * multiple state objects are created for every unioned expression.
  21152. *
  21153. * Returns 0 on success and -1 on internal errors.
  21154. */
  21155. static int
  21156. xmlSchemaIDCAddStateObject(xmlSchemaValidCtxtPtr vctxt,
  21157. xmlSchemaIDCMatcherPtr matcher,
  21158. xmlSchemaIDCSelectPtr sel,
  21159. int type)
  21160. {
  21161. xmlSchemaIDCStateObjPtr sto;
  21162. /*
  21163. * Reuse the state objects from the pool.
  21164. */
  21165. if (vctxt->xpathStatePool != NULL) {
  21166. sto = vctxt->xpathStatePool;
  21167. vctxt->xpathStatePool = sto->next;
  21168. sto->next = NULL;
  21169. } else {
  21170. /*
  21171. * Create a new state object.
  21172. */
  21173. sto = (xmlSchemaIDCStateObjPtr) xmlMalloc(sizeof(xmlSchemaIDCStateObj));
  21174. if (sto == NULL) {
  21175. xmlSchemaVErrMemory(NULL,
  21176. "allocating an IDC state object", NULL);
  21177. return (-1);
  21178. }
  21179. memset(sto, 0, sizeof(xmlSchemaIDCStateObj));
  21180. }
  21181. /*
  21182. * Add to global list.
  21183. */
  21184. if (vctxt->xpathStates != NULL)
  21185. sto->next = vctxt->xpathStates;
  21186. vctxt->xpathStates = sto;
  21187. /*
  21188. * Free the old xpath validation context.
  21189. */
  21190. if (sto->xpathCtxt != NULL)
  21191. xmlFreeStreamCtxt((xmlStreamCtxtPtr) sto->xpathCtxt);
  21192. /*
  21193. * Create a new XPath (pattern) validation context.
  21194. */
  21195. sto->xpathCtxt = (void *) xmlPatternGetStreamCtxt(
  21196. (xmlPatternPtr) sel->xpathComp);
  21197. if (sto->xpathCtxt == NULL) {
  21198. VERROR_INT("xmlSchemaIDCAddStateObject",
  21199. "failed to create an XPath validation context");
  21200. return (-1);
  21201. }
  21202. sto->type = type;
  21203. sto->depth = vctxt->depth;
  21204. sto->matcher = matcher;
  21205. sto->sel = sel;
  21206. sto->nbHistory = 0;
  21207. #ifdef DEBUG_IDC
  21208. xmlGenericError(xmlGenericErrorContext, "IDC: STO push '%s'\n",
  21209. sto->sel->xpath);
  21210. #endif
  21211. return (0);
  21212. }
  21213. /**
  21214. * xmlSchemaXPathEvaluate:
  21215. * @vctxt: the WXS validation context
  21216. * @nodeType: the nodeType of the current node
  21217. *
  21218. * Evaluates all active XPath state objects.
  21219. *
  21220. * Returns the number of IC "field" state objects which resolved to
  21221. * this node, 0 if none resolved and -1 on internal errors.
  21222. */
  21223. static int
  21224. xmlSchemaXPathEvaluate(xmlSchemaValidCtxtPtr vctxt,
  21225. xmlElementType nodeType)
  21226. {
  21227. xmlSchemaIDCStateObjPtr sto, head = NULL, first;
  21228. int res, resolved = 0, depth = vctxt->depth;
  21229. if (vctxt->xpathStates == NULL)
  21230. return (0);
  21231. if (nodeType == XML_ATTRIBUTE_NODE)
  21232. depth++;
  21233. #ifdef DEBUG_IDC
  21234. {
  21235. xmlChar *str = NULL;
  21236. xmlGenericError(xmlGenericErrorContext,
  21237. "IDC: EVAL on %s, depth %d, type %d\n",
  21238. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21239. vctxt->inode->localName), depth, nodeType);
  21240. FREE_AND_NULL(str)
  21241. }
  21242. #endif
  21243. /*
  21244. * Process all active XPath state objects.
  21245. */
  21246. first = vctxt->xpathStates;
  21247. sto = first;
  21248. while (sto != head) {
  21249. #ifdef DEBUG_IDC
  21250. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR)
  21251. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] selector '%s'\n",
  21252. sto->matcher->aidc->def->name, sto->sel->xpath);
  21253. else
  21254. xmlGenericError(xmlGenericErrorContext, "IDC: ['%s'] field '%s'\n",
  21255. sto->matcher->aidc->def->name, sto->sel->xpath);
  21256. #endif
  21257. if (nodeType == XML_ELEMENT_NODE)
  21258. res = xmlStreamPush((xmlStreamCtxtPtr) sto->xpathCtxt,
  21259. vctxt->inode->localName, vctxt->inode->nsName);
  21260. else
  21261. res = xmlStreamPushAttr((xmlStreamCtxtPtr) sto->xpathCtxt,
  21262. vctxt->inode->localName, vctxt->inode->nsName);
  21263. if (res == -1) {
  21264. VERROR_INT("xmlSchemaXPathEvaluate",
  21265. "calling xmlStreamPush()");
  21266. return (-1);
  21267. }
  21268. if (res == 0)
  21269. goto next_sto;
  21270. /*
  21271. * Full match.
  21272. */
  21273. #ifdef DEBUG_IDC
  21274. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21275. "MATCH\n");
  21276. #endif
  21277. /*
  21278. * Register a match in the state object history.
  21279. */
  21280. if (sto->history == NULL) {
  21281. sto->history = (int *) xmlMalloc(5 * sizeof(int));
  21282. if (sto->history == NULL) {
  21283. xmlSchemaVErrMemory(NULL,
  21284. "allocating the state object history", NULL);
  21285. return(-1);
  21286. }
  21287. sto->sizeHistory = 5;
  21288. } else if (sto->sizeHistory <= sto->nbHistory) {
  21289. sto->sizeHistory *= 2;
  21290. sto->history = (int *) xmlRealloc(sto->history,
  21291. sto->sizeHistory * sizeof(int));
  21292. if (sto->history == NULL) {
  21293. xmlSchemaVErrMemory(NULL,
  21294. "re-allocating the state object history", NULL);
  21295. return(-1);
  21296. }
  21297. }
  21298. sto->history[sto->nbHistory++] = depth;
  21299. #ifdef DEBUG_IDC
  21300. xmlGenericError(xmlGenericErrorContext, "IDC: push match '%d'\n",
  21301. vctxt->depth);
  21302. #endif
  21303. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21304. xmlSchemaIDCSelectPtr sel;
  21305. /*
  21306. * Activate state objects for the IDC fields of
  21307. * the IDC selector.
  21308. */
  21309. #ifdef DEBUG_IDC
  21310. xmlGenericError(xmlGenericErrorContext, "IDC: "
  21311. "activating field states\n");
  21312. #endif
  21313. sel = sto->matcher->aidc->def->fields;
  21314. while (sel != NULL) {
  21315. if (xmlSchemaIDCAddStateObject(vctxt, sto->matcher,
  21316. sel, XPATH_STATE_OBJ_TYPE_IDC_FIELD) == -1)
  21317. return (-1);
  21318. sel = sel->next;
  21319. }
  21320. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21321. /*
  21322. * An IDC key node was found by the IDC field.
  21323. */
  21324. #ifdef DEBUG_IDC
  21325. xmlGenericError(xmlGenericErrorContext,
  21326. "IDC: key found\n");
  21327. #endif
  21328. /*
  21329. * Notify that the character value of this node is
  21330. * needed.
  21331. */
  21332. if (resolved == 0) {
  21333. if ((vctxt->inode->flags &
  21334. XML_SCHEMA_NODE_INFO_VALUE_NEEDED) == 0)
  21335. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  21336. }
  21337. resolved++;
  21338. }
  21339. next_sto:
  21340. if (sto->next == NULL) {
  21341. /*
  21342. * Evaluate field state objects created on this node as well.
  21343. */
  21344. head = first;
  21345. sto = vctxt->xpathStates;
  21346. } else
  21347. sto = sto->next;
  21348. }
  21349. return (resolved);
  21350. }
  21351. static const xmlChar *
  21352. xmlSchemaFormatIDCKeySequence(xmlSchemaValidCtxtPtr vctxt,
  21353. xmlChar **buf,
  21354. xmlSchemaPSVIIDCKeyPtr *seq,
  21355. int count)
  21356. {
  21357. int i, res;
  21358. xmlChar *value = NULL;
  21359. *buf = xmlStrdup(BAD_CAST "[");
  21360. for (i = 0; i < count; i++) {
  21361. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21362. res = xmlSchemaGetCanonValueWhtspExt(seq[i]->val,
  21363. xmlSchemaGetWhiteSpaceFacetValue(seq[i]->type),
  21364. &value);
  21365. if (res == 0)
  21366. *buf = xmlStrcat(*buf, BAD_CAST value);
  21367. else {
  21368. VERROR_INT("xmlSchemaFormatIDCKeySequence",
  21369. "failed to compute a canonical value");
  21370. *buf = xmlStrcat(*buf, BAD_CAST "???");
  21371. }
  21372. if (i < count -1)
  21373. *buf = xmlStrcat(*buf, BAD_CAST "', ");
  21374. else
  21375. *buf = xmlStrcat(*buf, BAD_CAST "'");
  21376. if (value != NULL) {
  21377. xmlFree(value);
  21378. value = NULL;
  21379. }
  21380. }
  21381. *buf = xmlStrcat(*buf, BAD_CAST "]");
  21382. return (BAD_CAST *buf);
  21383. }
  21384. /**
  21385. * xmlSchemaXPathPop:
  21386. * @vctxt: the WXS validation context
  21387. *
  21388. * Pops all XPath states.
  21389. *
  21390. * Returns 0 on success and -1 on internal errors.
  21391. */
  21392. static int
  21393. xmlSchemaXPathPop(xmlSchemaValidCtxtPtr vctxt)
  21394. {
  21395. xmlSchemaIDCStateObjPtr sto;
  21396. int res;
  21397. if (vctxt->xpathStates == NULL)
  21398. return(0);
  21399. sto = vctxt->xpathStates;
  21400. do {
  21401. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21402. if (res == -1)
  21403. return (-1);
  21404. sto = sto->next;
  21405. } while (sto != NULL);
  21406. return(0);
  21407. }
  21408. /**
  21409. * xmlSchemaXPathProcessHistory:
  21410. * @vctxt: the WXS validation context
  21411. * @type: the simple/complex type of the current node if any at all
  21412. * @val: the precompiled value
  21413. *
  21414. * Processes and pops the history items of the IDC state objects.
  21415. * IDC key-sequences are validated/created on IDC bindings.
  21416. *
  21417. * Returns 0 on success and -1 on internal errors.
  21418. */
  21419. static int
  21420. xmlSchemaXPathProcessHistory(xmlSchemaValidCtxtPtr vctxt,
  21421. int depth)
  21422. {
  21423. xmlSchemaIDCStateObjPtr sto, nextsto;
  21424. int res, matchDepth;
  21425. xmlSchemaPSVIIDCKeyPtr key = NULL;
  21426. xmlSchemaTypePtr type = vctxt->inode->typeDef, simpleType = NULL;
  21427. if (vctxt->xpathStates == NULL)
  21428. return (0);
  21429. sto = vctxt->xpathStates;
  21430. #ifdef DEBUG_IDC
  21431. {
  21432. xmlChar *str = NULL;
  21433. xmlGenericError(xmlGenericErrorContext,
  21434. "IDC: BACK on %s, depth %d\n",
  21435. xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21436. vctxt->inode->localName), vctxt->depth);
  21437. FREE_AND_NULL(str)
  21438. }
  21439. #endif
  21440. /*
  21441. * Evaluate the state objects.
  21442. */
  21443. while (sto != NULL) {
  21444. res = xmlStreamPop((xmlStreamCtxtPtr) sto->xpathCtxt);
  21445. if (res == -1) {
  21446. VERROR_INT("xmlSchemaXPathProcessHistory",
  21447. "calling xmlStreamPop()");
  21448. return (-1);
  21449. }
  21450. #ifdef DEBUG_IDC
  21451. xmlGenericError(xmlGenericErrorContext, "IDC: stream pop '%s'\n",
  21452. sto->sel->xpath);
  21453. #endif
  21454. if (sto->nbHistory == 0)
  21455. goto deregister_check;
  21456. matchDepth = sto->history[sto->nbHistory -1];
  21457. /*
  21458. * Only matches at the current depth are of interest.
  21459. */
  21460. if (matchDepth != depth) {
  21461. sto = sto->next;
  21462. continue;
  21463. }
  21464. if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_FIELD) {
  21465. /*
  21466. * NOTE: According to
  21467. * http://www.w3.org/Bugs/Public/show_bug.cgi?id=2198
  21468. * ... the simple-content of complex types is also allowed.
  21469. */
  21470. if (WXS_IS_COMPLEX(type)) {
  21471. if (WXS_HAS_SIMPLE_CONTENT(type)) {
  21472. /*
  21473. * Sanity check for complex types with simple content.
  21474. */
  21475. simpleType = type->contentTypeDef;
  21476. if (simpleType == NULL) {
  21477. VERROR_INT("xmlSchemaXPathProcessHistory",
  21478. "field resolves to a CT with simple content "
  21479. "but the CT is missing the ST definition");
  21480. return (-1);
  21481. }
  21482. } else
  21483. simpleType = NULL;
  21484. } else
  21485. simpleType = type;
  21486. if (simpleType == NULL) {
  21487. xmlChar *str = NULL;
  21488. /*
  21489. * Not qualified if the field resolves to a node of non
  21490. * simple type.
  21491. */
  21492. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21493. XML_SCHEMAV_CVC_IDC, NULL,
  21494. WXS_BASIC_CAST sto->matcher->aidc->def,
  21495. "The XPath '%s' of a field of %s does evaluate to a node of "
  21496. "non-simple type",
  21497. sto->sel->xpath,
  21498. xmlSchemaGetIDCDesignation(&str, sto->matcher->aidc->def));
  21499. FREE_AND_NULL(str);
  21500. sto->nbHistory--;
  21501. goto deregister_check;
  21502. }
  21503. if ((key == NULL) && (vctxt->inode->val == NULL)) {
  21504. /*
  21505. * Failed to provide the normalized value; maybe
  21506. * the value was invalid.
  21507. */
  21508. VERROR(XML_SCHEMAV_CVC_IDC,
  21509. WXS_BASIC_CAST sto->matcher->aidc->def,
  21510. "Warning: No precomputed value available, the value "
  21511. "was either invalid or something strange happened");
  21512. sto->nbHistory--;
  21513. goto deregister_check;
  21514. } else {
  21515. xmlSchemaIDCMatcherPtr matcher = sto->matcher;
  21516. xmlSchemaPSVIIDCKeyPtr *keySeq;
  21517. int pos, idx;
  21518. /*
  21519. * The key will be anchored on the matcher's list of
  21520. * key-sequences. The position in this list is determined
  21521. * by the target node's depth relative to the matcher's
  21522. * depth of creation (i.e. the depth of the scope element).
  21523. *
  21524. * Element Depth Pos List-entries
  21525. * <scope> 0 NULL
  21526. * <bar> 1 NULL
  21527. * <target/> 2 2 target
  21528. * <bar>
  21529. * </scope>
  21530. *
  21531. * The size of the list is only dependent on the depth of
  21532. * the tree.
  21533. * An entry will be NULLed in selector_leave, i.e. when
  21534. * we hit the target's
  21535. */
  21536. pos = sto->depth - matcher->depth;
  21537. idx = sto->sel->index;
  21538. /*
  21539. * Create/grow the array of key-sequences.
  21540. */
  21541. if (matcher->keySeqs == NULL) {
  21542. if (pos > 9)
  21543. matcher->sizeKeySeqs = pos * 2;
  21544. else
  21545. matcher->sizeKeySeqs = 10;
  21546. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21547. xmlMalloc(matcher->sizeKeySeqs *
  21548. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21549. if (matcher->keySeqs == NULL) {
  21550. xmlSchemaVErrMemory(NULL,
  21551. "allocating an array of key-sequences",
  21552. NULL);
  21553. return(-1);
  21554. }
  21555. memset(matcher->keySeqs, 0,
  21556. matcher->sizeKeySeqs *
  21557. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21558. } else if (pos >= matcher->sizeKeySeqs) {
  21559. int i = matcher->sizeKeySeqs;
  21560. matcher->sizeKeySeqs *= 2;
  21561. matcher->keySeqs = (xmlSchemaPSVIIDCKeyPtr **)
  21562. xmlRealloc(matcher->keySeqs,
  21563. matcher->sizeKeySeqs *
  21564. sizeof(xmlSchemaPSVIIDCKeyPtr *));
  21565. if (matcher->keySeqs == NULL) {
  21566. xmlSchemaVErrMemory(NULL,
  21567. "reallocating an array of key-sequences",
  21568. NULL);
  21569. return (-1);
  21570. }
  21571. /*
  21572. * The array needs to be NULLed.
  21573. * TODO: Use memset?
  21574. */
  21575. for (; i < matcher->sizeKeySeqs; i++)
  21576. matcher->keySeqs[i] = NULL;
  21577. }
  21578. /*
  21579. * Get/create the key-sequence.
  21580. */
  21581. keySeq = matcher->keySeqs[pos];
  21582. if (keySeq == NULL) {
  21583. goto create_sequence;
  21584. } else if (keySeq[idx] != NULL) {
  21585. xmlChar *str = NULL;
  21586. /*
  21587. * cvc-identity-constraint:
  21588. * 3 For each node in the `target node set` all
  21589. * of the {fields}, with that node as the context
  21590. * node, evaluate to either an empty node-set or
  21591. * a node-set with exactly one member, which must
  21592. * have a simple type.
  21593. *
  21594. * The key was already set; report an error.
  21595. */
  21596. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21597. XML_SCHEMAV_CVC_IDC, NULL,
  21598. WXS_BASIC_CAST matcher->aidc->def,
  21599. "The XPath '%s' of a field of %s evaluates to a "
  21600. "node-set with more than one member",
  21601. sto->sel->xpath,
  21602. xmlSchemaGetIDCDesignation(&str, matcher->aidc->def));
  21603. FREE_AND_NULL(str);
  21604. sto->nbHistory--;
  21605. goto deregister_check;
  21606. } else
  21607. goto create_key;
  21608. create_sequence:
  21609. /*
  21610. * Create a key-sequence.
  21611. */
  21612. keySeq = (xmlSchemaPSVIIDCKeyPtr *) xmlMalloc(
  21613. matcher->aidc->def->nbFields *
  21614. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21615. if (keySeq == NULL) {
  21616. xmlSchemaVErrMemory(NULL,
  21617. "allocating an IDC key-sequence", NULL);
  21618. return(-1);
  21619. }
  21620. memset(keySeq, 0, matcher->aidc->def->nbFields *
  21621. sizeof(xmlSchemaPSVIIDCKeyPtr));
  21622. matcher->keySeqs[pos] = keySeq;
  21623. create_key:
  21624. /*
  21625. * Create a key once per node only.
  21626. */
  21627. if (key == NULL) {
  21628. key = (xmlSchemaPSVIIDCKeyPtr) xmlMalloc(
  21629. sizeof(xmlSchemaPSVIIDCKey));
  21630. if (key == NULL) {
  21631. xmlSchemaVErrMemory(NULL,
  21632. "allocating a IDC key", NULL);
  21633. xmlFree(keySeq);
  21634. matcher->keySeqs[pos] = NULL;
  21635. return(-1);
  21636. }
  21637. /*
  21638. * Consume the compiled value.
  21639. */
  21640. key->type = simpleType;
  21641. key->val = vctxt->inode->val;
  21642. vctxt->inode->val = NULL;
  21643. /*
  21644. * Store the key in a global list.
  21645. */
  21646. if (xmlSchemaIDCStoreKey(vctxt, key) == -1) {
  21647. xmlSchemaIDCFreeKey(key);
  21648. return (-1);
  21649. }
  21650. }
  21651. keySeq[idx] = key;
  21652. }
  21653. } else if (sto->type == XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) {
  21654. xmlSchemaPSVIIDCKeyPtr **keySeq = NULL;
  21655. /* xmlSchemaPSVIIDCBindingPtr bind; */
  21656. xmlSchemaPSVIIDCNodePtr ntItem;
  21657. xmlSchemaIDCMatcherPtr matcher;
  21658. xmlSchemaIDCPtr idc;
  21659. xmlSchemaItemListPtr targets;
  21660. int pos, i, j, nbKeys;
  21661. /*
  21662. * Here we have the following scenario:
  21663. * An IDC 'selector' state object resolved to a target node,
  21664. * during the time this target node was in the
  21665. * ancestor-or-self axis, the 'field' state object(s) looked
  21666. * out for matching nodes to create a key-sequence for this
  21667. * target node. Now we are back to this target node and need
  21668. * to put the key-sequence, together with the target node
  21669. * itself, into the node-table of the corresponding IDC
  21670. * binding.
  21671. */
  21672. matcher = sto->matcher;
  21673. idc = matcher->aidc->def;
  21674. nbKeys = idc->nbFields;
  21675. pos = depth - matcher->depth;
  21676. /*
  21677. * Check if the matcher has any key-sequences at all, plus
  21678. * if it has a key-sequence for the current target node.
  21679. */
  21680. if ((matcher->keySeqs == NULL) ||
  21681. (matcher->sizeKeySeqs <= pos)) {
  21682. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21683. goto selector_key_error;
  21684. else
  21685. goto selector_leave;
  21686. }
  21687. keySeq = &(matcher->keySeqs[pos]);
  21688. if (*keySeq == NULL) {
  21689. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY)
  21690. goto selector_key_error;
  21691. else
  21692. goto selector_leave;
  21693. }
  21694. for (i = 0; i < nbKeys; i++) {
  21695. if ((*keySeq)[i] == NULL) {
  21696. /*
  21697. * Not qualified, if not all fields did resolve.
  21698. */
  21699. if (idc->type == XML_SCHEMA_TYPE_IDC_KEY) {
  21700. /*
  21701. * All fields of a "key" IDC must resolve.
  21702. */
  21703. goto selector_key_error;
  21704. }
  21705. goto selector_leave;
  21706. }
  21707. }
  21708. /*
  21709. * All fields did resolve.
  21710. */
  21711. /*
  21712. * 4.1 If the {identity-constraint category} is unique(/key),
  21713. * then no two members of the `qualified node set` have
  21714. * `key-sequences` whose members are pairwise equal, as
  21715. * defined by Equal in [XML Schemas: Datatypes].
  21716. *
  21717. * Get the IDC binding from the matcher and check for
  21718. * duplicate key-sequences.
  21719. */
  21720. #if 0
  21721. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  21722. #endif
  21723. targets = xmlSchemaIDCAcquireTargetList(vctxt, matcher);
  21724. if ((idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) &&
  21725. (targets->nbItems != 0)) {
  21726. xmlSchemaPSVIIDCKeyPtr ckey, bkey, *bkeySeq;
  21727. i = 0;
  21728. res = 0;
  21729. /*
  21730. * Compare the key-sequences, key by key.
  21731. */
  21732. do {
  21733. bkeySeq =
  21734. ((xmlSchemaPSVIIDCNodePtr) targets->items[i])->keys;
  21735. for (j = 0; j < nbKeys; j++) {
  21736. ckey = (*keySeq)[j];
  21737. bkey = bkeySeq[j];
  21738. res = xmlSchemaAreValuesEqual(ckey->val, bkey->val);
  21739. if (res == -1) {
  21740. return (-1);
  21741. } else if (res == 0) {
  21742. /*
  21743. * One of the keys differs, so the key-sequence
  21744. * won't be equal; get out.
  21745. */
  21746. break;
  21747. }
  21748. }
  21749. if (res == 1) {
  21750. /*
  21751. * Duplicate key-sequence found.
  21752. */
  21753. break;
  21754. }
  21755. i++;
  21756. } while (i < targets->nbItems);
  21757. if (i != targets->nbItems) {
  21758. xmlChar *str = NULL, *strB = NULL;
  21759. /*
  21760. * TODO: Try to report the key-sequence.
  21761. */
  21762. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21763. XML_SCHEMAV_CVC_IDC, NULL,
  21764. WXS_BASIC_CAST idc,
  21765. "Duplicate key-sequence %s in %s",
  21766. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  21767. (*keySeq), nbKeys),
  21768. xmlSchemaGetIDCDesignation(&strB, idc));
  21769. FREE_AND_NULL(str);
  21770. FREE_AND_NULL(strB);
  21771. goto selector_leave;
  21772. }
  21773. }
  21774. /*
  21775. * Add a node-table item to the IDC binding.
  21776. */
  21777. ntItem = (xmlSchemaPSVIIDCNodePtr) xmlMalloc(
  21778. sizeof(xmlSchemaPSVIIDCNode));
  21779. if (ntItem == NULL) {
  21780. xmlSchemaVErrMemory(NULL,
  21781. "allocating an IDC node-table item", NULL);
  21782. xmlFree(*keySeq);
  21783. *keySeq = NULL;
  21784. return(-1);
  21785. }
  21786. memset(ntItem, 0, sizeof(xmlSchemaPSVIIDCNode));
  21787. /*
  21788. * Store the node-table item in a global list.
  21789. */
  21790. if (idc->type != XML_SCHEMA_TYPE_IDC_KEYREF) {
  21791. if (xmlSchemaIDCStoreNodeTableItem(vctxt, ntItem) == -1) {
  21792. xmlFree(ntItem);
  21793. xmlFree(*keySeq);
  21794. *keySeq = NULL;
  21795. return (-1);
  21796. }
  21797. ntItem->nodeQNameID = -1;
  21798. } else {
  21799. /*
  21800. * Save a cached QName for this node on the IDC node, to be
  21801. * able to report it, even if the node is not saved.
  21802. */
  21803. ntItem->nodeQNameID = xmlSchemaVAddNodeQName(vctxt,
  21804. vctxt->inode->localName, vctxt->inode->nsName);
  21805. if (ntItem->nodeQNameID == -1) {
  21806. xmlFree(ntItem);
  21807. xmlFree(*keySeq);
  21808. *keySeq = NULL;
  21809. return (-1);
  21810. }
  21811. }
  21812. /*
  21813. * Init the node-table item: Save the node, position and
  21814. * consume the key-sequence.
  21815. */
  21816. ntItem->node = vctxt->node;
  21817. ntItem->nodeLine = vctxt->inode->nodeLine;
  21818. ntItem->keys = *keySeq;
  21819. *keySeq = NULL;
  21820. #if 0
  21821. if (xmlSchemaIDCAppendNodeTableItem(bind, ntItem) == -1)
  21822. #endif
  21823. if (xmlSchemaItemListAdd(targets, ntItem) == -1) {
  21824. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21825. /*
  21826. * Free the item, since keyref items won't be
  21827. * put on a global list.
  21828. */
  21829. xmlFree(ntItem->keys);
  21830. xmlFree(ntItem);
  21831. }
  21832. return (-1);
  21833. }
  21834. goto selector_leave;
  21835. selector_key_error:
  21836. {
  21837. xmlChar *str = NULL;
  21838. /*
  21839. * 4.2.1 (KEY) The `target node set` and the
  21840. * `qualified node set` are equal, that is, every
  21841. * member of the `target node set` is also a member
  21842. * of the `qualified node set` and vice versa.
  21843. */
  21844. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  21845. XML_SCHEMAV_CVC_IDC, NULL,
  21846. WXS_BASIC_CAST idc,
  21847. "Not all fields of %s evaluate to a node",
  21848. xmlSchemaGetIDCDesignation(&str, idc), NULL);
  21849. FREE_AND_NULL(str);
  21850. }
  21851. selector_leave:
  21852. /*
  21853. * Free the key-sequence if not added to the IDC table.
  21854. */
  21855. if ((keySeq != NULL) && (*keySeq != NULL)) {
  21856. xmlFree(*keySeq);
  21857. *keySeq = NULL;
  21858. }
  21859. } /* if selector */
  21860. sto->nbHistory--;
  21861. deregister_check:
  21862. /*
  21863. * Deregister state objects if they reach the depth of creation.
  21864. */
  21865. if ((sto->nbHistory == 0) && (sto->depth == depth)) {
  21866. #ifdef DEBUG_IDC
  21867. xmlGenericError(xmlGenericErrorContext, "IDC: STO pop '%s'\n",
  21868. sto->sel->xpath);
  21869. #endif
  21870. if (vctxt->xpathStates != sto) {
  21871. VERROR_INT("xmlSchemaXPathProcessHistory",
  21872. "The state object to be removed is not the first "
  21873. "in the list");
  21874. }
  21875. nextsto = sto->next;
  21876. /*
  21877. * Unlink from the list of active XPath state objects.
  21878. */
  21879. vctxt->xpathStates = sto->next;
  21880. sto->next = vctxt->xpathStatePool;
  21881. /*
  21882. * Link it to the pool of reusable state objects.
  21883. */
  21884. vctxt->xpathStatePool = sto;
  21885. sto = nextsto;
  21886. } else
  21887. sto = sto->next;
  21888. } /* while (sto != NULL) */
  21889. return (0);
  21890. }
  21891. /**
  21892. * xmlSchemaIDCRegisterMatchers:
  21893. * @vctxt: the WXS validation context
  21894. * @elemDecl: the element declaration
  21895. *
  21896. * Creates helper objects to evaluate IDC selectors/fields
  21897. * successively.
  21898. *
  21899. * Returns 0 if OK and -1 on internal errors.
  21900. */
  21901. static int
  21902. xmlSchemaIDCRegisterMatchers(xmlSchemaValidCtxtPtr vctxt,
  21903. xmlSchemaElementPtr elemDecl)
  21904. {
  21905. xmlSchemaIDCMatcherPtr matcher, last = NULL;
  21906. xmlSchemaIDCPtr idc, refIdc;
  21907. xmlSchemaIDCAugPtr aidc;
  21908. idc = (xmlSchemaIDCPtr) elemDecl->idcs;
  21909. if (idc == NULL)
  21910. return (0);
  21911. #ifdef DEBUG_IDC
  21912. {
  21913. xmlChar *str = NULL;
  21914. xmlGenericError(xmlGenericErrorContext,
  21915. "IDC: REGISTER on %s, depth %d\n",
  21916. (char *) xmlSchemaFormatQName(&str, vctxt->inode->nsName,
  21917. vctxt->inode->localName), vctxt->depth);
  21918. FREE_AND_NULL(str)
  21919. }
  21920. #endif
  21921. if (vctxt->inode->idcMatchers != NULL) {
  21922. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21923. "The chain of IDC matchers is expected to be empty");
  21924. return (-1);
  21925. }
  21926. do {
  21927. if (idc->type == XML_SCHEMA_TYPE_IDC_KEYREF) {
  21928. /*
  21929. * Since IDCs bubbles are expensive we need to know the
  21930. * depth at which the bubbles should stop; this will be
  21931. * the depth of the top-most keyref IDC. If no keyref
  21932. * references a key/unique IDC, the keyrefDepth will
  21933. * be -1, indicating that no bubbles are needed.
  21934. */
  21935. refIdc = (xmlSchemaIDCPtr) idc->ref->item;
  21936. if (refIdc != NULL) {
  21937. /*
  21938. * Remember that we have keyrefs on this node.
  21939. */
  21940. vctxt->inode->hasKeyrefs = 1;
  21941. /*
  21942. * Lookup the referenced augmented IDC info.
  21943. */
  21944. aidc = vctxt->aidcs;
  21945. while (aidc != NULL) {
  21946. if (aidc->def == refIdc)
  21947. break;
  21948. aidc = aidc->next;
  21949. }
  21950. if (aidc == NULL) {
  21951. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21952. "Could not find an augmented IDC item for an IDC "
  21953. "definition");
  21954. return (-1);
  21955. }
  21956. if ((aidc->keyrefDepth == -1) ||
  21957. (vctxt->depth < aidc->keyrefDepth))
  21958. aidc->keyrefDepth = vctxt->depth;
  21959. }
  21960. }
  21961. /*
  21962. * Lookup the augmented IDC item for the IDC definition.
  21963. */
  21964. aidc = vctxt->aidcs;
  21965. while (aidc != NULL) {
  21966. if (aidc->def == idc)
  21967. break;
  21968. aidc = aidc->next;
  21969. }
  21970. if (aidc == NULL) {
  21971. VERROR_INT("xmlSchemaIDCRegisterMatchers",
  21972. "Could not find an augmented IDC item for an IDC definition");
  21973. return (-1);
  21974. }
  21975. /*
  21976. * Create an IDC matcher for every IDC definition.
  21977. */
  21978. if (vctxt->idcMatcherCache != NULL) {
  21979. /*
  21980. * Reuse a cached matcher.
  21981. */
  21982. matcher = vctxt->idcMatcherCache;
  21983. vctxt->idcMatcherCache = matcher->nextCached;
  21984. matcher->nextCached = NULL;
  21985. } else {
  21986. matcher = (xmlSchemaIDCMatcherPtr)
  21987. xmlMalloc(sizeof(xmlSchemaIDCMatcher));
  21988. if (matcher == NULL) {
  21989. xmlSchemaVErrMemory(vctxt,
  21990. "allocating an IDC matcher", NULL);
  21991. return (-1);
  21992. }
  21993. memset(matcher, 0, sizeof(xmlSchemaIDCMatcher));
  21994. }
  21995. if (last == NULL)
  21996. vctxt->inode->idcMatchers = matcher;
  21997. else
  21998. last->next = matcher;
  21999. last = matcher;
  22000. matcher->type = IDC_MATCHER;
  22001. matcher->depth = vctxt->depth;
  22002. matcher->aidc = aidc;
  22003. matcher->idcType = aidc->def->type;
  22004. #ifdef DEBUG_IDC
  22005. xmlGenericError(xmlGenericErrorContext, "IDC: register matcher\n");
  22006. #endif
  22007. /*
  22008. * Init the automaton state object.
  22009. */
  22010. if (xmlSchemaIDCAddStateObject(vctxt, matcher,
  22011. idc->selector, XPATH_STATE_OBJ_TYPE_IDC_SELECTOR) == -1)
  22012. return (-1);
  22013. idc = idc->next;
  22014. } while (idc != NULL);
  22015. return (0);
  22016. }
  22017. static int
  22018. xmlSchemaIDCFillNodeTables(xmlSchemaValidCtxtPtr vctxt,
  22019. xmlSchemaNodeInfoPtr ielem)
  22020. {
  22021. xmlSchemaPSVIIDCBindingPtr bind;
  22022. int res, i, j, k, nbTargets, nbFields, nbDupls, nbNodeTable;
  22023. xmlSchemaPSVIIDCKeyPtr *keys, *ntkeys;
  22024. xmlSchemaPSVIIDCNodePtr *targets, *dupls;
  22025. xmlSchemaIDCMatcherPtr matcher = ielem->idcMatchers;
  22026. /* vctxt->createIDCNodeTables */
  22027. while (matcher != NULL) {
  22028. /*
  22029. * Skip keyref IDCs and empty IDC target-lists.
  22030. */
  22031. if ((matcher->aidc->def->type == XML_SCHEMA_TYPE_IDC_KEYREF) ||
  22032. WXS_ILIST_IS_EMPTY(matcher->targets))
  22033. {
  22034. matcher = matcher->next;
  22035. continue;
  22036. }
  22037. /*
  22038. * If we _want_ the IDC node-table to be created in any case
  22039. * then do so. Otherwise create them only if keyrefs need them.
  22040. */
  22041. if ((! vctxt->createIDCNodeTables) &&
  22042. ((matcher->aidc->keyrefDepth == -1) ||
  22043. (matcher->aidc->keyrefDepth > vctxt->depth)))
  22044. {
  22045. matcher = matcher->next;
  22046. continue;
  22047. }
  22048. /*
  22049. * Get/create the IDC binding on this element for the IDC definition.
  22050. */
  22051. bind = xmlSchemaIDCAcquireBinding(vctxt, matcher);
  22052. if (bind == NULL)
  22053. goto internal_error;
  22054. if (! WXS_ILIST_IS_EMPTY(bind->dupls)) {
  22055. dupls = (xmlSchemaPSVIIDCNodePtr *) bind->dupls->items;
  22056. nbDupls = bind->dupls->nbItems;
  22057. } else {
  22058. dupls = NULL;
  22059. nbDupls = 0;
  22060. }
  22061. if (bind->nodeTable != NULL) {
  22062. nbNodeTable = bind->nbNodes;
  22063. } else {
  22064. nbNodeTable = 0;
  22065. }
  22066. if ((nbNodeTable == 0) && (nbDupls == 0)) {
  22067. /*
  22068. * Transfer all IDC target-nodes to the IDC node-table.
  22069. */
  22070. bind->nodeTable =
  22071. (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22072. bind->sizeNodes = matcher->targets->sizeItems;
  22073. bind->nbNodes = matcher->targets->nbItems;
  22074. matcher->targets->items = NULL;
  22075. matcher->targets->sizeItems = 0;
  22076. matcher->targets->nbItems = 0;
  22077. } else {
  22078. /*
  22079. * Compare the key-sequences and add to the IDC node-table.
  22080. */
  22081. nbTargets = matcher->targets->nbItems;
  22082. targets = (xmlSchemaPSVIIDCNodePtr *) matcher->targets->items;
  22083. nbFields = matcher->aidc->def->nbFields;
  22084. i = 0;
  22085. do {
  22086. keys = targets[i]->keys;
  22087. if (nbDupls) {
  22088. /*
  22089. * Search in already found duplicates first.
  22090. */
  22091. j = 0;
  22092. do {
  22093. if (nbFields == 1) {
  22094. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22095. dupls[j]->keys[0]->val);
  22096. if (res == -1)
  22097. goto internal_error;
  22098. if (res == 1) {
  22099. /*
  22100. * Equal key-sequence.
  22101. */
  22102. goto next_target;
  22103. }
  22104. } else {
  22105. res = 0;
  22106. ntkeys = dupls[j]->keys;
  22107. for (k = 0; k < nbFields; k++) {
  22108. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22109. ntkeys[k]->val);
  22110. if (res == -1)
  22111. goto internal_error;
  22112. if (res == 0) {
  22113. /*
  22114. * One of the keys differs.
  22115. */
  22116. break;
  22117. }
  22118. }
  22119. if (res == 1) {
  22120. /*
  22121. * Equal key-sequence found.
  22122. */
  22123. goto next_target;
  22124. }
  22125. }
  22126. j++;
  22127. } while (j < nbDupls);
  22128. }
  22129. if (nbNodeTable) {
  22130. j = 0;
  22131. do {
  22132. if (nbFields == 1) {
  22133. res = xmlSchemaAreValuesEqual(keys[0]->val,
  22134. bind->nodeTable[j]->keys[0]->val);
  22135. if (res == -1)
  22136. goto internal_error;
  22137. if (res == 0) {
  22138. /*
  22139. * The key-sequence differs.
  22140. */
  22141. goto next_node_table_entry;
  22142. }
  22143. } else {
  22144. res = 0;
  22145. ntkeys = bind->nodeTable[j]->keys;
  22146. for (k = 0; k < nbFields; k++) {
  22147. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22148. ntkeys[k]->val);
  22149. if (res == -1)
  22150. goto internal_error;
  22151. if (res == 0) {
  22152. /*
  22153. * One of the keys differs.
  22154. */
  22155. goto next_node_table_entry;
  22156. }
  22157. }
  22158. }
  22159. /*
  22160. * Add the duplicate to the list of duplicates.
  22161. */
  22162. if (bind->dupls == NULL) {
  22163. bind->dupls = xmlSchemaItemListCreate();
  22164. if (bind->dupls == NULL)
  22165. goto internal_error;
  22166. }
  22167. if (xmlSchemaItemListAdd(bind->dupls, bind->nodeTable[j]) == -1)
  22168. goto internal_error;
  22169. /*
  22170. * Remove the duplicate entry from the IDC node-table.
  22171. */
  22172. bind->nodeTable[j] = bind->nodeTable[bind->nbNodes -1];
  22173. bind->nbNodes--;
  22174. goto next_target;
  22175. next_node_table_entry:
  22176. j++;
  22177. } while (j < nbNodeTable);
  22178. }
  22179. /*
  22180. * If everything is fine, then add the IDC target-node to
  22181. * the IDC node-table.
  22182. */
  22183. if (xmlSchemaIDCAppendNodeTableItem(bind, targets[i]) == -1)
  22184. goto internal_error;
  22185. next_target:
  22186. i++;
  22187. } while (i < nbTargets);
  22188. }
  22189. matcher = matcher->next;
  22190. }
  22191. return(0);
  22192. internal_error:
  22193. return(-1);
  22194. }
  22195. /**
  22196. * xmlSchemaBubbleIDCNodeTables:
  22197. * @depth: the current tree depth
  22198. *
  22199. * Merges IDC bindings of an element at @depth into the corresponding IDC
  22200. * bindings of its parent element. If a duplicate note-table entry is found,
  22201. * both, the parent node-table entry and child entry are discarded from the
  22202. * node-table of the parent.
  22203. *
  22204. * Returns 0 if OK and -1 on internal errors.
  22205. */
  22206. static int
  22207. xmlSchemaBubbleIDCNodeTables(xmlSchemaValidCtxtPtr vctxt)
  22208. {
  22209. xmlSchemaPSVIIDCBindingPtr bind; /* IDC bindings of the current node. */
  22210. xmlSchemaPSVIIDCBindingPtr *parTable, parBind = NULL; /* parent IDC bindings. */
  22211. xmlSchemaPSVIIDCNodePtr node, parNode = NULL, *dupls, *parNodes; /* node-table entries. */
  22212. xmlSchemaIDCAugPtr aidc;
  22213. int i, j, k, ret = 0, nbFields, oldNum, oldDupls;
  22214. bind = vctxt->inode->idcTable;
  22215. if (bind == NULL) {
  22216. /* Fine, no table, no bubbles. */
  22217. return (0);
  22218. }
  22219. parTable = &(vctxt->elemInfos[vctxt->depth -1]->idcTable);
  22220. /*
  22221. * Walk all bindings; create new or add to existing bindings.
  22222. * Remove duplicate key-sequences.
  22223. */
  22224. while (bind != NULL) {
  22225. if ((bind->nbNodes == 0) && WXS_ILIST_IS_EMPTY(bind->dupls))
  22226. goto next_binding;
  22227. /*
  22228. * Check if the key/unique IDC table needs to be bubbled.
  22229. */
  22230. if (! vctxt->createIDCNodeTables) {
  22231. aidc = vctxt->aidcs;
  22232. do {
  22233. if (aidc->def == bind->definition) {
  22234. if ((aidc->keyrefDepth == -1) ||
  22235. (aidc->keyrefDepth >= vctxt->depth)) {
  22236. goto next_binding;
  22237. }
  22238. break;
  22239. }
  22240. aidc = aidc->next;
  22241. } while (aidc != NULL);
  22242. }
  22243. if (parTable != NULL)
  22244. parBind = *parTable;
  22245. /*
  22246. * Search a matching parent binding for the
  22247. * IDC definition.
  22248. */
  22249. while (parBind != NULL) {
  22250. if (parBind->definition == bind->definition)
  22251. break;
  22252. parBind = parBind->next;
  22253. }
  22254. if (parBind != NULL) {
  22255. /*
  22256. * Compare every node-table entry of the child node,
  22257. * i.e. the key-sequence within, ...
  22258. */
  22259. oldNum = parBind->nbNodes; /* Skip newly added items. */
  22260. if (! WXS_ILIST_IS_EMPTY(parBind->dupls)) {
  22261. oldDupls = parBind->dupls->nbItems;
  22262. dupls = (xmlSchemaPSVIIDCNodePtr *) parBind->dupls->items;
  22263. } else {
  22264. dupls = NULL;
  22265. oldDupls = 0;
  22266. }
  22267. parNodes = parBind->nodeTable;
  22268. nbFields = bind->definition->nbFields;
  22269. for (i = 0; i < bind->nbNodes; i++) {
  22270. node = bind->nodeTable[i];
  22271. if (node == NULL)
  22272. continue;
  22273. /*
  22274. * ...with every key-sequence of the parent node, already
  22275. * evaluated to be a duplicate key-sequence.
  22276. */
  22277. if (oldDupls) {
  22278. j = 0;
  22279. while (j < oldDupls) {
  22280. if (nbFields == 1) {
  22281. ret = xmlSchemaAreValuesEqual(
  22282. node->keys[0]->val,
  22283. dupls[j]->keys[0]->val);
  22284. if (ret == -1)
  22285. goto internal_error;
  22286. if (ret == 0) {
  22287. j++;
  22288. continue;
  22289. }
  22290. } else {
  22291. parNode = dupls[j];
  22292. for (k = 0; k < nbFields; k++) {
  22293. ret = xmlSchemaAreValuesEqual(
  22294. node->keys[k]->val,
  22295. parNode->keys[k]->val);
  22296. if (ret == -1)
  22297. goto internal_error;
  22298. if (ret == 0)
  22299. break;
  22300. }
  22301. }
  22302. if (ret == 1)
  22303. /* Duplicate found. */
  22304. break;
  22305. j++;
  22306. }
  22307. if (j != oldDupls) {
  22308. /* Duplicate found. Skip this entry. */
  22309. continue;
  22310. }
  22311. }
  22312. /*
  22313. * ... and with every key-sequence of the parent node.
  22314. */
  22315. if (oldNum) {
  22316. j = 0;
  22317. while (j < oldNum) {
  22318. parNode = parNodes[j];
  22319. if (nbFields == 1) {
  22320. ret = xmlSchemaAreValuesEqual(
  22321. node->keys[0]->val,
  22322. parNode->keys[0]->val);
  22323. if (ret == -1)
  22324. goto internal_error;
  22325. if (ret == 0) {
  22326. j++;
  22327. continue;
  22328. }
  22329. } else {
  22330. for (k = 0; k < nbFields; k++) {
  22331. ret = xmlSchemaAreValuesEqual(
  22332. node->keys[k]->val,
  22333. parNode->keys[k]->val);
  22334. if (ret == -1)
  22335. goto internal_error;
  22336. if (ret == 0)
  22337. break;
  22338. }
  22339. }
  22340. if (ret == 1)
  22341. /* Duplicate found. */
  22342. break;
  22343. j++;
  22344. }
  22345. if (j != oldNum) {
  22346. /*
  22347. * Handle duplicates. Move the duplicate in
  22348. * the parent's node-table to the list of
  22349. * duplicates.
  22350. */
  22351. oldNum--;
  22352. parBind->nbNodes--;
  22353. /*
  22354. * Move last old item to pos of duplicate.
  22355. */
  22356. parNodes[j] = parNodes[oldNum];
  22357. if (parBind->nbNodes != oldNum) {
  22358. /*
  22359. * If new items exist, move last new item to
  22360. * last of old items.
  22361. */
  22362. parNodes[oldNum] =
  22363. parNodes[parBind->nbNodes];
  22364. }
  22365. if (parBind->dupls == NULL) {
  22366. parBind->dupls = xmlSchemaItemListCreate();
  22367. if (parBind->dupls == NULL)
  22368. goto internal_error;
  22369. }
  22370. xmlSchemaItemListAdd(parBind->dupls, parNode);
  22371. } else {
  22372. /*
  22373. * Add the node-table entry (node and key-sequence) of
  22374. * the child node to the node table of the parent node.
  22375. */
  22376. if (parBind->nodeTable == NULL) {
  22377. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22378. xmlMalloc(10 * sizeof(xmlSchemaPSVIIDCNodePtr));
  22379. if (parBind->nodeTable == NULL) {
  22380. xmlSchemaVErrMemory(NULL,
  22381. "allocating IDC list of node-table items", NULL);
  22382. goto internal_error;
  22383. }
  22384. parBind->sizeNodes = 1;
  22385. } else if (parBind->nbNodes >= parBind->sizeNodes) {
  22386. parBind->sizeNodes *= 2;
  22387. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22388. xmlRealloc(parBind->nodeTable, parBind->sizeNodes *
  22389. sizeof(xmlSchemaPSVIIDCNodePtr));
  22390. if (parBind->nodeTable == NULL) {
  22391. xmlSchemaVErrMemory(NULL,
  22392. "re-allocating IDC list of node-table items", NULL);
  22393. goto internal_error;
  22394. }
  22395. }
  22396. parNodes = parBind->nodeTable;
  22397. /*
  22398. * Append the new node-table entry to the 'new node-table
  22399. * entries' section.
  22400. */
  22401. parNodes[parBind->nbNodes++] = node;
  22402. }
  22403. }
  22404. }
  22405. } else {
  22406. /*
  22407. * No binding for the IDC was found: create a new one and
  22408. * copy all node-tables.
  22409. */
  22410. parBind = xmlSchemaIDCNewBinding(bind->definition);
  22411. if (parBind == NULL)
  22412. goto internal_error;
  22413. /*
  22414. * TODO: Hmm, how to optimize the initial number of
  22415. * allocated entries?
  22416. */
  22417. if (bind->nbNodes != 0) {
  22418. /*
  22419. * Add all IDC node-table entries.
  22420. */
  22421. if (! vctxt->psviExposeIDCNodeTables) {
  22422. /*
  22423. * Just move the entries.
  22424. * NOTE: this is quite save here, since
  22425. * all the keyref lookups have already been
  22426. * performed.
  22427. */
  22428. parBind->nodeTable = bind->nodeTable;
  22429. bind->nodeTable = NULL;
  22430. parBind->sizeNodes = bind->sizeNodes;
  22431. bind->sizeNodes = 0;
  22432. parBind->nbNodes = bind->nbNodes;
  22433. bind->nbNodes = 0;
  22434. } else {
  22435. /*
  22436. * Copy the entries.
  22437. */
  22438. parBind->nodeTable = (xmlSchemaPSVIIDCNodePtr *)
  22439. xmlMalloc(bind->nbNodes *
  22440. sizeof(xmlSchemaPSVIIDCNodePtr));
  22441. if (parBind->nodeTable == NULL) {
  22442. xmlSchemaVErrMemory(NULL,
  22443. "allocating an array of IDC node-table "
  22444. "items", NULL);
  22445. xmlSchemaIDCFreeBinding(parBind);
  22446. goto internal_error;
  22447. }
  22448. parBind->sizeNodes = bind->nbNodes;
  22449. parBind->nbNodes = bind->nbNodes;
  22450. memcpy(parBind->nodeTable, bind->nodeTable,
  22451. bind->nbNodes * sizeof(xmlSchemaPSVIIDCNodePtr));
  22452. }
  22453. }
  22454. if (bind->dupls) {
  22455. /*
  22456. * Move the duplicates.
  22457. */
  22458. if (parBind->dupls != NULL)
  22459. xmlSchemaItemListFree(parBind->dupls);
  22460. parBind->dupls = bind->dupls;
  22461. bind->dupls = NULL;
  22462. }
  22463. if (parTable != NULL) {
  22464. if (*parTable == NULL)
  22465. *parTable = parBind;
  22466. else {
  22467. parBind->next = *parTable;
  22468. *parTable = parBind;
  22469. }
  22470. }
  22471. }
  22472. next_binding:
  22473. bind = bind->next;
  22474. }
  22475. return (0);
  22476. internal_error:
  22477. return(-1);
  22478. }
  22479. /**
  22480. * xmlSchemaCheckCVCIDCKeyRef:
  22481. * @vctxt: the WXS validation context
  22482. * @elemDecl: the element declaration
  22483. *
  22484. * Check the cvc-idc-keyref constraints.
  22485. */
  22486. static int
  22487. xmlSchemaCheckCVCIDCKeyRef(xmlSchemaValidCtxtPtr vctxt)
  22488. {
  22489. xmlSchemaIDCMatcherPtr matcher;
  22490. xmlSchemaPSVIIDCBindingPtr bind;
  22491. matcher = vctxt->inode->idcMatchers;
  22492. /*
  22493. * Find a keyref.
  22494. */
  22495. while (matcher != NULL) {
  22496. if ((matcher->idcType == XML_SCHEMA_TYPE_IDC_KEYREF) &&
  22497. matcher->targets &&
  22498. matcher->targets->nbItems)
  22499. {
  22500. int i, j, k, res, nbFields, hasDupls;
  22501. xmlSchemaPSVIIDCKeyPtr *refKeys, *keys;
  22502. xmlSchemaPSVIIDCNodePtr refNode = NULL;
  22503. nbFields = matcher->aidc->def->nbFields;
  22504. /*
  22505. * Find the IDC node-table for the referenced IDC key/unique.
  22506. */
  22507. bind = vctxt->inode->idcTable;
  22508. while (bind != NULL) {
  22509. if ((xmlSchemaIDCPtr) matcher->aidc->def->ref->item ==
  22510. bind->definition)
  22511. break;
  22512. bind = bind->next;
  22513. }
  22514. hasDupls = (bind && bind->dupls && bind->dupls->nbItems) ? 1 : 0;
  22515. /*
  22516. * Search for a matching key-sequences.
  22517. */
  22518. for (i = 0; i < matcher->targets->nbItems; i++) {
  22519. res = 0;
  22520. refNode = matcher->targets->items[i];
  22521. if (bind != NULL) {
  22522. refKeys = refNode->keys;
  22523. for (j = 0; j < bind->nbNodes; j++) {
  22524. keys = bind->nodeTable[j]->keys;
  22525. for (k = 0; k < nbFields; k++) {
  22526. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22527. refKeys[k]->val);
  22528. if (res == 0)
  22529. break;
  22530. else if (res == -1) {
  22531. return (-1);
  22532. }
  22533. }
  22534. if (res == 1) {
  22535. /*
  22536. * Match found.
  22537. */
  22538. break;
  22539. }
  22540. }
  22541. if ((res == 0) && hasDupls) {
  22542. /*
  22543. * Search in duplicates
  22544. */
  22545. for (j = 0; j < bind->dupls->nbItems; j++) {
  22546. keys = ((xmlSchemaPSVIIDCNodePtr)
  22547. bind->dupls->items[j])->keys;
  22548. for (k = 0; k < nbFields; k++) {
  22549. res = xmlSchemaAreValuesEqual(keys[k]->val,
  22550. refKeys[k]->val);
  22551. if (res == 0)
  22552. break;
  22553. else if (res == -1) {
  22554. return (-1);
  22555. }
  22556. }
  22557. if (res == 1) {
  22558. /*
  22559. * Match in duplicates found.
  22560. */
  22561. xmlChar *str = NULL, *strB = NULL;
  22562. xmlSchemaKeyrefErr(vctxt,
  22563. XML_SCHEMAV_CVC_IDC, refNode,
  22564. (xmlSchemaTypePtr) matcher->aidc->def,
  22565. "More than one match found for "
  22566. "key-sequence %s of keyref '%s'",
  22567. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22568. refNode->keys, nbFields),
  22569. xmlSchemaGetComponentQName(&strB,
  22570. matcher->aidc->def));
  22571. FREE_AND_NULL(str);
  22572. FREE_AND_NULL(strB);
  22573. break;
  22574. }
  22575. }
  22576. }
  22577. }
  22578. if (res == 0) {
  22579. xmlChar *str = NULL, *strB = NULL;
  22580. xmlSchemaKeyrefErr(vctxt,
  22581. XML_SCHEMAV_CVC_IDC, refNode,
  22582. (xmlSchemaTypePtr) matcher->aidc->def,
  22583. "No match found for key-sequence %s of keyref '%s'",
  22584. xmlSchemaFormatIDCKeySequence(vctxt, &str,
  22585. refNode->keys, nbFields),
  22586. xmlSchemaGetComponentQName(&strB, matcher->aidc->def));
  22587. FREE_AND_NULL(str);
  22588. FREE_AND_NULL(strB);
  22589. }
  22590. }
  22591. }
  22592. matcher = matcher->next;
  22593. }
  22594. /* TODO: Return an error if any error encountered. */
  22595. return (0);
  22596. }
  22597. /************************************************************************
  22598. * *
  22599. * XML Reader validation code *
  22600. * *
  22601. ************************************************************************/
  22602. static xmlSchemaAttrInfoPtr
  22603. xmlSchemaGetFreshAttrInfo(xmlSchemaValidCtxtPtr vctxt)
  22604. {
  22605. xmlSchemaAttrInfoPtr iattr;
  22606. /*
  22607. * Grow/create list of attribute infos.
  22608. */
  22609. if (vctxt->attrInfos == NULL) {
  22610. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22611. xmlMalloc(sizeof(xmlSchemaAttrInfoPtr));
  22612. vctxt->sizeAttrInfos = 1;
  22613. if (vctxt->attrInfos == NULL) {
  22614. xmlSchemaVErrMemory(vctxt,
  22615. "allocating attribute info list", NULL);
  22616. return (NULL);
  22617. }
  22618. } else if (vctxt->sizeAttrInfos <= vctxt->nbAttrInfos) {
  22619. vctxt->sizeAttrInfos++;
  22620. vctxt->attrInfos = (xmlSchemaAttrInfoPtr *)
  22621. xmlRealloc(vctxt->attrInfos,
  22622. vctxt->sizeAttrInfos * sizeof(xmlSchemaAttrInfoPtr));
  22623. if (vctxt->attrInfos == NULL) {
  22624. xmlSchemaVErrMemory(vctxt,
  22625. "re-allocating attribute info list", NULL);
  22626. return (NULL);
  22627. }
  22628. } else {
  22629. iattr = vctxt->attrInfos[vctxt->nbAttrInfos++];
  22630. if (iattr->localName != NULL) {
  22631. VERROR_INT("xmlSchemaGetFreshAttrInfo",
  22632. "attr info not cleared");
  22633. return (NULL);
  22634. }
  22635. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22636. return (iattr);
  22637. }
  22638. /*
  22639. * Create an attribute info.
  22640. */
  22641. iattr = (xmlSchemaAttrInfoPtr)
  22642. xmlMalloc(sizeof(xmlSchemaAttrInfo));
  22643. if (iattr == NULL) {
  22644. xmlSchemaVErrMemory(vctxt, "creating new attribute info", NULL);
  22645. return (NULL);
  22646. }
  22647. memset(iattr, 0, sizeof(xmlSchemaAttrInfo));
  22648. iattr->nodeType = XML_ATTRIBUTE_NODE;
  22649. vctxt->attrInfos[vctxt->nbAttrInfos++] = iattr;
  22650. return (iattr);
  22651. }
  22652. static int
  22653. xmlSchemaValidatorPushAttribute(xmlSchemaValidCtxtPtr vctxt,
  22654. xmlNodePtr attrNode,
  22655. int nodeLine,
  22656. const xmlChar *localName,
  22657. const xmlChar *nsName,
  22658. int ownedNames,
  22659. xmlChar *value,
  22660. int ownedValue)
  22661. {
  22662. xmlSchemaAttrInfoPtr attr;
  22663. attr = xmlSchemaGetFreshAttrInfo(vctxt);
  22664. if (attr == NULL) {
  22665. VERROR_INT("xmlSchemaPushAttribute",
  22666. "calling xmlSchemaGetFreshAttrInfo()");
  22667. return (-1);
  22668. }
  22669. attr->node = attrNode;
  22670. attr->nodeLine = nodeLine;
  22671. attr->state = XML_SCHEMAS_ATTR_UNKNOWN;
  22672. attr->localName = localName;
  22673. attr->nsName = nsName;
  22674. if (ownedNames)
  22675. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  22676. /*
  22677. * Evaluate if it's an XSI attribute.
  22678. */
  22679. if (nsName != NULL) {
  22680. if (xmlStrEqual(localName, BAD_CAST "nil")) {
  22681. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22682. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NIL;
  22683. }
  22684. } else if (xmlStrEqual(localName, BAD_CAST "type")) {
  22685. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22686. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_TYPE;
  22687. }
  22688. } else if (xmlStrEqual(localName, BAD_CAST "schemaLocation")) {
  22689. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22690. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_SCHEMA_LOC;
  22691. }
  22692. } else if (xmlStrEqual(localName, BAD_CAST "noNamespaceSchemaLocation")) {
  22693. if (xmlStrEqual(attr->nsName, xmlSchemaInstanceNs)) {
  22694. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XSI_NO_NS_SCHEMA_LOC;
  22695. }
  22696. } else if (xmlStrEqual(attr->nsName, xmlNamespaceNs)) {
  22697. attr->metaType = XML_SCHEMA_ATTR_INFO_META_XMLNS;
  22698. }
  22699. }
  22700. attr->value = value;
  22701. if (ownedValue)
  22702. attr->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  22703. if (attr->metaType != 0)
  22704. attr->state = XML_SCHEMAS_ATTR_META;
  22705. return (0);
  22706. }
  22707. /**
  22708. * xmlSchemaClearElemInfo:
  22709. * @vctxt: the WXS validation context
  22710. * @ielem: the element information item
  22711. */
  22712. static void
  22713. xmlSchemaClearElemInfo(xmlSchemaValidCtxtPtr vctxt,
  22714. xmlSchemaNodeInfoPtr ielem)
  22715. {
  22716. ielem->hasKeyrefs = 0;
  22717. ielem->appliedXPath = 0;
  22718. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  22719. FREE_AND_NULL(ielem->localName);
  22720. FREE_AND_NULL(ielem->nsName);
  22721. } else {
  22722. ielem->localName = NULL;
  22723. ielem->nsName = NULL;
  22724. }
  22725. if (ielem->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  22726. FREE_AND_NULL(ielem->value);
  22727. } else {
  22728. ielem->value = NULL;
  22729. }
  22730. if (ielem->val != NULL) {
  22731. /*
  22732. * PSVI TODO: Be careful not to free it when the value is
  22733. * exposed via PSVI.
  22734. */
  22735. xmlSchemaFreeValue(ielem->val);
  22736. ielem->val = NULL;
  22737. }
  22738. if (ielem->idcMatchers != NULL) {
  22739. /*
  22740. * REVISIT OPTIMIZE TODO: Use a pool of IDC matchers.
  22741. * Does it work?
  22742. */
  22743. xmlSchemaIDCReleaseMatcherList(vctxt, ielem->idcMatchers);
  22744. #if 0
  22745. xmlSchemaIDCFreeMatcherList(ielem->idcMatchers);
  22746. #endif
  22747. ielem->idcMatchers = NULL;
  22748. }
  22749. if (ielem->idcTable != NULL) {
  22750. /*
  22751. * OPTIMIZE TODO: Use a pool of IDC tables??.
  22752. */
  22753. xmlSchemaIDCFreeIDCTable(ielem->idcTable);
  22754. ielem->idcTable = NULL;
  22755. }
  22756. if (ielem->regexCtxt != NULL) {
  22757. xmlRegFreeExecCtxt(ielem->regexCtxt);
  22758. ielem->regexCtxt = NULL;
  22759. }
  22760. if (ielem->nsBindings != NULL) {
  22761. xmlFree((xmlChar **)ielem->nsBindings);
  22762. ielem->nsBindings = NULL;
  22763. ielem->nbNsBindings = 0;
  22764. ielem->sizeNsBindings = 0;
  22765. }
  22766. }
  22767. /**
  22768. * xmlSchemaGetFreshElemInfo:
  22769. * @vctxt: the schema validation context
  22770. *
  22771. * Creates/reuses and initializes the element info item for
  22772. * the current tree depth.
  22773. *
  22774. * Returns the element info item or NULL on API or internal errors.
  22775. */
  22776. static xmlSchemaNodeInfoPtr
  22777. xmlSchemaGetFreshElemInfo(xmlSchemaValidCtxtPtr vctxt)
  22778. {
  22779. xmlSchemaNodeInfoPtr info = NULL;
  22780. if (vctxt->depth > vctxt->sizeElemInfos) {
  22781. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22782. "inconsistent depth encountered");
  22783. return (NULL);
  22784. }
  22785. if (vctxt->elemInfos == NULL) {
  22786. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22787. xmlMalloc(10 * sizeof(xmlSchemaNodeInfoPtr));
  22788. if (vctxt->elemInfos == NULL) {
  22789. xmlSchemaVErrMemory(vctxt,
  22790. "allocating the element info array", NULL);
  22791. return (NULL);
  22792. }
  22793. memset(vctxt->elemInfos, 0, 10 * sizeof(xmlSchemaNodeInfoPtr));
  22794. vctxt->sizeElemInfos = 10;
  22795. } else if (vctxt->sizeElemInfos <= vctxt->depth) {
  22796. int i = vctxt->sizeElemInfos;
  22797. vctxt->sizeElemInfos *= 2;
  22798. vctxt->elemInfos = (xmlSchemaNodeInfoPtr *)
  22799. xmlRealloc(vctxt->elemInfos, vctxt->sizeElemInfos *
  22800. sizeof(xmlSchemaNodeInfoPtr));
  22801. if (vctxt->elemInfos == NULL) {
  22802. xmlSchemaVErrMemory(vctxt,
  22803. "re-allocating the element info array", NULL);
  22804. return (NULL);
  22805. }
  22806. /*
  22807. * We need the new memory to be NULLed.
  22808. * TODO: Use memset instead?
  22809. */
  22810. for (; i < vctxt->sizeElemInfos; i++)
  22811. vctxt->elemInfos[i] = NULL;
  22812. } else
  22813. info = vctxt->elemInfos[vctxt->depth];
  22814. if (info == NULL) {
  22815. info = (xmlSchemaNodeInfoPtr)
  22816. xmlMalloc(sizeof(xmlSchemaNodeInfo));
  22817. if (info == NULL) {
  22818. xmlSchemaVErrMemory(vctxt,
  22819. "allocating an element info", NULL);
  22820. return (NULL);
  22821. }
  22822. vctxt->elemInfos[vctxt->depth] = info;
  22823. } else {
  22824. if (info->localName != NULL) {
  22825. VERROR_INT("xmlSchemaGetFreshElemInfo",
  22826. "elem info has not been cleared");
  22827. return (NULL);
  22828. }
  22829. }
  22830. memset(info, 0, sizeof(xmlSchemaNodeInfo));
  22831. info->nodeType = XML_ELEMENT_NODE;
  22832. info->depth = vctxt->depth;
  22833. return (info);
  22834. }
  22835. #define ACTIVATE_ATTRIBUTE(item) vctxt->inode = (xmlSchemaNodeInfoPtr) item;
  22836. #define ACTIVATE_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth];
  22837. #define ACTIVATE_PARENT_ELEM vctxt->inode = vctxt->elemInfos[vctxt->depth -1];
  22838. static int
  22839. xmlSchemaValidateFacets(xmlSchemaAbstractCtxtPtr actxt,
  22840. xmlNodePtr node,
  22841. xmlSchemaTypePtr type,
  22842. xmlSchemaValType valType,
  22843. const xmlChar * value,
  22844. xmlSchemaValPtr val,
  22845. unsigned long length,
  22846. int fireErrors)
  22847. {
  22848. int ret, error = 0;
  22849. xmlSchemaTypePtr tmpType;
  22850. xmlSchemaFacetLinkPtr facetLink;
  22851. xmlSchemaFacetPtr facet;
  22852. unsigned long len = 0;
  22853. xmlSchemaWhitespaceValueType ws;
  22854. /*
  22855. * In Libxml2, derived built-in types have currently no explicit facets.
  22856. */
  22857. if (type->type == XML_SCHEMA_TYPE_BASIC)
  22858. return (0);
  22859. /*
  22860. * NOTE: Do not jump away, if the facetSet of the given type is
  22861. * empty: until now, "pattern" and "enumeration" facets of the
  22862. * *base types* need to be checked as well.
  22863. */
  22864. if (type->facetSet == NULL)
  22865. goto pattern_and_enum;
  22866. if (! WXS_IS_ATOMIC(type)) {
  22867. if (WXS_IS_LIST(type))
  22868. goto WXS_IS_LIST;
  22869. else
  22870. goto pattern_and_enum;
  22871. }
  22872. /*
  22873. * Whitespace handling is only of importance for string-based
  22874. * types.
  22875. */
  22876. tmpType = xmlSchemaGetPrimitiveType(type);
  22877. if ((tmpType->builtInType == XML_SCHEMAS_STRING) ||
  22878. WXS_IS_ANY_SIMPLE_TYPE(tmpType)) {
  22879. ws = xmlSchemaGetWhiteSpaceFacetValue(type);
  22880. } else
  22881. ws = XML_SCHEMA_WHITESPACE_COLLAPSE;
  22882. /*
  22883. * If the value was not computed (for string or
  22884. * anySimpleType based types), then use the provided
  22885. * type.
  22886. */
  22887. if (val != NULL)
  22888. valType = xmlSchemaGetValType(val);
  22889. ret = 0;
  22890. for (facetLink = type->facetSet; facetLink != NULL;
  22891. facetLink = facetLink->next) {
  22892. /*
  22893. * Skip the pattern "whiteSpace": it is used to
  22894. * format the character content beforehand.
  22895. */
  22896. switch (facetLink->facet->type) {
  22897. case XML_SCHEMA_FACET_WHITESPACE:
  22898. case XML_SCHEMA_FACET_PATTERN:
  22899. case XML_SCHEMA_FACET_ENUMERATION:
  22900. continue;
  22901. case XML_SCHEMA_FACET_LENGTH:
  22902. case XML_SCHEMA_FACET_MINLENGTH:
  22903. case XML_SCHEMA_FACET_MAXLENGTH:
  22904. ret = xmlSchemaValidateLengthFacetWhtsp(facetLink->facet,
  22905. valType, value, val, &len, ws);
  22906. break;
  22907. default:
  22908. ret = xmlSchemaValidateFacetWhtsp(facetLink->facet, ws,
  22909. valType, value, val, ws);
  22910. break;
  22911. }
  22912. if (ret < 0) {
  22913. AERROR_INT("xmlSchemaValidateFacets",
  22914. "validating against a atomic type facet");
  22915. return (-1);
  22916. } else if (ret > 0) {
  22917. if (fireErrors)
  22918. xmlSchemaFacetErr(actxt, ret, node,
  22919. value, len, type, facetLink->facet, NULL, NULL, NULL);
  22920. else
  22921. return (ret);
  22922. if (error == 0)
  22923. error = ret;
  22924. }
  22925. ret = 0;
  22926. }
  22927. WXS_IS_LIST:
  22928. if (! WXS_IS_LIST(type))
  22929. goto pattern_and_enum;
  22930. /*
  22931. * "length", "minLength" and "maxLength" of list types.
  22932. */
  22933. ret = 0;
  22934. for (facetLink = type->facetSet; facetLink != NULL;
  22935. facetLink = facetLink->next) {
  22936. switch (facetLink->facet->type) {
  22937. case XML_SCHEMA_FACET_LENGTH:
  22938. case XML_SCHEMA_FACET_MINLENGTH:
  22939. case XML_SCHEMA_FACET_MAXLENGTH:
  22940. ret = xmlSchemaValidateListSimpleTypeFacet(facetLink->facet,
  22941. value, length, NULL);
  22942. break;
  22943. default:
  22944. continue;
  22945. }
  22946. if (ret < 0) {
  22947. AERROR_INT("xmlSchemaValidateFacets",
  22948. "validating against a list type facet");
  22949. return (-1);
  22950. } else if (ret > 0) {
  22951. if (fireErrors)
  22952. xmlSchemaFacetErr(actxt, ret, node,
  22953. value, length, type, facetLink->facet, NULL, NULL, NULL);
  22954. else
  22955. return (ret);
  22956. if (error == 0)
  22957. error = ret;
  22958. }
  22959. ret = 0;
  22960. }
  22961. pattern_and_enum:
  22962. if (error >= 0) {
  22963. int found = 0;
  22964. /*
  22965. * Process enumerations. Facet values are in the value space
  22966. * of the defining type's base type. This seems to be a bug in the
  22967. * XML Schema 1.0 spec. Use the whitespace type of the base type.
  22968. * Only the first set of enumerations in the ancestor-or-self axis
  22969. * is used for validation.
  22970. */
  22971. ret = 0;
  22972. tmpType = type;
  22973. do {
  22974. for (facet = tmpType->facets; facet != NULL; facet = facet->next) {
  22975. if (facet->type != XML_SCHEMA_FACET_ENUMERATION)
  22976. continue;
  22977. found = 1;
  22978. ret = xmlSchemaAreValuesEqual(facet->val, val);
  22979. if (ret == 1)
  22980. break;
  22981. else if (ret < 0) {
  22982. AERROR_INT("xmlSchemaValidateFacets",
  22983. "validating against an enumeration facet");
  22984. return (-1);
  22985. }
  22986. }
  22987. if (ret != 0)
  22988. break;
  22989. /*
  22990. * Break on the first set of enumerations. Any additional
  22991. * enumerations which might be existent on the ancestors
  22992. * of the current type are restricted by this set; thus
  22993. * *must* *not* be taken into account.
  22994. */
  22995. if (found)
  22996. break;
  22997. tmpType = tmpType->baseType;
  22998. } while ((tmpType != NULL) &&
  22999. (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  23000. if (found && (ret == 0)) {
  23001. ret = XML_SCHEMAV_CVC_ENUMERATION_VALID;
  23002. if (fireErrors) {
  23003. xmlSchemaFacetErr(actxt, ret, node,
  23004. value, 0, type, NULL, NULL, NULL, NULL);
  23005. } else
  23006. return (ret);
  23007. if (error == 0)
  23008. error = ret;
  23009. }
  23010. }
  23011. if (error >= 0) {
  23012. int found;
  23013. /*
  23014. * Process patters. Pattern facets are ORed at type level
  23015. * and ANDed if derived. Walk the base type axis.
  23016. */
  23017. tmpType = type;
  23018. facet = NULL;
  23019. do {
  23020. found = 0;
  23021. for (facetLink = tmpType->facetSet; facetLink != NULL;
  23022. facetLink = facetLink->next) {
  23023. if (facetLink->facet->type != XML_SCHEMA_FACET_PATTERN)
  23024. continue;
  23025. found = 1;
  23026. /*
  23027. * NOTE that for patterns, @value needs to be the
  23028. * normalized value.
  23029. */
  23030. ret = xmlRegexpExec(facetLink->facet->regexp, value);
  23031. if (ret == 1)
  23032. break;
  23033. else if (ret < 0) {
  23034. AERROR_INT("xmlSchemaValidateFacets",
  23035. "validating against a pattern facet");
  23036. return (-1);
  23037. } else {
  23038. /*
  23039. * Save the last non-validating facet.
  23040. */
  23041. facet = facetLink->facet;
  23042. }
  23043. }
  23044. if (found && (ret != 1)) {
  23045. ret = XML_SCHEMAV_CVC_PATTERN_VALID;
  23046. if (fireErrors) {
  23047. xmlSchemaFacetErr(actxt, ret, node,
  23048. value, 0, type, facet, NULL, NULL, NULL);
  23049. } else
  23050. return (ret);
  23051. if (error == 0)
  23052. error = ret;
  23053. break;
  23054. }
  23055. tmpType = tmpType->baseType;
  23056. } while ((tmpType != NULL) && (tmpType->type != XML_SCHEMA_TYPE_BASIC));
  23057. }
  23058. return (error);
  23059. }
  23060. static xmlChar *
  23061. xmlSchemaNormalizeValue(xmlSchemaTypePtr type,
  23062. const xmlChar *value)
  23063. {
  23064. switch (xmlSchemaGetWhiteSpaceFacetValue(type)) {
  23065. case XML_SCHEMA_WHITESPACE_COLLAPSE:
  23066. return (xmlSchemaCollapseString(value));
  23067. case XML_SCHEMA_WHITESPACE_REPLACE:
  23068. return (xmlSchemaWhiteSpaceReplace(value));
  23069. default:
  23070. return (NULL);
  23071. }
  23072. }
  23073. static int
  23074. xmlSchemaValidateQName(xmlSchemaValidCtxtPtr vctxt,
  23075. const xmlChar *value,
  23076. xmlSchemaValPtr *val,
  23077. int valNeeded)
  23078. {
  23079. int ret;
  23080. const xmlChar *nsName;
  23081. xmlChar *local, *prefix = NULL;
  23082. ret = xmlValidateQName(value, 1);
  23083. if (ret != 0) {
  23084. if (ret == -1) {
  23085. VERROR_INT("xmlSchemaValidateQName",
  23086. "calling xmlValidateQName()");
  23087. return (-1);
  23088. }
  23089. return( XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1);
  23090. }
  23091. /*
  23092. * NOTE: xmlSplitQName2 will always return a duplicated
  23093. * strings.
  23094. */
  23095. local = xmlSplitQName2(value, &prefix);
  23096. if (local == NULL)
  23097. local = xmlStrdup(value);
  23098. /*
  23099. * OPTIMIZE TODO: Use flags for:
  23100. * - is there any namespace binding?
  23101. * - is there a default namespace?
  23102. */
  23103. nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23104. if (prefix != NULL) {
  23105. xmlFree(prefix);
  23106. /*
  23107. * A namespace must be found if the prefix is
  23108. * NOT NULL.
  23109. */
  23110. if (nsName == NULL) {
  23111. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23112. xmlSchemaCustomErr(ACTXT_CAST vctxt, ret, NULL,
  23113. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23114. "The QName value '%s' has no "
  23115. "corresponding namespace declaration in "
  23116. "scope", value, NULL);
  23117. if (local != NULL)
  23118. xmlFree(local);
  23119. return (ret);
  23120. }
  23121. }
  23122. if (valNeeded && val) {
  23123. if (nsName != NULL)
  23124. *val = xmlSchemaNewQNameValue(
  23125. BAD_CAST xmlStrdup(nsName), BAD_CAST local);
  23126. else
  23127. *val = xmlSchemaNewQNameValue(NULL,
  23128. BAD_CAST local);
  23129. } else
  23130. xmlFree(local);
  23131. return (0);
  23132. }
  23133. /*
  23134. * cvc-simple-type
  23135. */
  23136. static int
  23137. xmlSchemaVCheckCVCSimpleType(xmlSchemaAbstractCtxtPtr actxt,
  23138. xmlNodePtr node,
  23139. xmlSchemaTypePtr type,
  23140. const xmlChar *value,
  23141. xmlSchemaValPtr *retVal,
  23142. int fireErrors,
  23143. int normalize,
  23144. int isNormalized)
  23145. {
  23146. int ret = 0, valNeeded = (retVal) ? 1 : 0;
  23147. xmlSchemaValPtr val = NULL;
  23148. /* xmlSchemaWhitespaceValueType ws; */
  23149. xmlChar *normValue = NULL;
  23150. #define NORMALIZE(atype) \
  23151. if ((! isNormalized) && \
  23152. (normalize || (type->flags & XML_SCHEMAS_TYPE_NORMVALUENEEDED))) { \
  23153. normValue = xmlSchemaNormalizeValue(atype, value); \
  23154. if (normValue != NULL) \
  23155. value = normValue; \
  23156. isNormalized = 1; \
  23157. }
  23158. if ((retVal != NULL) && (*retVal != NULL)) {
  23159. xmlSchemaFreeValue(*retVal);
  23160. *retVal = NULL;
  23161. }
  23162. /*
  23163. * 3.14.4 Simple Type Definition Validation Rules
  23164. * Validation Rule: String Valid
  23165. */
  23166. /*
  23167. * 1 It is schema-valid with respect to that definition as defined
  23168. * by Datatype Valid in [XML Schemas: Datatypes].
  23169. */
  23170. /*
  23171. * 2.1 If The definition is ENTITY or is validly derived from ENTITY given
  23172. * the empty set, as defined in Type Derivation OK (Simple) ($3.14.6), then
  23173. * the string must be a `declared entity name`.
  23174. */
  23175. /*
  23176. * 2.2 If The definition is ENTITIES or is validly derived from ENTITIES
  23177. * given the empty set, as defined in Type Derivation OK (Simple) ($3.14.6),
  23178. * then every whitespace-delimited substring of the string must be a `declared
  23179. * entity name`.
  23180. */
  23181. /*
  23182. * 2.3 otherwise no further condition applies.
  23183. */
  23184. if ((! valNeeded) && (type->flags & XML_SCHEMAS_TYPE_FACETSNEEDVALUE))
  23185. valNeeded = 1;
  23186. if (value == NULL)
  23187. value = BAD_CAST "";
  23188. if (WXS_IS_ANY_SIMPLE_TYPE(type) || WXS_IS_ATOMIC(type)) {
  23189. xmlSchemaTypePtr biType; /* The built-in type. */
  23190. /*
  23191. * SPEC (1.2.1) "if {variety} is `atomic` then the string must `match`
  23192. * a literal in the `lexical space` of {base type definition}"
  23193. */
  23194. /*
  23195. * Whitespace-normalize.
  23196. */
  23197. NORMALIZE(type);
  23198. if (type->type != XML_SCHEMA_TYPE_BASIC) {
  23199. /*
  23200. * Get the built-in type.
  23201. */
  23202. biType = type->baseType;
  23203. while ((biType != NULL) &&
  23204. (biType->type != XML_SCHEMA_TYPE_BASIC))
  23205. biType = biType->baseType;
  23206. if (biType == NULL) {
  23207. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23208. "could not get the built-in type");
  23209. goto internal_error;
  23210. }
  23211. } else
  23212. biType = type;
  23213. /*
  23214. * NOTATIONs need to be processed here, since they need
  23215. * to lookup in the hashtable of NOTATION declarations of the schema.
  23216. */
  23217. if (actxt->type == XML_SCHEMA_CTXT_VALIDATOR) {
  23218. switch (biType->builtInType) {
  23219. case XML_SCHEMAS_NOTATION:
  23220. ret = xmlSchemaValidateNotation(
  23221. (xmlSchemaValidCtxtPtr) actxt,
  23222. ((xmlSchemaValidCtxtPtr) actxt)->schema,
  23223. NULL, value, &val, valNeeded);
  23224. break;
  23225. case XML_SCHEMAS_QNAME:
  23226. ret = xmlSchemaValidateQName((xmlSchemaValidCtxtPtr) actxt,
  23227. value, &val, valNeeded);
  23228. break;
  23229. default:
  23230. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23231. if (valNeeded)
  23232. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23233. value, &val, node);
  23234. else
  23235. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23236. value, NULL, node);
  23237. break;
  23238. }
  23239. } else if (actxt->type == XML_SCHEMA_CTXT_PARSER) {
  23240. switch (biType->builtInType) {
  23241. case XML_SCHEMAS_NOTATION:
  23242. ret = xmlSchemaValidateNotation(NULL,
  23243. ((xmlSchemaParserCtxtPtr) actxt)->schema, node,
  23244. value, &val, valNeeded);
  23245. break;
  23246. default:
  23247. /* ws = xmlSchemaGetWhiteSpaceFacetValue(type); */
  23248. if (valNeeded)
  23249. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23250. value, &val, node);
  23251. else
  23252. ret = xmlSchemaValPredefTypeNodeNoNorm(biType,
  23253. value, NULL, node);
  23254. break;
  23255. }
  23256. } else {
  23257. /*
  23258. * Validation via a public API is not implemented yet.
  23259. */
  23260. TODO
  23261. goto internal_error;
  23262. }
  23263. if (ret != 0) {
  23264. if (ret < 0) {
  23265. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23266. "validating against a built-in type");
  23267. goto internal_error;
  23268. }
  23269. if (WXS_IS_LIST(type))
  23270. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23271. else
  23272. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23273. }
  23274. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23275. /*
  23276. * Check facets.
  23277. */
  23278. ret = xmlSchemaValidateFacets(actxt, node, type,
  23279. (xmlSchemaValType) biType->builtInType, value, val,
  23280. 0, fireErrors);
  23281. if (ret != 0) {
  23282. if (ret < 0) {
  23283. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23284. "validating facets of atomic simple type");
  23285. goto internal_error;
  23286. }
  23287. if (WXS_IS_LIST(type))
  23288. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23289. else
  23290. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1;
  23291. }
  23292. }
  23293. else if (fireErrors && (ret > 0))
  23294. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23295. } else if (WXS_IS_LIST(type)) {
  23296. xmlSchemaTypePtr itemType;
  23297. const xmlChar *cur, *end;
  23298. xmlChar *tmpValue = NULL;
  23299. unsigned long len = 0;
  23300. xmlSchemaValPtr prevVal = NULL, curVal = NULL;
  23301. /* 1.2.2 if {variety} is `list` then the string must be a sequence
  23302. * of white space separated tokens, each of which `match`es a literal
  23303. * in the `lexical space` of {item type definition}
  23304. */
  23305. /*
  23306. * Note that XML_SCHEMAS_TYPE_NORMVALUENEEDED will be set if
  23307. * the list type has an enum or pattern facet.
  23308. */
  23309. NORMALIZE(type);
  23310. /*
  23311. * VAL TODO: Optimize validation of empty values.
  23312. * VAL TODO: We do not have computed values for lists.
  23313. */
  23314. itemType = WXS_LIST_ITEMTYPE(type);
  23315. cur = value;
  23316. do {
  23317. while (IS_BLANK_CH(*cur))
  23318. cur++;
  23319. end = cur;
  23320. while ((*end != 0) && (!(IS_BLANK_CH(*end))))
  23321. end++;
  23322. if (end == cur)
  23323. break;
  23324. tmpValue = xmlStrndup(cur, end - cur);
  23325. len++;
  23326. if (valNeeded)
  23327. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23328. tmpValue, &curVal, fireErrors, 0, 1);
  23329. else
  23330. ret = xmlSchemaVCheckCVCSimpleType(actxt, node, itemType,
  23331. tmpValue, NULL, fireErrors, 0, 1);
  23332. FREE_AND_NULL(tmpValue);
  23333. if (curVal != NULL) {
  23334. /*
  23335. * Add to list of computed values.
  23336. */
  23337. if (val == NULL)
  23338. val = curVal;
  23339. else
  23340. xmlSchemaValueAppend(prevVal, curVal);
  23341. prevVal = curVal;
  23342. curVal = NULL;
  23343. }
  23344. if (ret != 0) {
  23345. if (ret < 0) {
  23346. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23347. "validating an item of list simple type");
  23348. goto internal_error;
  23349. }
  23350. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23351. break;
  23352. }
  23353. cur = end;
  23354. } while (*cur != 0);
  23355. FREE_AND_NULL(tmpValue);
  23356. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23357. /*
  23358. * Apply facets (pattern, enumeration).
  23359. */
  23360. ret = xmlSchemaValidateFacets(actxt, node, type,
  23361. XML_SCHEMAS_UNKNOWN, value, val,
  23362. len, fireErrors);
  23363. if (ret != 0) {
  23364. if (ret < 0) {
  23365. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23366. "validating facets of list simple type");
  23367. goto internal_error;
  23368. }
  23369. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_2;
  23370. }
  23371. }
  23372. if (fireErrors && (ret > 0)) {
  23373. /*
  23374. * Report the normalized value.
  23375. */
  23376. normalize = 1;
  23377. NORMALIZE(type);
  23378. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23379. }
  23380. } else if (WXS_IS_UNION(type)) {
  23381. xmlSchemaTypeLinkPtr memberLink;
  23382. /*
  23383. * TODO: For all datatypes `derived` by `union` whiteSpace does
  23384. * not apply directly; however, the normalization behavior of `union`
  23385. * types is controlled by the value of whiteSpace on that one of the
  23386. * `memberTypes` against which the `union` is successfully validated.
  23387. *
  23388. * This means that the value is normalized by the first validating
  23389. * member type, then the facets of the union type are applied. This
  23390. * needs changing of the value!
  23391. */
  23392. /*
  23393. * 1.2.3 if {variety} is `union` then the string must `match` a
  23394. * literal in the `lexical space` of at least one member of
  23395. * {member type definitions}
  23396. */
  23397. memberLink = xmlSchemaGetUnionSimpleTypeMemberTypes(type);
  23398. if (memberLink == NULL) {
  23399. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23400. "union simple type has no member types");
  23401. goto internal_error;
  23402. }
  23403. /*
  23404. * Always normalize union type values, since we currently
  23405. * cannot store the whitespace information with the value
  23406. * itself; otherwise a later value-comparison would be
  23407. * not possible.
  23408. */
  23409. while (memberLink != NULL) {
  23410. if (valNeeded)
  23411. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23412. memberLink->type, value, &val, 0, 1, 0);
  23413. else
  23414. ret = xmlSchemaVCheckCVCSimpleType(actxt, node,
  23415. memberLink->type, value, NULL, 0, 1, 0);
  23416. if (ret <= 0)
  23417. break;
  23418. memberLink = memberLink->next;
  23419. }
  23420. if (ret != 0) {
  23421. if (ret < 0) {
  23422. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23423. "validating members of union simple type");
  23424. goto internal_error;
  23425. }
  23426. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23427. }
  23428. /*
  23429. * Apply facets (pattern, enumeration).
  23430. */
  23431. if ((ret == 0) && (type->flags & XML_SCHEMAS_TYPE_HAS_FACETS)) {
  23432. /*
  23433. * The normalization behavior of `union` types is controlled by
  23434. * the value of whiteSpace on that one of the `memberTypes`
  23435. * against which the `union` is successfully validated.
  23436. */
  23437. NORMALIZE(memberLink->type);
  23438. ret = xmlSchemaValidateFacets(actxt, node, type,
  23439. XML_SCHEMAS_UNKNOWN, value, val,
  23440. 0, fireErrors);
  23441. if (ret != 0) {
  23442. if (ret < 0) {
  23443. AERROR_INT("xmlSchemaVCheckCVCSimpleType",
  23444. "validating facets of union simple type");
  23445. goto internal_error;
  23446. }
  23447. ret = XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_3;
  23448. }
  23449. }
  23450. if (fireErrors && (ret > 0))
  23451. xmlSchemaSimpleTypeErr(actxt, ret, node, value, type, 1);
  23452. }
  23453. if (normValue != NULL)
  23454. xmlFree(normValue);
  23455. if (ret == 0) {
  23456. if (retVal != NULL)
  23457. *retVal = val;
  23458. else if (val != NULL)
  23459. xmlSchemaFreeValue(val);
  23460. } else if (val != NULL)
  23461. xmlSchemaFreeValue(val);
  23462. return (ret);
  23463. internal_error:
  23464. if (normValue != NULL)
  23465. xmlFree(normValue);
  23466. if (val != NULL)
  23467. xmlSchemaFreeValue(val);
  23468. return (-1);
  23469. }
  23470. static int
  23471. xmlSchemaVExpandQName(xmlSchemaValidCtxtPtr vctxt,
  23472. const xmlChar *value,
  23473. const xmlChar **nsName,
  23474. const xmlChar **localName)
  23475. {
  23476. int ret = 0;
  23477. if ((nsName == NULL) || (localName == NULL))
  23478. return (-1);
  23479. *nsName = NULL;
  23480. *localName = NULL;
  23481. ret = xmlValidateQName(value, 1);
  23482. if (ret == -1)
  23483. return (-1);
  23484. if (ret > 0) {
  23485. xmlSchemaSimpleTypeErr(ACTXT_CAST vctxt,
  23486. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23487. value, xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME), 1);
  23488. return (1);
  23489. }
  23490. {
  23491. xmlChar *local = NULL;
  23492. xmlChar *prefix;
  23493. /*
  23494. * NOTE: xmlSplitQName2 will return a duplicated
  23495. * string.
  23496. */
  23497. local = xmlSplitQName2(value, &prefix);
  23498. if (local == NULL)
  23499. *localName = xmlDictLookup(vctxt->dict, value, -1);
  23500. else {
  23501. *localName = xmlDictLookup(vctxt->dict, local, -1);
  23502. xmlFree(local);
  23503. }
  23504. *nsName = xmlSchemaLookupNamespace(vctxt, prefix);
  23505. if (prefix != NULL) {
  23506. xmlFree(prefix);
  23507. /*
  23508. * A namespace must be found if the prefix is NOT NULL.
  23509. */
  23510. if (*nsName == NULL) {
  23511. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23512. XML_SCHEMAV_CVC_DATATYPE_VALID_1_2_1, NULL,
  23513. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23514. "The QName value '%s' has no "
  23515. "corresponding namespace declaration in scope",
  23516. value, NULL);
  23517. return (2);
  23518. }
  23519. }
  23520. }
  23521. return (0);
  23522. }
  23523. static int
  23524. xmlSchemaProcessXSIType(xmlSchemaValidCtxtPtr vctxt,
  23525. xmlSchemaAttrInfoPtr iattr,
  23526. xmlSchemaTypePtr *localType,
  23527. xmlSchemaElementPtr elemDecl)
  23528. {
  23529. int ret = 0;
  23530. /*
  23531. * cvc-elt (3.3.4) : (4)
  23532. * AND
  23533. * Schema-Validity Assessment (Element) (cvc-assess-elt)
  23534. * (1.2.1.2.1) - (1.2.1.2.4)
  23535. * Handle 'xsi:type'.
  23536. */
  23537. if (localType == NULL)
  23538. return (-1);
  23539. *localType = NULL;
  23540. if (iattr == NULL)
  23541. return (0);
  23542. else {
  23543. const xmlChar *nsName = NULL, *local = NULL;
  23544. /*
  23545. * TODO: We should report a *warning* that the type was overridden
  23546. * by the instance.
  23547. */
  23548. ACTIVATE_ATTRIBUTE(iattr);
  23549. /*
  23550. * (cvc-elt) (3.3.4) : (4.1)
  23551. * (cvc-assess-elt) (1.2.1.2.2)
  23552. */
  23553. ret = xmlSchemaVExpandQName(vctxt, iattr->value,
  23554. &nsName, &local);
  23555. if (ret != 0) {
  23556. if (ret < 0) {
  23557. VERROR_INT("xmlSchemaValidateElementByDeclaration",
  23558. "calling xmlSchemaQNameExpand() to validate the "
  23559. "attribute 'xsi:type'");
  23560. goto internal_error;
  23561. }
  23562. goto exit;
  23563. }
  23564. /*
  23565. * (cvc-elt) (3.3.4) : (4.2)
  23566. * (cvc-assess-elt) (1.2.1.2.3)
  23567. */
  23568. *localType = xmlSchemaGetType(vctxt->schema, local, nsName);
  23569. if (*localType == NULL) {
  23570. xmlChar *str = NULL;
  23571. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23572. XML_SCHEMAV_CVC_ELT_4_2, NULL,
  23573. WXS_BASIC_CAST xmlSchemaGetBuiltInType(XML_SCHEMAS_QNAME),
  23574. "The QName value '%s' of the xsi:type attribute does not "
  23575. "resolve to a type definition",
  23576. xmlSchemaFormatQName(&str, nsName, local), NULL);
  23577. FREE_AND_NULL(str);
  23578. ret = vctxt->err;
  23579. goto exit;
  23580. }
  23581. if (elemDecl != NULL) {
  23582. int set = 0;
  23583. /*
  23584. * SPEC cvc-elt (3.3.4) : (4.3) (Type Derivation OK)
  23585. * "The `local type definition` must be validly
  23586. * derived from the {type definition} given the union of
  23587. * the {disallowed substitutions} and the {type definition}'s
  23588. * {prohibited substitutions}, as defined in
  23589. * Type Derivation OK (Complex) ($3.4.6)
  23590. * (if it is a complex type definition),
  23591. * or given {disallowed substitutions} as defined in Type
  23592. * Derivation OK (Simple) ($3.14.6) (if it is a simple type
  23593. * definition)."
  23594. *
  23595. * {disallowed substitutions}: the "block" on the element decl.
  23596. * {prohibited substitutions}: the "block" on the type def.
  23597. */
  23598. /*
  23599. * OPTIMIZE TODO: We could map types already evaluated
  23600. * to be validly derived from other types to avoid checking
  23601. * this over and over for the same types.
  23602. */
  23603. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_EXTENSION) ||
  23604. (elemDecl->subtypes->flags &
  23605. XML_SCHEMAS_TYPE_BLOCK_EXTENSION))
  23606. set |= SUBSET_EXTENSION;
  23607. if ((elemDecl->flags & XML_SCHEMAS_ELEM_BLOCK_RESTRICTION) ||
  23608. (elemDecl->subtypes->flags &
  23609. XML_SCHEMAS_TYPE_BLOCK_RESTRICTION))
  23610. set |= SUBSET_RESTRICTION;
  23611. /*
  23612. * REMOVED and CHANGED since this produced a parser context
  23613. * which adds to the string dict of the schema. So this would
  23614. * change the schema and we don't want this. We don't need
  23615. * the parser context anymore.
  23616. *
  23617. * if ((vctxt->pctxt == NULL) &&
  23618. * (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  23619. * return (-1);
  23620. */
  23621. if (xmlSchemaCheckCOSDerivedOK(ACTXT_CAST vctxt, *localType,
  23622. elemDecl->subtypes, set) != 0) {
  23623. xmlChar *str = NULL;
  23624. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  23625. XML_SCHEMAV_CVC_ELT_4_3, NULL, NULL,
  23626. "The type definition '%s', specified by xsi:type, is "
  23627. "blocked or not validly derived from the type definition "
  23628. "of the element declaration",
  23629. xmlSchemaFormatQName(&str,
  23630. (*localType)->targetNamespace,
  23631. (*localType)->name),
  23632. NULL);
  23633. FREE_AND_NULL(str);
  23634. ret = vctxt->err;
  23635. *localType = NULL;
  23636. }
  23637. }
  23638. }
  23639. exit:
  23640. ACTIVATE_ELEM;
  23641. return (ret);
  23642. internal_error:
  23643. ACTIVATE_ELEM;
  23644. return (-1);
  23645. }
  23646. static int
  23647. xmlSchemaValidateElemDecl(xmlSchemaValidCtxtPtr vctxt)
  23648. {
  23649. xmlSchemaElementPtr elemDecl = vctxt->inode->decl;
  23650. xmlSchemaTypePtr actualType;
  23651. /*
  23652. * cvc-elt (3.3.4) : 1
  23653. */
  23654. if (elemDecl == NULL) {
  23655. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL,
  23656. "No matching declaration available");
  23657. return (vctxt->err);
  23658. }
  23659. actualType = WXS_ELEM_TYPEDEF(elemDecl);
  23660. /*
  23661. * cvc-elt (3.3.4) : 2
  23662. */
  23663. if (elemDecl->flags & XML_SCHEMAS_ELEM_ABSTRACT) {
  23664. VERROR(XML_SCHEMAV_CVC_ELT_2, NULL,
  23665. "The element declaration is abstract");
  23666. return (vctxt->err);
  23667. }
  23668. if (actualType == NULL) {
  23669. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23670. "The type definition is absent");
  23671. return (XML_SCHEMAV_CVC_TYPE_1);
  23672. }
  23673. if (vctxt->nbAttrInfos != 0) {
  23674. int ret;
  23675. xmlSchemaAttrInfoPtr iattr;
  23676. /*
  23677. * cvc-elt (3.3.4) : 3
  23678. * Handle 'xsi:nil'.
  23679. */
  23680. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23681. XML_SCHEMA_ATTR_INFO_META_XSI_NIL);
  23682. if (iattr) {
  23683. ACTIVATE_ATTRIBUTE(iattr);
  23684. /*
  23685. * Validate the value.
  23686. */
  23687. ret = xmlSchemaVCheckCVCSimpleType(
  23688. ACTXT_CAST vctxt, NULL,
  23689. xmlSchemaGetBuiltInType(XML_SCHEMAS_BOOLEAN),
  23690. iattr->value, &(iattr->val), 1, 0, 0);
  23691. ACTIVATE_ELEM;
  23692. if (ret < 0) {
  23693. VERROR_INT("xmlSchemaValidateElemDecl",
  23694. "calling xmlSchemaVCheckCVCSimpleType() to "
  23695. "validate the attribute 'xsi:nil'");
  23696. return (-1);
  23697. }
  23698. if (ret == 0) {
  23699. if ((elemDecl->flags & XML_SCHEMAS_ELEM_NILLABLE) == 0) {
  23700. /*
  23701. * cvc-elt (3.3.4) : 3.1
  23702. */
  23703. VERROR(XML_SCHEMAV_CVC_ELT_3_1, NULL,
  23704. "The element is not 'nillable'");
  23705. /* Does not return an error on purpose. */
  23706. } else {
  23707. if (xmlSchemaValueGetAsBoolean(iattr->val)) {
  23708. /*
  23709. * cvc-elt (3.3.4) : 3.2.2
  23710. */
  23711. if ((elemDecl->flags & XML_SCHEMAS_ELEM_FIXED) &&
  23712. (elemDecl->value != NULL)) {
  23713. VERROR(XML_SCHEMAV_CVC_ELT_3_2_2, NULL,
  23714. "The element cannot be 'nilled' because "
  23715. "there is a fixed value constraint defined "
  23716. "for it");
  23717. /* Does not return an error on purpose. */
  23718. } else
  23719. vctxt->inode->flags |=
  23720. XML_SCHEMA_ELEM_INFO_NILLED;
  23721. }
  23722. }
  23723. }
  23724. }
  23725. /*
  23726. * cvc-elt (3.3.4) : 4
  23727. * Handle 'xsi:type'.
  23728. */
  23729. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  23730. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  23731. if (iattr) {
  23732. xmlSchemaTypePtr localType = NULL;
  23733. ret = xmlSchemaProcessXSIType(vctxt, iattr, &localType,
  23734. elemDecl);
  23735. if (ret != 0) {
  23736. if (ret == -1) {
  23737. VERROR_INT("xmlSchemaValidateElemDecl",
  23738. "calling xmlSchemaProcessXSIType() to "
  23739. "process the attribute 'xsi:type'");
  23740. return (-1);
  23741. }
  23742. /* Does not return an error on purpose. */
  23743. }
  23744. if (localType != NULL) {
  23745. vctxt->inode->flags |= XML_SCHEMA_ELEM_INFO_LOCAL_TYPE;
  23746. actualType = localType;
  23747. }
  23748. }
  23749. }
  23750. /*
  23751. * IDC: Register identity-constraint XPath matchers.
  23752. */
  23753. if ((elemDecl->idcs != NULL) &&
  23754. (xmlSchemaIDCRegisterMatchers(vctxt, elemDecl) == -1))
  23755. return (-1);
  23756. /*
  23757. * No actual type definition.
  23758. */
  23759. if (actualType == NULL) {
  23760. VERROR(XML_SCHEMAV_CVC_TYPE_1, NULL,
  23761. "The type definition is absent");
  23762. return (XML_SCHEMAV_CVC_TYPE_1);
  23763. }
  23764. /*
  23765. * Remember the actual type definition.
  23766. */
  23767. vctxt->inode->typeDef = actualType;
  23768. return (0);
  23769. }
  23770. static int
  23771. xmlSchemaVAttributesSimple(xmlSchemaValidCtxtPtr vctxt)
  23772. {
  23773. xmlSchemaAttrInfoPtr iattr;
  23774. int ret = 0, i;
  23775. /*
  23776. * SPEC cvc-type (3.1.1)
  23777. * "The attributes of must be empty, excepting those whose namespace
  23778. * name is identical to http://www.w3.org/2001/XMLSchema-instance and
  23779. * whose local name is one of type, nil, schemaLocation or
  23780. * noNamespaceSchemaLocation."
  23781. */
  23782. if (vctxt->nbAttrInfos == 0)
  23783. return (0);
  23784. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23785. iattr = vctxt->attrInfos[i];
  23786. if (! iattr->metaType) {
  23787. ACTIVATE_ATTRIBUTE(iattr)
  23788. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  23789. XML_SCHEMAV_CVC_TYPE_3_1_1, iattr, NULL);
  23790. ret = XML_SCHEMAV_CVC_TYPE_3_1_1;
  23791. }
  23792. }
  23793. ACTIVATE_ELEM
  23794. return (ret);
  23795. }
  23796. /*
  23797. * Cleanup currently used attribute infos.
  23798. */
  23799. static void
  23800. xmlSchemaClearAttrInfos(xmlSchemaValidCtxtPtr vctxt)
  23801. {
  23802. int i;
  23803. xmlSchemaAttrInfoPtr attr;
  23804. if (vctxt->nbAttrInfos == 0)
  23805. return;
  23806. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  23807. attr = vctxt->attrInfos[i];
  23808. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES) {
  23809. if (attr->localName != NULL)
  23810. xmlFree((xmlChar *) attr->localName);
  23811. if (attr->nsName != NULL)
  23812. xmlFree((xmlChar *) attr->nsName);
  23813. }
  23814. if (attr->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  23815. if (attr->value != NULL)
  23816. xmlFree((xmlChar *) attr->value);
  23817. }
  23818. if (attr->val != NULL) {
  23819. xmlSchemaFreeValue(attr->val);
  23820. attr->val = NULL;
  23821. }
  23822. memset(attr, 0, sizeof(xmlSchemaAttrInfo));
  23823. }
  23824. vctxt->nbAttrInfos = 0;
  23825. }
  23826. /*
  23827. * 3.4.4 Complex Type Definition Validation Rules
  23828. * Element Locally Valid (Complex Type) (cvc-complex-type)
  23829. * 3.2.4 Attribute Declaration Validation Rules
  23830. * Validation Rule: Attribute Locally Valid (cvc-attribute)
  23831. * Attribute Locally Valid (Use) (cvc-au)
  23832. *
  23833. * Only "assessed" attribute information items will be visible to
  23834. * IDCs. I.e. not "lax" (without declaration) and "skip" wild attributes.
  23835. */
  23836. static int
  23837. xmlSchemaVAttributesComplex(xmlSchemaValidCtxtPtr vctxt)
  23838. {
  23839. xmlSchemaTypePtr type = vctxt->inode->typeDef;
  23840. xmlSchemaItemListPtr attrUseList;
  23841. xmlSchemaAttributeUsePtr attrUse = NULL;
  23842. xmlSchemaAttributePtr attrDecl = NULL;
  23843. xmlSchemaAttrInfoPtr iattr, tmpiattr;
  23844. int i, j, found, nbAttrs, nbUses;
  23845. int xpathRes = 0, res, wildIDs = 0, fixed;
  23846. xmlNodePtr defAttrOwnerElem = NULL;
  23847. /*
  23848. * SPEC (cvc-attribute)
  23849. * (1) "The declaration must not be `absent` (see Missing
  23850. * Sub-components ($5.3) for how this can fail to be
  23851. * the case)."
  23852. * (2) "Its {type definition} must not be absent."
  23853. *
  23854. * NOTE (1) + (2): This is not handled here, since we currently do not
  23855. * allow validation against schemas which have missing sub-components.
  23856. *
  23857. * SPEC (cvc-complex-type)
  23858. * (3) "For each attribute information item in the element information
  23859. * item's [attributes] excepting those whose [namespace name] is
  23860. * identical to http://www.w3.org/2001/XMLSchema-instance and whose
  23861. * [local name] is one of type, nil, schemaLocation or
  23862. * noNamespaceSchemaLocation, the appropriate case among the following
  23863. * must be true:
  23864. *
  23865. */
  23866. attrUseList = (xmlSchemaItemListPtr) type->attrUses;
  23867. /*
  23868. * @nbAttrs is the number of attributes present in the instance.
  23869. */
  23870. nbAttrs = vctxt->nbAttrInfos;
  23871. if (attrUseList != NULL)
  23872. nbUses = attrUseList->nbItems;
  23873. else
  23874. nbUses = 0;
  23875. for (i = 0; i < nbUses; i++) {
  23876. found = 0;
  23877. attrUse = attrUseList->items[i];
  23878. attrDecl = WXS_ATTRUSE_DECL(attrUse);
  23879. for (j = 0; j < nbAttrs; j++) {
  23880. iattr = vctxt->attrInfos[j];
  23881. /*
  23882. * SPEC (cvc-complex-type) (3)
  23883. * Skip meta attributes.
  23884. */
  23885. if (iattr->metaType)
  23886. continue;
  23887. if (iattr->localName[0] != attrDecl->name[0])
  23888. continue;
  23889. if (!xmlStrEqual(iattr->localName, attrDecl->name))
  23890. continue;
  23891. if (!xmlStrEqual(iattr->nsName, attrDecl->targetNamespace))
  23892. continue;
  23893. found = 1;
  23894. /*
  23895. * SPEC (cvc-complex-type)
  23896. * (3.1) "If there is among the {attribute uses} an attribute
  23897. * use with an {attribute declaration} whose {name} matches
  23898. * the attribute information item's [local name] and whose
  23899. * {target namespace} is identical to the attribute information
  23900. * item's [namespace name] (where an `absent` {target namespace}
  23901. * is taken to be identical to a [namespace name] with no value),
  23902. * then the attribute information must be `valid` with respect
  23903. * to that attribute use as per Attribute Locally Valid (Use)
  23904. * ($3.5.4). In this case the {attribute declaration} of that
  23905. * attribute use is the `context-determined declaration` for the
  23906. * attribute information item with respect to Schema-Validity
  23907. * Assessment (Attribute) ($3.2.4) and
  23908. * Assessment Outcome (Attribute) ($3.2.5).
  23909. */
  23910. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  23911. iattr->use = attrUse;
  23912. /*
  23913. * Context-determined declaration.
  23914. */
  23915. iattr->decl = attrDecl;
  23916. iattr->typeDef = attrDecl->subtypes;
  23917. break;
  23918. }
  23919. if (found)
  23920. continue;
  23921. if (attrUse->occurs == XML_SCHEMAS_ATTR_USE_REQUIRED) {
  23922. /*
  23923. * Handle non-existent, required attributes.
  23924. *
  23925. * SPEC (cvc-complex-type)
  23926. * (4) "The {attribute declaration} of each attribute use in
  23927. * the {attribute uses} whose {required} is true matches one
  23928. * of the attribute information items in the element information
  23929. * item's [attributes] as per clause 3.1 above."
  23930. */
  23931. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  23932. if (tmpiattr == NULL) {
  23933. VERROR_INT(
  23934. "xmlSchemaVAttributesComplex",
  23935. "calling xmlSchemaGetFreshAttrInfo()");
  23936. return (-1);
  23937. }
  23938. tmpiattr->state = XML_SCHEMAS_ATTR_ERR_MISSING;
  23939. tmpiattr->use = attrUse;
  23940. tmpiattr->decl = attrDecl;
  23941. } else if ((attrUse->occurs == XML_SCHEMAS_ATTR_USE_OPTIONAL) &&
  23942. ((attrUse->defValue != NULL) ||
  23943. (attrDecl->defValue != NULL))) {
  23944. /*
  23945. * Handle non-existent, optional, default/fixed attributes.
  23946. */
  23947. tmpiattr = xmlSchemaGetFreshAttrInfo(vctxt);
  23948. if (tmpiattr == NULL) {
  23949. VERROR_INT(
  23950. "xmlSchemaVAttributesComplex",
  23951. "calling xmlSchemaGetFreshAttrInfo()");
  23952. return (-1);
  23953. }
  23954. tmpiattr->state = XML_SCHEMAS_ATTR_DEFAULT;
  23955. tmpiattr->use = attrUse;
  23956. tmpiattr->decl = attrDecl;
  23957. tmpiattr->typeDef = attrDecl->subtypes;
  23958. tmpiattr->localName = attrDecl->name;
  23959. tmpiattr->nsName = attrDecl->targetNamespace;
  23960. }
  23961. }
  23962. if (vctxt->nbAttrInfos == 0)
  23963. return (0);
  23964. /*
  23965. * Validate against the wildcard.
  23966. */
  23967. if (type->attributeWildcard != NULL) {
  23968. /*
  23969. * SPEC (cvc-complex-type)
  23970. * (3.2.1) "There must be an {attribute wildcard}."
  23971. */
  23972. for (i = 0; i < nbAttrs; i++) {
  23973. iattr = vctxt->attrInfos[i];
  23974. /*
  23975. * SPEC (cvc-complex-type) (3)
  23976. * Skip meta attributes.
  23977. */
  23978. if (iattr->state != XML_SCHEMAS_ATTR_UNKNOWN)
  23979. continue;
  23980. /*
  23981. * SPEC (cvc-complex-type)
  23982. * (3.2.2) "The attribute information item must be `valid` with
  23983. * respect to it as defined in Item Valid (Wildcard) ($3.10.4)."
  23984. *
  23985. * SPEC Item Valid (Wildcard) (cvc-wildcard)
  23986. * "... its [namespace name] must be `valid` with respect to
  23987. * the wildcard constraint, as defined in Wildcard allows
  23988. * Namespace Name ($3.10.4)."
  23989. */
  23990. if (xmlSchemaCheckCVCWildcardNamespace(type->attributeWildcard,
  23991. iattr->nsName) == 0) {
  23992. /*
  23993. * Handle processContents.
  23994. *
  23995. * SPEC (cvc-wildcard):
  23996. * processContents | context-determined declaration:
  23997. * "strict" "mustFind"
  23998. * "lax" "none"
  23999. * "skip" "skip"
  24000. */
  24001. if (type->attributeWildcard->processContents ==
  24002. XML_SCHEMAS_ANY_SKIP) {
  24003. /*
  24004. * context-determined declaration = "skip"
  24005. *
  24006. * SPEC PSVI Assessment Outcome (Attribute)
  24007. * [validity] = "notKnown"
  24008. * [validation attempted] = "none"
  24009. */
  24010. iattr->state = XML_SCHEMAS_ATTR_WILD_SKIP;
  24011. continue;
  24012. }
  24013. /*
  24014. * Find an attribute declaration.
  24015. */
  24016. iattr->decl = xmlSchemaGetAttributeDecl(vctxt->schema,
  24017. iattr->localName, iattr->nsName);
  24018. if (iattr->decl != NULL) {
  24019. iattr->state = XML_SCHEMAS_ATTR_ASSESSED;
  24020. /*
  24021. * SPEC (cvc-complex-type)
  24022. * (5) "Let [Definition:] the wild IDs be the set of
  24023. * all attribute information item to which clause 3.2
  24024. * applied and whose `validation` resulted in a
  24025. * `context-determined declaration` of mustFind or no
  24026. * `context-determined declaration` at all, and whose
  24027. * [local name] and [namespace name] resolve (as
  24028. * defined by QName resolution (Instance) ($3.15.4)) to
  24029. * an attribute declaration whose {type definition} is
  24030. * or is derived from ID. Then all of the following
  24031. * must be true:"
  24032. */
  24033. iattr->typeDef = WXS_ATTR_TYPEDEF(iattr->decl);
  24034. if (xmlSchemaIsDerivedFromBuiltInType(
  24035. iattr->typeDef, XML_SCHEMAS_ID)) {
  24036. /*
  24037. * SPEC (5.1) "There must be no more than one
  24038. * item in `wild IDs`."
  24039. */
  24040. if (wildIDs != 0) {
  24041. /* VAL TODO */
  24042. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_DUPLICATE_ID;
  24043. TODO
  24044. continue;
  24045. }
  24046. wildIDs++;
  24047. /*
  24048. * SPEC (cvc-complex-type)
  24049. * (5.2) "If `wild IDs` is non-empty, there must not
  24050. * be any attribute uses among the {attribute uses}
  24051. * whose {attribute declaration}'s {type definition}
  24052. * is or is derived from ID."
  24053. */
  24054. if (attrUseList != NULL) {
  24055. for (j = 0; j < attrUseList->nbItems; j++) {
  24056. if (xmlSchemaIsDerivedFromBuiltInType(
  24057. WXS_ATTRUSE_TYPEDEF(attrUseList->items[j]),
  24058. XML_SCHEMAS_ID)) {
  24059. /* URGENT VAL TODO: implement */
  24060. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_AND_USE_ID;
  24061. TODO
  24062. break;
  24063. }
  24064. }
  24065. }
  24066. }
  24067. } else if (type->attributeWildcard->processContents ==
  24068. XML_SCHEMAS_ANY_LAX) {
  24069. iattr->state = XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL;
  24070. /*
  24071. * SPEC PSVI Assessment Outcome (Attribute)
  24072. * [validity] = "notKnown"
  24073. * [validation attempted] = "none"
  24074. */
  24075. } else {
  24076. iattr->state = XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL;
  24077. }
  24078. }
  24079. }
  24080. }
  24081. if (vctxt->nbAttrInfos == 0)
  24082. return (0);
  24083. /*
  24084. * Get the owner element; needed for creation of default attributes.
  24085. * This fixes bug #341337, reported by David Grohmann.
  24086. */
  24087. if (vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) {
  24088. xmlSchemaNodeInfoPtr ielem = vctxt->elemInfos[vctxt->depth];
  24089. if (ielem && ielem->node && ielem->node->doc)
  24090. defAttrOwnerElem = ielem->node;
  24091. }
  24092. /*
  24093. * Validate values, create default attributes, evaluate IDCs.
  24094. */
  24095. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24096. iattr = vctxt->attrInfos[i];
  24097. /*
  24098. * VAL TODO: Note that we won't try to resolve IDCs to
  24099. * "lax" and "skip" validated attributes. Check what to
  24100. * do in this case.
  24101. */
  24102. if ((iattr->state != XML_SCHEMAS_ATTR_ASSESSED) &&
  24103. (iattr->state != XML_SCHEMAS_ATTR_DEFAULT))
  24104. continue;
  24105. /*
  24106. * VAL TODO: What to do if the type definition is missing?
  24107. */
  24108. if (iattr->typeDef == NULL) {
  24109. iattr->state = XML_SCHEMAS_ATTR_ERR_NO_TYPE;
  24110. continue;
  24111. }
  24112. ACTIVATE_ATTRIBUTE(iattr);
  24113. fixed = 0;
  24114. xpathRes = 0;
  24115. if (vctxt->xpathStates != NULL) {
  24116. /*
  24117. * Evaluate IDCs.
  24118. */
  24119. xpathRes = xmlSchemaXPathEvaluate(vctxt,
  24120. XML_ATTRIBUTE_NODE);
  24121. if (xpathRes == -1) {
  24122. VERROR_INT("xmlSchemaVAttributesComplex",
  24123. "calling xmlSchemaXPathEvaluate()");
  24124. goto internal_error;
  24125. }
  24126. }
  24127. if (iattr->state == XML_SCHEMAS_ATTR_DEFAULT) {
  24128. /*
  24129. * Default/fixed attributes.
  24130. * We need the value only if we need to resolve IDCs or
  24131. * will create default attributes.
  24132. */
  24133. if ((xpathRes) || (defAttrOwnerElem)) {
  24134. if (iattr->use->defValue != NULL) {
  24135. iattr->value = (xmlChar *) iattr->use->defValue;
  24136. iattr->val = iattr->use->defVal;
  24137. } else {
  24138. iattr->value = (xmlChar *) iattr->decl->defValue;
  24139. iattr->val = iattr->decl->defVal;
  24140. }
  24141. /*
  24142. * IDCs will consume the precomputed default value,
  24143. * so we need to clone it.
  24144. */
  24145. if (iattr->val == NULL) {
  24146. VERROR_INT("xmlSchemaVAttributesComplex",
  24147. "default/fixed value on an attribute use was "
  24148. "not precomputed");
  24149. goto internal_error;
  24150. }
  24151. iattr->val = xmlSchemaCopyValue(iattr->val);
  24152. if (iattr->val == NULL) {
  24153. VERROR_INT("xmlSchemaVAttributesComplex",
  24154. "calling xmlSchemaCopyValue()");
  24155. goto internal_error;
  24156. }
  24157. }
  24158. /*
  24159. * PSVI: Add the default attribute to the current element.
  24160. * VAL TODO: Should we use the *normalized* value? This currently
  24161. * uses the *initial* value.
  24162. */
  24163. if (defAttrOwnerElem) {
  24164. xmlChar *normValue;
  24165. const xmlChar *value;
  24166. value = iattr->value;
  24167. /*
  24168. * Normalize the value.
  24169. */
  24170. normValue = xmlSchemaNormalizeValue(iattr->typeDef,
  24171. iattr->value);
  24172. if (normValue != NULL)
  24173. value = BAD_CAST normValue;
  24174. if (iattr->nsName == NULL) {
  24175. if (xmlNewProp(defAttrOwnerElem,
  24176. iattr->localName, value) == NULL) {
  24177. VERROR_INT("xmlSchemaVAttributesComplex",
  24178. "calling xmlNewProp()");
  24179. if (normValue != NULL)
  24180. xmlFree(normValue);
  24181. goto internal_error;
  24182. }
  24183. } else {
  24184. xmlNsPtr ns;
  24185. ns = xmlSearchNsByHref(defAttrOwnerElem->doc,
  24186. defAttrOwnerElem, iattr->nsName);
  24187. if (ns == NULL) {
  24188. xmlChar prefix[12];
  24189. int counter = 0;
  24190. /*
  24191. * Create a namespace declaration on the validation
  24192. * root node if no namespace declaration is in scope.
  24193. */
  24194. do {
  24195. snprintf((char *) prefix, 12, "p%d", counter++);
  24196. ns = xmlSearchNs(defAttrOwnerElem->doc,
  24197. defAttrOwnerElem, BAD_CAST prefix);
  24198. if (counter > 1000) {
  24199. VERROR_INT(
  24200. "xmlSchemaVAttributesComplex",
  24201. "could not compute a ns prefix for a "
  24202. "default/fixed attribute");
  24203. if (normValue != NULL)
  24204. xmlFree(normValue);
  24205. goto internal_error;
  24206. }
  24207. } while (ns != NULL);
  24208. ns = xmlNewNs(vctxt->validationRoot,
  24209. iattr->nsName, BAD_CAST prefix);
  24210. }
  24211. /*
  24212. * TODO:
  24213. * http://lists.w3.org/Archives/Public/www-xml-schema-comments/2005JulSep/0406.html
  24214. * If we have QNames: do we need to ensure there's a
  24215. * prefix defined for the QName?
  24216. */
  24217. xmlNewNsProp(defAttrOwnerElem, ns, iattr->localName, value);
  24218. }
  24219. if (normValue != NULL)
  24220. xmlFree(normValue);
  24221. }
  24222. /*
  24223. * Go directly to IDC evaluation.
  24224. */
  24225. goto eval_idcs;
  24226. }
  24227. /*
  24228. * Validate the value.
  24229. */
  24230. if (vctxt->value != NULL) {
  24231. /*
  24232. * Free last computed value; just for safety reasons.
  24233. */
  24234. xmlSchemaFreeValue(vctxt->value);
  24235. vctxt->value = NULL;
  24236. }
  24237. /*
  24238. * Note that the attribute *use* can be unavailable, if
  24239. * the attribute was a wild attribute.
  24240. */
  24241. if ((iattr->decl->flags & XML_SCHEMAS_ATTR_FIXED) ||
  24242. ((iattr->use != NULL) &&
  24243. (iattr->use->flags & XML_SCHEMAS_ATTR_FIXED)))
  24244. fixed = 1;
  24245. else
  24246. fixed = 0;
  24247. /*
  24248. * SPEC (cvc-attribute)
  24249. * (3) "The item's `normalized value` must be locally `valid`
  24250. * with respect to that {type definition} as per
  24251. * String Valid ($3.14.4)."
  24252. *
  24253. * VAL TODO: Do we already have the
  24254. * "normalized attribute value" here?
  24255. */
  24256. if (xpathRes || fixed) {
  24257. iattr->flags |= XML_SCHEMA_NODE_INFO_VALUE_NEEDED;
  24258. /*
  24259. * Request a computed value.
  24260. */
  24261. res = xmlSchemaVCheckCVCSimpleType(
  24262. ACTXT_CAST vctxt,
  24263. iattr->node, iattr->typeDef, iattr->value, &(iattr->val),
  24264. 1, 1, 0);
  24265. } else {
  24266. res = xmlSchemaVCheckCVCSimpleType(
  24267. ACTXT_CAST vctxt,
  24268. iattr->node, iattr->typeDef, iattr->value, NULL,
  24269. 1, 0, 0);
  24270. }
  24271. if (res != 0) {
  24272. if (res == -1) {
  24273. VERROR_INT("xmlSchemaVAttributesComplex",
  24274. "calling xmlSchemaStreamValidateSimpleTypeValue()");
  24275. goto internal_error;
  24276. }
  24277. iattr->state = XML_SCHEMAS_ATTR_INVALID_VALUE;
  24278. /*
  24279. * SPEC PSVI Assessment Outcome (Attribute)
  24280. * [validity] = "invalid"
  24281. */
  24282. goto eval_idcs;
  24283. }
  24284. if (fixed) {
  24285. /*
  24286. * SPEC Attribute Locally Valid (Use) (cvc-au)
  24287. * "For an attribute information item to be `valid`
  24288. * with respect to an attribute use its *normalized*
  24289. * value must match the *canonical* lexical
  24290. * representation of the attribute use's {value
  24291. * constraint}value, if it is present and fixed."
  24292. *
  24293. * VAL TODO: The requirement for the *canonical* value
  24294. * will be removed in XML Schema 1.1.
  24295. */
  24296. /*
  24297. * SPEC Attribute Locally Valid (cvc-attribute)
  24298. * (4) "The item's *actual* value must match the *value* of
  24299. * the {value constraint}, if it is present and fixed."
  24300. */
  24301. if (iattr->val == NULL) {
  24302. /* VAL TODO: A value was not precomputed. */
  24303. TODO
  24304. goto eval_idcs;
  24305. }
  24306. if ((iattr->use != NULL) &&
  24307. (iattr->use->defValue != NULL)) {
  24308. if (iattr->use->defVal == NULL) {
  24309. /* VAL TODO: A default value was not precomputed. */
  24310. TODO
  24311. goto eval_idcs;
  24312. }
  24313. iattr->vcValue = iattr->use->defValue;
  24314. /*
  24315. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24316. (xmlSchemaWhitespaceValueType) ws,
  24317. attr->use->defVal,
  24318. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24319. */
  24320. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->use->defVal))
  24321. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24322. } else {
  24323. if (iattr->decl->defVal == NULL) {
  24324. /* VAL TODO: A default value was not precomputed. */
  24325. TODO
  24326. goto eval_idcs;
  24327. }
  24328. iattr->vcValue = iattr->decl->defValue;
  24329. /*
  24330. if (xmlSchemaCompareValuesWhtsp(attr->val,
  24331. (xmlSchemaWhitespaceValueType) ws,
  24332. attrDecl->defVal,
  24333. (xmlSchemaWhitespaceValueType) ws) != 0) {
  24334. */
  24335. if (! xmlSchemaAreValuesEqual(iattr->val, iattr->decl->defVal))
  24336. iattr->state = XML_SCHEMAS_ATTR_ERR_FIXED_VALUE;
  24337. }
  24338. /*
  24339. * [validity] = "valid"
  24340. */
  24341. }
  24342. eval_idcs:
  24343. /*
  24344. * Evaluate IDCs.
  24345. */
  24346. if (xpathRes) {
  24347. if (xmlSchemaXPathProcessHistory(vctxt,
  24348. vctxt->depth +1) == -1) {
  24349. VERROR_INT("xmlSchemaVAttributesComplex",
  24350. "calling xmlSchemaXPathEvaluate()");
  24351. goto internal_error;
  24352. }
  24353. } else if (vctxt->xpathStates != NULL)
  24354. xmlSchemaXPathPop(vctxt);
  24355. }
  24356. /*
  24357. * Report errors.
  24358. */
  24359. for (i = 0; i < vctxt->nbAttrInfos; i++) {
  24360. iattr = vctxt->attrInfos[i];
  24361. if ((iattr->state == XML_SCHEMAS_ATTR_META) ||
  24362. (iattr->state == XML_SCHEMAS_ATTR_ASSESSED) ||
  24363. (iattr->state == XML_SCHEMAS_ATTR_WILD_SKIP) ||
  24364. (iattr->state == XML_SCHEMAS_ATTR_WILD_LAX_NO_DECL))
  24365. continue;
  24366. ACTIVATE_ATTRIBUTE(iattr);
  24367. switch (iattr->state) {
  24368. case XML_SCHEMAS_ATTR_ERR_MISSING: {
  24369. xmlChar *str = NULL;
  24370. ACTIVATE_ELEM;
  24371. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24372. XML_SCHEMAV_CVC_COMPLEX_TYPE_4, NULL, NULL,
  24373. "The attribute '%s' is required but missing",
  24374. xmlSchemaFormatQName(&str,
  24375. iattr->decl->targetNamespace,
  24376. iattr->decl->name),
  24377. NULL);
  24378. FREE_AND_NULL(str)
  24379. break;
  24380. }
  24381. case XML_SCHEMAS_ATTR_ERR_NO_TYPE:
  24382. VERROR(XML_SCHEMAV_CVC_ATTRIBUTE_2, NULL,
  24383. "The type definition is absent");
  24384. break;
  24385. case XML_SCHEMAS_ATTR_ERR_FIXED_VALUE:
  24386. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24387. XML_SCHEMAV_CVC_AU, NULL, NULL,
  24388. "The value '%s' does not match the fixed "
  24389. "value constraint '%s'",
  24390. iattr->value, iattr->vcValue);
  24391. break;
  24392. case XML_SCHEMAS_ATTR_ERR_WILD_STRICT_NO_DECL:
  24393. VERROR(XML_SCHEMAV_CVC_WILDCARD, NULL,
  24394. "No matching global attribute declaration available, but "
  24395. "demanded by the strict wildcard");
  24396. break;
  24397. case XML_SCHEMAS_ATTR_UNKNOWN:
  24398. if (iattr->metaType)
  24399. break;
  24400. /*
  24401. * MAYBE VAL TODO: One might report different error messages
  24402. * for the following errors.
  24403. */
  24404. if (type->attributeWildcard == NULL) {
  24405. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24406. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_1, iattr, NULL);
  24407. } else {
  24408. xmlSchemaIllegalAttrErr(ACTXT_CAST vctxt,
  24409. XML_SCHEMAV_CVC_COMPLEX_TYPE_3_2_2, iattr, NULL);
  24410. }
  24411. break;
  24412. default:
  24413. break;
  24414. }
  24415. }
  24416. ACTIVATE_ELEM;
  24417. return (0);
  24418. internal_error:
  24419. ACTIVATE_ELEM;
  24420. return (-1);
  24421. }
  24422. static int
  24423. xmlSchemaValidateElemWildcard(xmlSchemaValidCtxtPtr vctxt,
  24424. int *skip)
  24425. {
  24426. xmlSchemaWildcardPtr wild = (xmlSchemaWildcardPtr) vctxt->inode->decl;
  24427. /*
  24428. * The namespace of the element was already identified to be
  24429. * matching the wildcard.
  24430. */
  24431. if ((skip == NULL) || (wild == NULL) ||
  24432. (wild->type != XML_SCHEMA_TYPE_ANY)) {
  24433. VERROR_INT("xmlSchemaValidateElemWildcard",
  24434. "bad arguments");
  24435. return (-1);
  24436. }
  24437. *skip = 0;
  24438. if (wild->processContents == XML_SCHEMAS_ANY_SKIP) {
  24439. /*
  24440. * URGENT VAL TODO: Either we need to position the stream to the
  24441. * next sibling, or walk the whole subtree.
  24442. */
  24443. *skip = 1;
  24444. return (0);
  24445. }
  24446. {
  24447. xmlSchemaElementPtr decl = NULL;
  24448. decl = xmlSchemaGetElem(vctxt->schema,
  24449. vctxt->inode->localName, vctxt->inode->nsName);
  24450. if (decl != NULL) {
  24451. vctxt->inode->decl = decl;
  24452. return (0);
  24453. }
  24454. }
  24455. if (wild->processContents == XML_SCHEMAS_ANY_STRICT) {
  24456. /* VAL TODO: Change to proper error code. */
  24457. VERROR(XML_SCHEMAV_CVC_ELT_1, NULL, /* WXS_BASIC_CAST wild */
  24458. "No matching global element declaration available, but "
  24459. "demanded by the strict wildcard");
  24460. return (vctxt->err);
  24461. }
  24462. if (vctxt->nbAttrInfos != 0) {
  24463. xmlSchemaAttrInfoPtr iattr;
  24464. /*
  24465. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24466. * (1.2.1.2.1) - (1.2.1.2.3 )
  24467. *
  24468. * Use the xsi:type attribute for the type definition.
  24469. */
  24470. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  24471. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  24472. if (iattr != NULL) {
  24473. if (xmlSchemaProcessXSIType(vctxt, iattr,
  24474. &(vctxt->inode->typeDef), NULL) == -1) {
  24475. VERROR_INT("xmlSchemaValidateElemWildcard",
  24476. "calling xmlSchemaProcessXSIType() to "
  24477. "process the attribute 'xsi:nil'");
  24478. return (-1);
  24479. }
  24480. /*
  24481. * Don't return an error on purpose.
  24482. */
  24483. return (0);
  24484. }
  24485. }
  24486. /*
  24487. * SPEC Validation Rule: Schema-Validity Assessment (Element)
  24488. *
  24489. * Fallback to "anyType".
  24490. */
  24491. vctxt->inode->typeDef =
  24492. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  24493. return (0);
  24494. }
  24495. /*
  24496. * xmlSchemaCheckCOSValidDefault:
  24497. *
  24498. * This will be called if: not nilled, no content and a default/fixed
  24499. * value is provided.
  24500. */
  24501. static int
  24502. xmlSchemaCheckCOSValidDefault(xmlSchemaValidCtxtPtr vctxt,
  24503. const xmlChar *value,
  24504. xmlSchemaValPtr *val)
  24505. {
  24506. int ret = 0;
  24507. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24508. /*
  24509. * cos-valid-default:
  24510. * Schema Component Constraint: Element Default Valid (Immediate)
  24511. * For a string to be a valid default with respect to a type
  24512. * definition the appropriate case among the following must be true:
  24513. */
  24514. if WXS_IS_COMPLEX(inode->typeDef) {
  24515. /*
  24516. * Complex type.
  24517. *
  24518. * SPEC (2.1) "its {content type} must be a simple type definition
  24519. * or mixed."
  24520. * SPEC (2.2.2) "If the {content type} is mixed, then the {content
  24521. * type}'s particle must be `emptiable` as defined by
  24522. * Particle Emptiable ($3.9.6)."
  24523. */
  24524. if ((! WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) &&
  24525. ((! WXS_HAS_MIXED_CONTENT(inode->typeDef)) ||
  24526. (! WXS_EMPTIABLE(inode->typeDef)))) {
  24527. ret = XML_SCHEMAP_COS_VALID_DEFAULT_2_1;
  24528. /* NOTE that this covers (2.2.2) as well. */
  24529. VERROR(ret, NULL,
  24530. "For a string to be a valid default, the type definition "
  24531. "must be a simple type or a complex type with simple content "
  24532. "or mixed content and a particle emptiable");
  24533. return(ret);
  24534. }
  24535. }
  24536. /*
  24537. * 1 If the type definition is a simple type definition, then the string
  24538. * must be `valid` with respect to that definition as defined by String
  24539. * Valid ($3.14.4).
  24540. *
  24541. * AND
  24542. *
  24543. * 2.2.1 If the {content type} is a simple type definition, then the
  24544. * string must be `valid` with respect to that simple type definition
  24545. * as defined by String Valid ($3.14.4).
  24546. */
  24547. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24548. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24549. NULL, inode->typeDef, value, val, 1, 1, 0);
  24550. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24551. ret = xmlSchemaVCheckCVCSimpleType(ACTXT_CAST vctxt,
  24552. NULL, inode->typeDef->contentTypeDef, value, val, 1, 1, 0);
  24553. }
  24554. if (ret < 0) {
  24555. VERROR_INT("xmlSchemaCheckCOSValidDefault",
  24556. "calling xmlSchemaVCheckCVCSimpleType()");
  24557. }
  24558. return (ret);
  24559. }
  24560. static void
  24561. xmlSchemaVContentModelCallback(xmlRegExecCtxtPtr exec ATTRIBUTE_UNUSED,
  24562. const xmlChar * name ATTRIBUTE_UNUSED,
  24563. void *transdata, void *inputdata)
  24564. {
  24565. xmlSchemaElementPtr item = (xmlSchemaElementPtr) transdata;
  24566. xmlSchemaNodeInfoPtr inode = (xmlSchemaNodeInfoPtr) inputdata;
  24567. inode->decl = item;
  24568. #ifdef DEBUG_CONTENT
  24569. {
  24570. xmlChar *str = NULL;
  24571. if (item->type == XML_SCHEMA_TYPE_ELEMENT) {
  24572. xmlGenericError(xmlGenericErrorContext,
  24573. "AUTOMATON callback for '%s' [declaration]\n",
  24574. xmlSchemaFormatQName(&str,
  24575. inode->localName, inode->nsName));
  24576. } else {
  24577. xmlGenericError(xmlGenericErrorContext,
  24578. "AUTOMATON callback for '%s' [wildcard]\n",
  24579. xmlSchemaFormatQName(&str,
  24580. inode->localName, inode->nsName));
  24581. }
  24582. FREE_AND_NULL(str)
  24583. }
  24584. #endif
  24585. }
  24586. static int
  24587. xmlSchemaValidatorPushElem(xmlSchemaValidCtxtPtr vctxt)
  24588. {
  24589. vctxt->inode = xmlSchemaGetFreshElemInfo(vctxt);
  24590. if (vctxt->inode == NULL) {
  24591. VERROR_INT("xmlSchemaValidatorPushElem",
  24592. "calling xmlSchemaGetFreshElemInfo()");
  24593. return (-1);
  24594. }
  24595. vctxt->nbAttrInfos = 0;
  24596. return (0);
  24597. }
  24598. static int
  24599. xmlSchemaVCheckINodeDataType(xmlSchemaValidCtxtPtr vctxt,
  24600. xmlSchemaNodeInfoPtr inode,
  24601. xmlSchemaTypePtr type,
  24602. const xmlChar *value)
  24603. {
  24604. if (inode->flags & XML_SCHEMA_NODE_INFO_VALUE_NEEDED)
  24605. return (xmlSchemaVCheckCVCSimpleType(
  24606. ACTXT_CAST vctxt, NULL,
  24607. type, value, &(inode->val), 1, 1, 0));
  24608. else
  24609. return (xmlSchemaVCheckCVCSimpleType(
  24610. ACTXT_CAST vctxt, NULL,
  24611. type, value, NULL, 1, 0, 0));
  24612. }
  24613. /*
  24614. * Process END of element.
  24615. */
  24616. static int
  24617. xmlSchemaValidatorPopElem(xmlSchemaValidCtxtPtr vctxt)
  24618. {
  24619. int ret = 0;
  24620. xmlSchemaNodeInfoPtr inode = vctxt->inode;
  24621. if (vctxt->nbAttrInfos != 0)
  24622. xmlSchemaClearAttrInfos(vctxt);
  24623. if (inode->flags & XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED) {
  24624. /*
  24625. * This element was not expected;
  24626. * we will not validate child elements of broken parents.
  24627. * Skip validation of all content of the parent.
  24628. */
  24629. vctxt->skipDepth = vctxt->depth -1;
  24630. goto end_elem;
  24631. }
  24632. if ((inode->typeDef == NULL) ||
  24633. (inode->flags & XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE)) {
  24634. /*
  24635. * 1. the type definition might be missing if the element was
  24636. * error prone
  24637. * 2. it might be abstract.
  24638. */
  24639. goto end_elem;
  24640. }
  24641. /*
  24642. * Check the content model.
  24643. */
  24644. if ((inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) ||
  24645. (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)) {
  24646. /*
  24647. * Workaround for "anyType".
  24648. */
  24649. if (inode->typeDef->builtInType == XML_SCHEMAS_ANYTYPE)
  24650. goto character_content;
  24651. if ((inode->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) == 0) {
  24652. xmlChar *values[10];
  24653. int terminal, nbval = 10, nbneg;
  24654. if (inode->regexCtxt == NULL) {
  24655. /*
  24656. * Create the regex context.
  24657. */
  24658. inode->regexCtxt =
  24659. xmlRegNewExecCtxt(inode->typeDef->contModel,
  24660. xmlSchemaVContentModelCallback, vctxt);
  24661. if (inode->regexCtxt == NULL) {
  24662. VERROR_INT("xmlSchemaValidatorPopElem",
  24663. "failed to create a regex context");
  24664. goto internal_error;
  24665. }
  24666. #ifdef DEBUG_AUTOMATA
  24667. xmlGenericError(xmlGenericErrorContext,
  24668. "AUTOMATON create on '%s'\n", inode->localName);
  24669. #endif
  24670. }
  24671. /*
  24672. * Do not check further content if the node has been nilled
  24673. */
  24674. if (INODE_NILLED(inode)) {
  24675. ret = 0;
  24676. #ifdef DEBUG_AUTOMATA
  24677. xmlGenericError(xmlGenericErrorContext,
  24678. "AUTOMATON succeeded on nilled '%s'\n",
  24679. inode->localName);
  24680. #endif
  24681. goto skip_nilled;
  24682. }
  24683. /*
  24684. * Get hold of the still expected content, since a further
  24685. * call to xmlRegExecPushString() will lose this information.
  24686. */
  24687. xmlRegExecNextValues(inode->regexCtxt,
  24688. &nbval, &nbneg, &values[0], &terminal);
  24689. ret = xmlRegExecPushString(inode->regexCtxt, NULL, NULL);
  24690. if ((ret<0) || ((ret==0) && (!INODE_NILLED(inode)))) {
  24691. /*
  24692. * Still missing something.
  24693. */
  24694. ret = 1;
  24695. inode->flags |=
  24696. XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  24697. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  24698. XML_SCHEMAV_ELEMENT_CONTENT, NULL, NULL,
  24699. "Missing child element(s)",
  24700. nbval, nbneg, values);
  24701. #ifdef DEBUG_AUTOMATA
  24702. xmlGenericError(xmlGenericErrorContext,
  24703. "AUTOMATON missing ERROR on '%s'\n",
  24704. inode->localName);
  24705. #endif
  24706. } else {
  24707. /*
  24708. * Content model is satisfied.
  24709. */
  24710. ret = 0;
  24711. #ifdef DEBUG_AUTOMATA
  24712. xmlGenericError(xmlGenericErrorContext,
  24713. "AUTOMATON succeeded on '%s'\n",
  24714. inode->localName);
  24715. #endif
  24716. }
  24717. }
  24718. }
  24719. skip_nilled:
  24720. if (inode->typeDef->contentType == XML_SCHEMA_CONTENT_ELEMENTS)
  24721. goto end_elem;
  24722. character_content:
  24723. if (vctxt->value != NULL) {
  24724. xmlSchemaFreeValue(vctxt->value);
  24725. vctxt->value = NULL;
  24726. }
  24727. /*
  24728. * Check character content.
  24729. */
  24730. if (inode->decl == NULL) {
  24731. /*
  24732. * Speedup if no declaration exists.
  24733. */
  24734. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24735. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24736. inode, inode->typeDef, inode->value);
  24737. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24738. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24739. inode, inode->typeDef->contentTypeDef,
  24740. inode->value);
  24741. }
  24742. if (ret < 0) {
  24743. VERROR_INT("xmlSchemaValidatorPopElem",
  24744. "calling xmlSchemaVCheckCVCSimpleType()");
  24745. goto internal_error;
  24746. }
  24747. goto end_elem;
  24748. }
  24749. /*
  24750. * cvc-elt (3.3.4) : 5
  24751. * The appropriate case among the following must be true:
  24752. */
  24753. /*
  24754. * cvc-elt (3.3.4) : 5.1
  24755. * If the declaration has a {value constraint},
  24756. * the item has neither element nor character [children] and
  24757. * clause 3.2 has not applied, then all of the following must be true:
  24758. */
  24759. if ((inode->decl->value != NULL) &&
  24760. (inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY) &&
  24761. (! INODE_NILLED(inode))) {
  24762. /*
  24763. * cvc-elt (3.3.4) : 5.1.1
  24764. * If the `actual type definition` is a `local type definition`
  24765. * then the canonical lexical representation of the {value constraint}
  24766. * value must be a valid default for the `actual type definition` as
  24767. * defined in Element Default Valid (Immediate) ($3.3.6).
  24768. */
  24769. /*
  24770. * NOTE: 'local' above means types acquired by xsi:type.
  24771. * NOTE: Although the *canonical* value is stated, it is not
  24772. * relevant if canonical or not. Additionally XML Schema 1.1
  24773. * will removed this requirement as well.
  24774. */
  24775. if (inode->flags & XML_SCHEMA_ELEM_INFO_LOCAL_TYPE) {
  24776. ret = xmlSchemaCheckCOSValidDefault(vctxt,
  24777. inode->decl->value, &(inode->val));
  24778. if (ret != 0) {
  24779. if (ret < 0) {
  24780. VERROR_INT("xmlSchemaValidatorPopElem",
  24781. "calling xmlSchemaCheckCOSValidDefault()");
  24782. goto internal_error;
  24783. }
  24784. goto end_elem;
  24785. }
  24786. /*
  24787. * Stop here, to avoid redundant validation of the value
  24788. * (see following).
  24789. */
  24790. goto default_psvi;
  24791. }
  24792. /*
  24793. * cvc-elt (3.3.4) : 5.1.2
  24794. * The element information item with the canonical lexical
  24795. * representation of the {value constraint} value used as its
  24796. * `normalized value` must be `valid` with respect to the
  24797. * `actual type definition` as defined by Element Locally Valid (Type)
  24798. * ($3.3.4).
  24799. */
  24800. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24801. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24802. inode, inode->typeDef, inode->decl->value);
  24803. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24804. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24805. inode, inode->typeDef->contentTypeDef,
  24806. inode->decl->value);
  24807. }
  24808. if (ret != 0) {
  24809. if (ret < 0) {
  24810. VERROR_INT("xmlSchemaValidatorPopElem",
  24811. "calling xmlSchemaVCheckCVCSimpleType()");
  24812. goto internal_error;
  24813. }
  24814. goto end_elem;
  24815. }
  24816. default_psvi:
  24817. /*
  24818. * PSVI: Create a text node on the instance element.
  24819. */
  24820. if ((vctxt->options & XML_SCHEMA_VAL_VC_I_CREATE) &&
  24821. (inode->node != NULL)) {
  24822. xmlNodePtr textChild;
  24823. xmlChar *normValue;
  24824. /*
  24825. * VAL TODO: Normalize the value.
  24826. */
  24827. normValue = xmlSchemaNormalizeValue(inode->typeDef,
  24828. inode->decl->value);
  24829. if (normValue != NULL) {
  24830. textChild = xmlNewText(BAD_CAST normValue);
  24831. xmlFree(normValue);
  24832. } else
  24833. textChild = xmlNewText(inode->decl->value);
  24834. if (textChild == NULL) {
  24835. VERROR_INT("xmlSchemaValidatorPopElem",
  24836. "calling xmlNewText()");
  24837. goto internal_error;
  24838. } else
  24839. xmlAddChild(inode->node, textChild);
  24840. }
  24841. } else if (! INODE_NILLED(inode)) {
  24842. /*
  24843. * 5.2.1 The element information item must be `valid` with respect
  24844. * to the `actual type definition` as defined by Element Locally
  24845. * Valid (Type) ($3.3.4).
  24846. */
  24847. if (WXS_IS_SIMPLE(inode->typeDef)) {
  24848. /*
  24849. * SPEC (cvc-type) (3.1)
  24850. * "If the type definition is a simple type definition, ..."
  24851. * (3.1.3) "If clause 3.2 of Element Locally Valid
  24852. * (Element) ($3.3.4) did not apply, then the `normalized value`
  24853. * must be `valid` with respect to the type definition as defined
  24854. * by String Valid ($3.14.4).
  24855. */
  24856. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24857. inode, inode->typeDef, inode->value);
  24858. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24859. /*
  24860. * SPEC (cvc-type) (3.2) "If the type definition is a complex type
  24861. * definition, then the element information item must be
  24862. * `valid` with respect to the type definition as per
  24863. * Element Locally Valid (Complex Type) ($3.4.4);"
  24864. *
  24865. * SPEC (cvc-complex-type) (2.2)
  24866. * "If the {content type} is a simple type definition, ...
  24867. * the `normalized value` of the element information item is
  24868. * `valid` with respect to that simple type definition as
  24869. * defined by String Valid ($3.14.4)."
  24870. */
  24871. ret = xmlSchemaVCheckINodeDataType(vctxt,
  24872. inode, inode->typeDef->contentTypeDef, inode->value);
  24873. }
  24874. if (ret != 0) {
  24875. if (ret < 0) {
  24876. VERROR_INT("xmlSchemaValidatorPopElem",
  24877. "calling xmlSchemaVCheckCVCSimpleType()");
  24878. goto internal_error;
  24879. }
  24880. goto end_elem;
  24881. }
  24882. /*
  24883. * 5.2.2 If there is a fixed {value constraint} and clause 3.2 has
  24884. * not applied, all of the following must be true:
  24885. */
  24886. if ((inode->decl->value != NULL) &&
  24887. (inode->decl->flags & XML_SCHEMAS_ELEM_FIXED)) {
  24888. /*
  24889. * TODO: We will need a computed value, when comparison is
  24890. * done on computed values.
  24891. */
  24892. /*
  24893. * 5.2.2.1 The element information item must have no element
  24894. * information item [children].
  24895. */
  24896. if (inode->flags &
  24897. XML_SCHEMA_ELEM_INFO_HAS_ELEM_CONTENT) {
  24898. ret = XML_SCHEMAV_CVC_ELT_5_2_2_1;
  24899. VERROR(ret, NULL,
  24900. "The content must not contain element nodes since "
  24901. "there is a fixed value constraint");
  24902. goto end_elem;
  24903. } else {
  24904. /*
  24905. * 5.2.2.2 The appropriate case among the following must
  24906. * be true:
  24907. */
  24908. if (WXS_HAS_MIXED_CONTENT(inode->typeDef)) {
  24909. /*
  24910. * 5.2.2.2.1 If the {content type} of the `actual type
  24911. * definition` is mixed, then the *initial value* of the
  24912. * item must match the canonical lexical representation
  24913. * of the {value constraint} value.
  24914. *
  24915. * ... the *initial value* of an element information
  24916. * item is the string composed of, in order, the
  24917. * [character code] of each character information item in
  24918. * the [children] of that element information item.
  24919. */
  24920. if (! xmlStrEqual(inode->value, inode->decl->value)){
  24921. /*
  24922. * VAL TODO: Report invalid & expected values as well.
  24923. * VAL TODO: Implement the canonical stuff.
  24924. */
  24925. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_1;
  24926. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24927. ret, NULL, NULL,
  24928. "The initial value '%s' does not match the fixed "
  24929. "value constraint '%s'",
  24930. inode->value, inode->decl->value);
  24931. goto end_elem;
  24932. }
  24933. } else if (WXS_HAS_SIMPLE_CONTENT(inode->typeDef)) {
  24934. /*
  24935. * 5.2.2.2.2 If the {content type} of the `actual type
  24936. * definition` is a simple type definition, then the
  24937. * *actual value* of the item must match the canonical
  24938. * lexical representation of the {value constraint} value.
  24939. */
  24940. /*
  24941. * VAL TODO: *actual value* is the normalized value, impl.
  24942. * this.
  24943. * VAL TODO: Report invalid & expected values as well.
  24944. * VAL TODO: Implement a comparison with the computed values.
  24945. */
  24946. if (! xmlStrEqual(inode->value,
  24947. inode->decl->value)) {
  24948. ret = XML_SCHEMAV_CVC_ELT_5_2_2_2_2;
  24949. xmlSchemaCustomErr(ACTXT_CAST vctxt,
  24950. ret, NULL, NULL,
  24951. "The actual value '%s' does not match the fixed "
  24952. "value constraint '%s'",
  24953. inode->value,
  24954. inode->decl->value);
  24955. goto end_elem;
  24956. }
  24957. }
  24958. }
  24959. }
  24960. }
  24961. end_elem:
  24962. if (vctxt->depth < 0) {
  24963. /* TODO: raise error? */
  24964. return (0);
  24965. }
  24966. if (vctxt->depth == vctxt->skipDepth)
  24967. vctxt->skipDepth = -1;
  24968. /*
  24969. * Evaluate the history of XPath state objects.
  24970. */
  24971. if (inode->appliedXPath &&
  24972. (xmlSchemaXPathProcessHistory(vctxt, vctxt->depth) == -1))
  24973. goto internal_error;
  24974. /*
  24975. * MAYBE TODO:
  24976. * SPEC (6) "The element information item must be `valid` with
  24977. * respect to each of the {identity-constraint definitions} as per
  24978. * Identity-constraint Satisfied ($3.11.4)."
  24979. */
  24980. /*
  24981. * PSVI TODO: If we expose IDC node-tables via PSVI then the tables
  24982. * need to be built in any case.
  24983. * We will currently build IDC node-tables and bubble them only if
  24984. * keyrefs do exist.
  24985. */
  24986. /*
  24987. * Add the current IDC target-nodes to the IDC node-tables.
  24988. */
  24989. if ((inode->idcMatchers != NULL) &&
  24990. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  24991. {
  24992. if (xmlSchemaIDCFillNodeTables(vctxt, inode) == -1)
  24993. goto internal_error;
  24994. }
  24995. /*
  24996. * Validate IDC keyrefs.
  24997. */
  24998. if (vctxt->inode->hasKeyrefs)
  24999. if (xmlSchemaCheckCVCIDCKeyRef(vctxt) == -1)
  25000. goto internal_error;
  25001. /*
  25002. * Merge/free the IDC table.
  25003. */
  25004. if (inode->idcTable != NULL) {
  25005. #ifdef DEBUG_IDC_NODE_TABLE
  25006. xmlSchemaDebugDumpIDCTable(stdout,
  25007. inode->nsName,
  25008. inode->localName,
  25009. inode->idcTable);
  25010. #endif
  25011. if ((vctxt->depth > 0) &&
  25012. (vctxt->hasKeyrefs || vctxt->createIDCNodeTables))
  25013. {
  25014. /*
  25015. * Merge the IDC node table with the table of the parent node.
  25016. */
  25017. if (xmlSchemaBubbleIDCNodeTables(vctxt) == -1)
  25018. goto internal_error;
  25019. }
  25020. }
  25021. /*
  25022. * Clear the current ielem.
  25023. * VAL TODO: Don't free the PSVI IDC tables if they are
  25024. * requested for the PSVI.
  25025. */
  25026. xmlSchemaClearElemInfo(vctxt, inode);
  25027. /*
  25028. * Skip further processing if we are on the validation root.
  25029. */
  25030. if (vctxt->depth == 0) {
  25031. vctxt->depth--;
  25032. vctxt->inode = NULL;
  25033. return (0);
  25034. }
  25035. /*
  25036. * Reset the keyrefDepth if needed.
  25037. */
  25038. if (vctxt->aidcs != NULL) {
  25039. xmlSchemaIDCAugPtr aidc = vctxt->aidcs;
  25040. do {
  25041. if (aidc->keyrefDepth == vctxt->depth) {
  25042. /*
  25043. * A 'keyrefDepth' of a key/unique IDC matches the current
  25044. * depth, this means that we are leaving the scope of the
  25045. * top-most keyref IDC which refers to this IDC.
  25046. */
  25047. aidc->keyrefDepth = -1;
  25048. }
  25049. aidc = aidc->next;
  25050. } while (aidc != NULL);
  25051. }
  25052. vctxt->depth--;
  25053. vctxt->inode = vctxt->elemInfos[vctxt->depth];
  25054. /*
  25055. * VAL TODO: 7 If the element information item is the `validation root`, it must be
  25056. * `valid` per Validation Root Valid (ID/IDREF) ($3.3.4).
  25057. */
  25058. return (ret);
  25059. internal_error:
  25060. vctxt->err = -1;
  25061. return (-1);
  25062. }
  25063. /*
  25064. * 3.4.4 Complex Type Definition Validation Rules
  25065. * Validation Rule: Element Locally Valid (Complex Type) (cvc-complex-type)
  25066. */
  25067. static int
  25068. xmlSchemaValidateChildElem(xmlSchemaValidCtxtPtr vctxt)
  25069. {
  25070. xmlSchemaNodeInfoPtr pielem;
  25071. xmlSchemaTypePtr ptype;
  25072. int ret = 0;
  25073. if (vctxt->depth <= 0) {
  25074. VERROR_INT("xmlSchemaValidateChildElem",
  25075. "not intended for the validation root");
  25076. return (-1);
  25077. }
  25078. pielem = vctxt->elemInfos[vctxt->depth -1];
  25079. if (pielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25080. pielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25081. /*
  25082. * Handle 'nilled' elements.
  25083. */
  25084. if (INODE_NILLED(pielem)) {
  25085. /*
  25086. * SPEC (cvc-elt) (3.3.4) : (3.2.1)
  25087. */
  25088. ACTIVATE_PARENT_ELEM;
  25089. ret = XML_SCHEMAV_CVC_ELT_3_2_1;
  25090. VERROR(ret, NULL,
  25091. "Neither character nor element content is allowed, "
  25092. "because the element was 'nilled'");
  25093. ACTIVATE_ELEM;
  25094. goto unexpected_elem;
  25095. }
  25096. ptype = pielem->typeDef;
  25097. if (ptype->builtInType == XML_SCHEMAS_ANYTYPE) {
  25098. /*
  25099. * Workaround for "anyType": we have currently no content model
  25100. * assigned for "anyType", so handle it explicitly.
  25101. * "anyType" has an unbounded, lax "any" wildcard.
  25102. */
  25103. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25104. vctxt->inode->localName,
  25105. vctxt->inode->nsName);
  25106. if (vctxt->inode->decl == NULL) {
  25107. xmlSchemaAttrInfoPtr iattr;
  25108. /*
  25109. * Process "xsi:type".
  25110. * SPEC (cvc-assess-elt) (1.2.1.2.1) - (1.2.1.2.3)
  25111. */
  25112. iattr = xmlSchemaGetMetaAttrInfo(vctxt,
  25113. XML_SCHEMA_ATTR_INFO_META_XSI_TYPE);
  25114. if (iattr != NULL) {
  25115. ret = xmlSchemaProcessXSIType(vctxt, iattr,
  25116. &(vctxt->inode->typeDef), NULL);
  25117. if (ret != 0) {
  25118. if (ret == -1) {
  25119. VERROR_INT("xmlSchemaValidateChildElem",
  25120. "calling xmlSchemaProcessXSIType() to "
  25121. "process the attribute 'xsi:nil'");
  25122. return (-1);
  25123. }
  25124. return (ret);
  25125. }
  25126. } else {
  25127. /*
  25128. * Fallback to "anyType".
  25129. *
  25130. * SPEC (cvc-assess-elt)
  25131. * "If the item cannot be `strictly assessed`, [...]
  25132. * an element information item's schema validity may be laxly
  25133. * assessed if its `context-determined declaration` is not
  25134. * skip by `validating` with respect to the `ur-type
  25135. * definition` as per Element Locally Valid (Type) ($3.3.4)."
  25136. */
  25137. vctxt->inode->typeDef =
  25138. xmlSchemaGetBuiltInType(XML_SCHEMAS_ANYTYPE);
  25139. }
  25140. }
  25141. return (0);
  25142. }
  25143. switch (ptype->contentType) {
  25144. case XML_SCHEMA_CONTENT_EMPTY:
  25145. /*
  25146. * SPEC (2.1) "If the {content type} is empty, then the
  25147. * element information item has no character or element
  25148. * information item [children]."
  25149. */
  25150. ACTIVATE_PARENT_ELEM
  25151. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1;
  25152. VERROR(ret, NULL,
  25153. "Element content is not allowed, "
  25154. "because the content type is empty");
  25155. ACTIVATE_ELEM
  25156. goto unexpected_elem;
  25157. break;
  25158. case XML_SCHEMA_CONTENT_MIXED:
  25159. case XML_SCHEMA_CONTENT_ELEMENTS: {
  25160. xmlRegExecCtxtPtr regexCtxt;
  25161. xmlChar *values[10];
  25162. int terminal, nbval = 10, nbneg;
  25163. /* VAL TODO: Optimized "anyType" validation.*/
  25164. if (ptype->contModel == NULL) {
  25165. VERROR_INT("xmlSchemaValidateChildElem",
  25166. "type has elem content but no content model");
  25167. return (-1);
  25168. }
  25169. /*
  25170. * Safety belt for evaluation if the cont. model was already
  25171. * examined to be invalid.
  25172. */
  25173. if (pielem->flags & XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT) {
  25174. VERROR_INT("xmlSchemaValidateChildElem",
  25175. "validating elem, but elem content is already invalid");
  25176. return (-1);
  25177. }
  25178. regexCtxt = pielem->regexCtxt;
  25179. if (regexCtxt == NULL) {
  25180. /*
  25181. * Create the regex context.
  25182. */
  25183. regexCtxt = xmlRegNewExecCtxt(ptype->contModel,
  25184. xmlSchemaVContentModelCallback, vctxt);
  25185. if (regexCtxt == NULL) {
  25186. VERROR_INT("xmlSchemaValidateChildElem",
  25187. "failed to create a regex context");
  25188. return (-1);
  25189. }
  25190. pielem->regexCtxt = regexCtxt;
  25191. #ifdef DEBUG_AUTOMATA
  25192. xmlGenericError(xmlGenericErrorContext, "AUTOMATA create on '%s'\n",
  25193. pielem->localName);
  25194. #endif
  25195. }
  25196. /*
  25197. * SPEC (2.4) "If the {content type} is element-only or mixed,
  25198. * then the sequence of the element information item's
  25199. * element information item [children], if any, taken in
  25200. * order, is `valid` with respect to the {content type}'s
  25201. * particle, as defined in Element Sequence Locally Valid
  25202. * (Particle) ($3.9.4)."
  25203. */
  25204. ret = xmlRegExecPushString2(regexCtxt,
  25205. vctxt->inode->localName,
  25206. vctxt->inode->nsName,
  25207. vctxt->inode);
  25208. #ifdef DEBUG_AUTOMATA
  25209. if (ret < 0)
  25210. xmlGenericError(xmlGenericErrorContext,
  25211. "AUTOMATON push ERROR for '%s' on '%s'\n",
  25212. vctxt->inode->localName, pielem->localName);
  25213. else
  25214. xmlGenericError(xmlGenericErrorContext,
  25215. "AUTOMATON push OK for '%s' on '%s'\n",
  25216. vctxt->inode->localName, pielem->localName);
  25217. #endif
  25218. if (vctxt->err == XML_SCHEMAV_INTERNAL) {
  25219. VERROR_INT("xmlSchemaValidateChildElem",
  25220. "calling xmlRegExecPushString2()");
  25221. return (-1);
  25222. }
  25223. if (ret < 0) {
  25224. xmlRegExecErrInfo(regexCtxt, NULL, &nbval, &nbneg,
  25225. &values[0], &terminal);
  25226. xmlSchemaComplexTypeErr(ACTXT_CAST vctxt,
  25227. XML_SCHEMAV_ELEMENT_CONTENT, NULL,NULL,
  25228. "This element is not expected",
  25229. nbval, nbneg, values);
  25230. ret = vctxt->err;
  25231. goto unexpected_elem;
  25232. } else
  25233. ret = 0;
  25234. }
  25235. break;
  25236. case XML_SCHEMA_CONTENT_SIMPLE:
  25237. case XML_SCHEMA_CONTENT_BASIC:
  25238. ACTIVATE_PARENT_ELEM
  25239. if (WXS_IS_COMPLEX(ptype)) {
  25240. /*
  25241. * SPEC (cvc-complex-type) (2.2)
  25242. * "If the {content type} is a simple type definition, then
  25243. * the element information item has no element information
  25244. * item [children], ..."
  25245. */
  25246. ret = XML_SCHEMAV_CVC_COMPLEX_TYPE_2_2;
  25247. VERROR(ret, NULL, "Element content is not allowed, "
  25248. "because the content type is a simple type definition");
  25249. } else {
  25250. /*
  25251. * SPEC (cvc-type) (3.1.2) "The element information item must
  25252. * have no element information item [children]."
  25253. */
  25254. ret = XML_SCHEMAV_CVC_TYPE_3_1_2;
  25255. VERROR(ret, NULL, "Element content is not allowed, "
  25256. "because the type definition is simple");
  25257. }
  25258. ACTIVATE_ELEM
  25259. ret = vctxt->err;
  25260. goto unexpected_elem;
  25261. break;
  25262. default:
  25263. break;
  25264. }
  25265. return (ret);
  25266. unexpected_elem:
  25267. /*
  25268. * Pop this element and set the skipDepth to skip
  25269. * all further content of the parent element.
  25270. */
  25271. vctxt->skipDepth = vctxt->depth;
  25272. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_NOT_EXPECTED;
  25273. pielem->flags |= XML_SCHEMA_ELEM_INFO_ERR_BAD_CONTENT;
  25274. return (ret);
  25275. }
  25276. #define XML_SCHEMA_PUSH_TEXT_PERSIST 1
  25277. #define XML_SCHEMA_PUSH_TEXT_CREATED 2
  25278. #define XML_SCHEMA_PUSH_TEXT_VOLATILE 3
  25279. static int
  25280. xmlSchemaVPushText(xmlSchemaValidCtxtPtr vctxt,
  25281. int nodeType, const xmlChar *value, int len,
  25282. int mode, int *consumed)
  25283. {
  25284. /*
  25285. * Unfortunately we have to duplicate the text sometimes.
  25286. * OPTIMIZE: Maybe we could skip it, if:
  25287. * 1. content type is simple
  25288. * 2. whitespace is "collapse"
  25289. * 3. it consists of whitespace only
  25290. *
  25291. * Process character content.
  25292. */
  25293. if (consumed != NULL)
  25294. *consumed = 0;
  25295. if (INODE_NILLED(vctxt->inode)) {
  25296. /*
  25297. * SPEC cvc-elt (3.3.4 - 3.2.1)
  25298. * "The element information item must have no character or
  25299. * element information item [children]."
  25300. */
  25301. VERROR(XML_SCHEMAV_CVC_ELT_3_2_1, NULL,
  25302. "Neither character nor element content is allowed "
  25303. "because the element is 'nilled'");
  25304. return (vctxt->err);
  25305. }
  25306. /*
  25307. * SPEC (2.1) "If the {content type} is empty, then the
  25308. * element information item has no character or element
  25309. * information item [children]."
  25310. */
  25311. if (vctxt->inode->typeDef->contentType ==
  25312. XML_SCHEMA_CONTENT_EMPTY) {
  25313. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_1, NULL,
  25314. "Character content is not allowed, "
  25315. "because the content type is empty");
  25316. return (vctxt->err);
  25317. }
  25318. if (vctxt->inode->typeDef->contentType ==
  25319. XML_SCHEMA_CONTENT_ELEMENTS) {
  25320. if ((nodeType != XML_TEXT_NODE) ||
  25321. (! xmlSchemaIsBlank((xmlChar *) value, len))) {
  25322. /*
  25323. * SPEC cvc-complex-type (2.3)
  25324. * "If the {content type} is element-only, then the
  25325. * element information item has no character information
  25326. * item [children] other than those whose [character
  25327. * code] is defined as a white space in [XML 1.0 (Second
  25328. * Edition)]."
  25329. */
  25330. VERROR(XML_SCHEMAV_CVC_COMPLEX_TYPE_2_3, NULL,
  25331. "Character content other than whitespace is not allowed "
  25332. "because the content type is 'element-only'");
  25333. return (vctxt->err);
  25334. }
  25335. return (0);
  25336. }
  25337. if ((value == NULL) || (value[0] == 0))
  25338. return (0);
  25339. /*
  25340. * Save the value.
  25341. * NOTE that even if the content type is *mixed*, we need the
  25342. * *initial value* for default/fixed value constraints.
  25343. */
  25344. if ((vctxt->inode->typeDef->contentType == XML_SCHEMA_CONTENT_MIXED) &&
  25345. ((vctxt->inode->decl == NULL) ||
  25346. (vctxt->inode->decl->value == NULL)))
  25347. return (0);
  25348. if (vctxt->inode->value == NULL) {
  25349. /*
  25350. * Set the value.
  25351. */
  25352. switch (mode) {
  25353. case XML_SCHEMA_PUSH_TEXT_PERSIST:
  25354. /*
  25355. * When working on a tree.
  25356. */
  25357. vctxt->inode->value = value;
  25358. break;
  25359. case XML_SCHEMA_PUSH_TEXT_CREATED:
  25360. /*
  25361. * When working with the reader.
  25362. * The value will be freed by the element info.
  25363. */
  25364. vctxt->inode->value = value;
  25365. if (consumed != NULL)
  25366. *consumed = 1;
  25367. vctxt->inode->flags |=
  25368. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25369. break;
  25370. case XML_SCHEMA_PUSH_TEXT_VOLATILE:
  25371. /*
  25372. * When working with SAX.
  25373. * The value will be freed by the element info.
  25374. */
  25375. if (len != -1)
  25376. vctxt->inode->value = BAD_CAST xmlStrndup(value, len);
  25377. else
  25378. vctxt->inode->value = BAD_CAST xmlStrdup(value);
  25379. vctxt->inode->flags |=
  25380. XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25381. break;
  25382. default:
  25383. break;
  25384. }
  25385. } else {
  25386. if (len < 0)
  25387. len = xmlStrlen(value);
  25388. /*
  25389. * Concat the value.
  25390. */
  25391. if (vctxt->inode->flags & XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES) {
  25392. vctxt->inode->value = BAD_CAST xmlStrncat(
  25393. (xmlChar *) vctxt->inode->value, value, len);
  25394. } else {
  25395. vctxt->inode->value =
  25396. BAD_CAST xmlStrncatNew(vctxt->inode->value, value, len);
  25397. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_VALUES;
  25398. }
  25399. }
  25400. return (0);
  25401. }
  25402. static int
  25403. xmlSchemaValidateElem(xmlSchemaValidCtxtPtr vctxt)
  25404. {
  25405. int ret = 0;
  25406. if ((vctxt->skipDepth != -1) &&
  25407. (vctxt->depth >= vctxt->skipDepth)) {
  25408. VERROR_INT("xmlSchemaValidateElem",
  25409. "in skip-state");
  25410. goto internal_error;
  25411. }
  25412. if (vctxt->xsiAssemble) {
  25413. /*
  25414. * We will stop validation if there was an error during
  25415. * dynamic schema construction.
  25416. * Note that we simply set @skipDepth to 0, this could
  25417. * mean that a streaming document via SAX would be
  25418. * still read to the end but it won't be validated any more.
  25419. * TODO: If we are sure how to stop the validation at once
  25420. * for all input scenarios, then this should be changed to
  25421. * instantly stop the validation.
  25422. */
  25423. ret = xmlSchemaAssembleByXSI(vctxt);
  25424. if (ret != 0) {
  25425. if (ret == -1)
  25426. goto internal_error;
  25427. vctxt->skipDepth = 0;
  25428. return(ret);
  25429. }
  25430. /*
  25431. * Augment the IDC definitions for the main schema and all imported ones
  25432. * NOTE: main schema is the first in the imported list
  25433. */
  25434. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  25435. vctxt);
  25436. }
  25437. if (vctxt->depth > 0) {
  25438. /*
  25439. * Validate this element against the content model
  25440. * of the parent.
  25441. */
  25442. ret = xmlSchemaValidateChildElem(vctxt);
  25443. if (ret != 0) {
  25444. if (ret < 0) {
  25445. VERROR_INT("xmlSchemaValidateElem",
  25446. "calling xmlSchemaStreamValidateChildElement()");
  25447. goto internal_error;
  25448. }
  25449. goto exit;
  25450. }
  25451. if (vctxt->depth == vctxt->skipDepth)
  25452. goto exit;
  25453. if ((vctxt->inode->decl == NULL) &&
  25454. (vctxt->inode->typeDef == NULL)) {
  25455. VERROR_INT("xmlSchemaValidateElem",
  25456. "the child element was valid but neither the "
  25457. "declaration nor the type was set");
  25458. goto internal_error;
  25459. }
  25460. } else {
  25461. /*
  25462. * Get the declaration of the validation root.
  25463. */
  25464. vctxt->inode->decl = xmlSchemaGetElem(vctxt->schema,
  25465. vctxt->inode->localName,
  25466. vctxt->inode->nsName);
  25467. if (vctxt->inode->decl == NULL) {
  25468. ret = XML_SCHEMAV_CVC_ELT_1;
  25469. VERROR(ret, NULL,
  25470. "No matching global declaration available "
  25471. "for the validation root");
  25472. goto exit;
  25473. }
  25474. }
  25475. if (vctxt->inode->decl == NULL)
  25476. goto type_validation;
  25477. if (vctxt->inode->decl->type == XML_SCHEMA_TYPE_ANY) {
  25478. int skip;
  25479. /*
  25480. * Wildcards.
  25481. */
  25482. ret = xmlSchemaValidateElemWildcard(vctxt, &skip);
  25483. if (ret != 0) {
  25484. if (ret < 0) {
  25485. VERROR_INT("xmlSchemaValidateElem",
  25486. "calling xmlSchemaValidateElemWildcard()");
  25487. goto internal_error;
  25488. }
  25489. goto exit;
  25490. }
  25491. if (skip) {
  25492. vctxt->skipDepth = vctxt->depth;
  25493. goto exit;
  25494. }
  25495. /*
  25496. * The declaration might be set by the wildcard validation,
  25497. * when the processContents is "lax" or "strict".
  25498. */
  25499. if (vctxt->inode->decl->type != XML_SCHEMA_TYPE_ELEMENT) {
  25500. /*
  25501. * Clear the "decl" field to not confuse further processing.
  25502. */
  25503. vctxt->inode->decl = NULL;
  25504. goto type_validation;
  25505. }
  25506. }
  25507. /*
  25508. * Validate against the declaration.
  25509. */
  25510. ret = xmlSchemaValidateElemDecl(vctxt);
  25511. if (ret != 0) {
  25512. if (ret < 0) {
  25513. VERROR_INT("xmlSchemaValidateElem",
  25514. "calling xmlSchemaValidateElemDecl()");
  25515. goto internal_error;
  25516. }
  25517. goto exit;
  25518. }
  25519. /*
  25520. * Validate against the type definition.
  25521. */
  25522. type_validation:
  25523. if (vctxt->inode->typeDef == NULL) {
  25524. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25525. ret = XML_SCHEMAV_CVC_TYPE_1;
  25526. VERROR(ret, NULL,
  25527. "The type definition is absent");
  25528. goto exit;
  25529. }
  25530. if (vctxt->inode->typeDef->flags & XML_SCHEMAS_TYPE_ABSTRACT) {
  25531. vctxt->inode->flags |= XML_SCHEMA_NODE_INFO_ERR_BAD_TYPE;
  25532. ret = XML_SCHEMAV_CVC_TYPE_2;
  25533. VERROR(ret, NULL,
  25534. "The type definition is abstract");
  25535. goto exit;
  25536. }
  25537. /*
  25538. * Evaluate IDCs. Do it here, since new IDC matchers are registered
  25539. * during validation against the declaration. This must be done
  25540. * _before_ attribute validation.
  25541. */
  25542. if (vctxt->xpathStates != NULL) {
  25543. ret = xmlSchemaXPathEvaluate(vctxt, XML_ELEMENT_NODE);
  25544. vctxt->inode->appliedXPath = 1;
  25545. if (ret == -1) {
  25546. VERROR_INT("xmlSchemaValidateElem",
  25547. "calling xmlSchemaXPathEvaluate()");
  25548. goto internal_error;
  25549. }
  25550. }
  25551. /*
  25552. * Validate attributes.
  25553. */
  25554. if (WXS_IS_COMPLEX(vctxt->inode->typeDef)) {
  25555. if ((vctxt->nbAttrInfos != 0) ||
  25556. (vctxt->inode->typeDef->attrUses != NULL)) {
  25557. ret = xmlSchemaVAttributesComplex(vctxt);
  25558. }
  25559. } else if (vctxt->nbAttrInfos != 0) {
  25560. ret = xmlSchemaVAttributesSimple(vctxt);
  25561. }
  25562. /*
  25563. * Clear registered attributes.
  25564. */
  25565. if (vctxt->nbAttrInfos != 0)
  25566. xmlSchemaClearAttrInfos(vctxt);
  25567. if (ret == -1) {
  25568. VERROR_INT("xmlSchemaValidateElem",
  25569. "calling attributes validation");
  25570. goto internal_error;
  25571. }
  25572. /*
  25573. * Don't return an error if attributes are invalid on purpose.
  25574. */
  25575. ret = 0;
  25576. exit:
  25577. if (ret != 0)
  25578. vctxt->skipDepth = vctxt->depth;
  25579. return (ret);
  25580. internal_error:
  25581. return (-1);
  25582. }
  25583. #ifdef XML_SCHEMA_READER_ENABLED
  25584. static int
  25585. xmlSchemaVReaderWalk(xmlSchemaValidCtxtPtr vctxt)
  25586. {
  25587. const int WHTSP = 13, SIGN_WHTSP = 14, END_ELEM = 15;
  25588. int depth, nodeType, ret = 0, consumed;
  25589. xmlSchemaNodeInfoPtr ielem;
  25590. vctxt->depth = -1;
  25591. ret = xmlTextReaderRead(vctxt->reader);
  25592. /*
  25593. * Move to the document element.
  25594. */
  25595. while (ret == 1) {
  25596. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25597. if (nodeType == XML_ELEMENT_NODE)
  25598. goto root_found;
  25599. ret = xmlTextReaderRead(vctxt->reader);
  25600. }
  25601. goto exit;
  25602. root_found:
  25603. do {
  25604. depth = xmlTextReaderDepth(vctxt->reader);
  25605. nodeType = xmlTextReaderNodeType(vctxt->reader);
  25606. if (nodeType == XML_ELEMENT_NODE) {
  25607. vctxt->depth++;
  25608. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25609. VERROR_INT("xmlSchemaVReaderWalk",
  25610. "calling xmlSchemaValidatorPushElem()");
  25611. goto internal_error;
  25612. }
  25613. ielem = vctxt->inode;
  25614. ielem->localName = xmlTextReaderLocalName(vctxt->reader);
  25615. ielem->nsName = xmlTextReaderNamespaceUri(vctxt->reader);
  25616. ielem->flags |= XML_SCHEMA_NODE_INFO_FLAG_OWNED_NAMES;
  25617. /*
  25618. * Is the element empty?
  25619. */
  25620. ret = xmlTextReaderIsEmptyElement(vctxt->reader);
  25621. if (ret == -1) {
  25622. VERROR_INT("xmlSchemaVReaderWalk",
  25623. "calling xmlTextReaderIsEmptyElement()");
  25624. goto internal_error;
  25625. }
  25626. if (ret) {
  25627. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25628. }
  25629. /*
  25630. * Register attributes.
  25631. */
  25632. vctxt->nbAttrInfos = 0;
  25633. ret = xmlTextReaderMoveToFirstAttribute(vctxt->reader);
  25634. if (ret == -1) {
  25635. VERROR_INT("xmlSchemaVReaderWalk",
  25636. "calling xmlTextReaderMoveToFirstAttribute()");
  25637. goto internal_error;
  25638. }
  25639. if (ret == 1) {
  25640. do {
  25641. /*
  25642. * VAL TODO: How do we know that the reader works on a
  25643. * node tree, to be able to pass a node here?
  25644. */
  25645. if (xmlSchemaValidatorPushAttribute(vctxt, NULL,
  25646. (const xmlChar *) xmlTextReaderLocalName(vctxt->reader),
  25647. xmlTextReaderNamespaceUri(vctxt->reader), 1,
  25648. xmlTextReaderValue(vctxt->reader), 1) == -1) {
  25649. VERROR_INT("xmlSchemaVReaderWalk",
  25650. "calling xmlSchemaValidatorPushAttribute()");
  25651. goto internal_error;
  25652. }
  25653. ret = xmlTextReaderMoveToNextAttribute(vctxt->reader);
  25654. if (ret == -1) {
  25655. VERROR_INT("xmlSchemaVReaderWalk",
  25656. "calling xmlTextReaderMoveToFirstAttribute()");
  25657. goto internal_error;
  25658. }
  25659. } while (ret == 1);
  25660. /*
  25661. * Back to element position.
  25662. */
  25663. ret = xmlTextReaderMoveToElement(vctxt->reader);
  25664. if (ret == -1) {
  25665. VERROR_INT("xmlSchemaVReaderWalk",
  25666. "calling xmlTextReaderMoveToElement()");
  25667. goto internal_error;
  25668. }
  25669. }
  25670. /*
  25671. * Validate the element.
  25672. */
  25673. ret= xmlSchemaValidateElem(vctxt);
  25674. if (ret != 0) {
  25675. if (ret == -1) {
  25676. VERROR_INT("xmlSchemaVReaderWalk",
  25677. "calling xmlSchemaValidateElem()");
  25678. goto internal_error;
  25679. }
  25680. goto exit;
  25681. }
  25682. if (vctxt->depth == vctxt->skipDepth) {
  25683. int curDepth;
  25684. /*
  25685. * Skip all content.
  25686. */
  25687. if ((ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY) == 0) {
  25688. ret = xmlTextReaderRead(vctxt->reader);
  25689. curDepth = xmlTextReaderDepth(vctxt->reader);
  25690. while ((ret == 1) && (curDepth != depth)) {
  25691. ret = xmlTextReaderRead(vctxt->reader);
  25692. curDepth = xmlTextReaderDepth(vctxt->reader);
  25693. }
  25694. if (ret < 0) {
  25695. /*
  25696. * VAL TODO: A reader error occurred; what to do here?
  25697. */
  25698. ret = 1;
  25699. goto exit;
  25700. }
  25701. }
  25702. goto leave_elem;
  25703. }
  25704. /*
  25705. * READER VAL TODO: Is an END_ELEM really never called
  25706. * if the elem is empty?
  25707. */
  25708. if (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25709. goto leave_elem;
  25710. } else if (nodeType == END_ELEM) {
  25711. /*
  25712. * Process END of element.
  25713. */
  25714. leave_elem:
  25715. ret = xmlSchemaValidatorPopElem(vctxt);
  25716. if (ret != 0) {
  25717. if (ret < 0) {
  25718. VERROR_INT("xmlSchemaVReaderWalk",
  25719. "calling xmlSchemaValidatorPopElem()");
  25720. goto internal_error;
  25721. }
  25722. goto exit;
  25723. }
  25724. if (vctxt->depth >= 0)
  25725. ielem = vctxt->inode;
  25726. else
  25727. ielem = NULL;
  25728. } else if ((nodeType == XML_TEXT_NODE) ||
  25729. (nodeType == XML_CDATA_SECTION_NODE) ||
  25730. (nodeType == WHTSP) ||
  25731. (nodeType == SIGN_WHTSP)) {
  25732. /*
  25733. * Process character content.
  25734. */
  25735. xmlChar *value;
  25736. if ((nodeType == WHTSP) || (nodeType == SIGN_WHTSP))
  25737. nodeType = XML_TEXT_NODE;
  25738. value = xmlTextReaderValue(vctxt->reader);
  25739. ret = xmlSchemaVPushText(vctxt, nodeType, BAD_CAST value,
  25740. -1, XML_SCHEMA_PUSH_TEXT_CREATED, &consumed);
  25741. if (! consumed)
  25742. xmlFree(value);
  25743. if (ret == -1) {
  25744. VERROR_INT("xmlSchemaVReaderWalk",
  25745. "calling xmlSchemaVPushText()");
  25746. goto internal_error;
  25747. }
  25748. } else if ((nodeType == XML_ENTITY_NODE) ||
  25749. (nodeType == XML_ENTITY_REF_NODE)) {
  25750. /*
  25751. * VAL TODO: What to do with entities?
  25752. */
  25753. TODO
  25754. }
  25755. /*
  25756. * Read next node.
  25757. */
  25758. ret = xmlTextReaderRead(vctxt->reader);
  25759. } while (ret == 1);
  25760. exit:
  25761. return (ret);
  25762. internal_error:
  25763. return (-1);
  25764. }
  25765. #endif
  25766. /************************************************************************
  25767. * *
  25768. * SAX validation handlers *
  25769. * *
  25770. ************************************************************************/
  25771. /*
  25772. * Process text content.
  25773. */
  25774. static void
  25775. xmlSchemaSAXHandleText(void *ctx,
  25776. const xmlChar * ch,
  25777. int len)
  25778. {
  25779. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25780. if (vctxt->depth < 0)
  25781. return;
  25782. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25783. return;
  25784. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25785. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25786. if (xmlSchemaVPushText(vctxt, XML_TEXT_NODE, ch, len,
  25787. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25788. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25789. "calling xmlSchemaVPushText()");
  25790. vctxt->err = -1;
  25791. xmlStopParser(vctxt->parserCtxt);
  25792. }
  25793. }
  25794. /*
  25795. * Process CDATA content.
  25796. */
  25797. static void
  25798. xmlSchemaSAXHandleCDataSection(void *ctx,
  25799. const xmlChar * ch,
  25800. int len)
  25801. {
  25802. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25803. if (vctxt->depth < 0)
  25804. return;
  25805. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25806. return;
  25807. if (vctxt->inode->flags & XML_SCHEMA_ELEM_INFO_EMPTY)
  25808. vctxt->inode->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  25809. if (xmlSchemaVPushText(vctxt, XML_CDATA_SECTION_NODE, ch, len,
  25810. XML_SCHEMA_PUSH_TEXT_VOLATILE, NULL) == -1) {
  25811. VERROR_INT("xmlSchemaSAXHandleCDataSection",
  25812. "calling xmlSchemaVPushText()");
  25813. vctxt->err = -1;
  25814. xmlStopParser(vctxt->parserCtxt);
  25815. }
  25816. }
  25817. static void
  25818. xmlSchemaSAXHandleReference(void *ctx ATTRIBUTE_UNUSED,
  25819. const xmlChar * name ATTRIBUTE_UNUSED)
  25820. {
  25821. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25822. if (vctxt->depth < 0)
  25823. return;
  25824. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25825. return;
  25826. /* SAX VAL TODO: What to do here? */
  25827. TODO
  25828. }
  25829. static void
  25830. xmlSchemaSAXHandleStartElementNs(void *ctx,
  25831. const xmlChar * localname,
  25832. const xmlChar * prefix ATTRIBUTE_UNUSED,
  25833. const xmlChar * URI,
  25834. int nb_namespaces,
  25835. const xmlChar ** namespaces,
  25836. int nb_attributes,
  25837. int nb_defaulted ATTRIBUTE_UNUSED,
  25838. const xmlChar ** attributes)
  25839. {
  25840. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25841. int ret;
  25842. xmlSchemaNodeInfoPtr ielem;
  25843. int i, j;
  25844. /*
  25845. * SAX VAL TODO: What to do with nb_defaulted?
  25846. */
  25847. /*
  25848. * Skip elements if inside a "skip" wildcard or invalid.
  25849. */
  25850. vctxt->depth++;
  25851. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  25852. return;
  25853. /*
  25854. * Push the element.
  25855. */
  25856. if (xmlSchemaValidatorPushElem(vctxt) == -1) {
  25857. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25858. "calling xmlSchemaValidatorPushElem()");
  25859. goto internal_error;
  25860. }
  25861. ielem = vctxt->inode;
  25862. /*
  25863. * TODO: Is this OK?
  25864. */
  25865. ielem->nodeLine = xmlSAX2GetLineNumber(vctxt->parserCtxt);
  25866. ielem->localName = localname;
  25867. ielem->nsName = URI;
  25868. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  25869. /*
  25870. * Register namespaces on the elem info.
  25871. */
  25872. if (nb_namespaces != 0) {
  25873. /*
  25874. * Although the parser builds its own namespace list,
  25875. * we have no access to it, so we'll use an own one.
  25876. */
  25877. for (i = 0, j = 0; i < nb_namespaces; i++, j += 2) {
  25878. /*
  25879. * Store prefix and namespace name.
  25880. */
  25881. if (ielem->nsBindings == NULL) {
  25882. ielem->nsBindings =
  25883. (const xmlChar **) xmlMalloc(10 *
  25884. sizeof(const xmlChar *));
  25885. if (ielem->nsBindings == NULL) {
  25886. xmlSchemaVErrMemory(vctxt,
  25887. "allocating namespace bindings for SAX validation",
  25888. NULL);
  25889. goto internal_error;
  25890. }
  25891. ielem->nbNsBindings = 0;
  25892. ielem->sizeNsBindings = 5;
  25893. } else if (ielem->sizeNsBindings <= ielem->nbNsBindings) {
  25894. ielem->sizeNsBindings *= 2;
  25895. ielem->nsBindings =
  25896. (const xmlChar **) xmlRealloc(
  25897. (void *) ielem->nsBindings,
  25898. ielem->sizeNsBindings * 2 * sizeof(const xmlChar *));
  25899. if (ielem->nsBindings == NULL) {
  25900. xmlSchemaVErrMemory(vctxt,
  25901. "re-allocating namespace bindings for SAX validation",
  25902. NULL);
  25903. goto internal_error;
  25904. }
  25905. }
  25906. ielem->nsBindings[ielem->nbNsBindings * 2] = namespaces[j];
  25907. if (namespaces[j+1][0] == 0) {
  25908. /*
  25909. * Handle xmlns="".
  25910. */
  25911. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] = NULL;
  25912. } else
  25913. ielem->nsBindings[ielem->nbNsBindings * 2 + 1] =
  25914. namespaces[j+1];
  25915. ielem->nbNsBindings++;
  25916. }
  25917. }
  25918. /*
  25919. * Register attributes.
  25920. * SAX VAL TODO: We are not adding namespace declaration
  25921. * attributes yet.
  25922. */
  25923. if (nb_attributes != 0) {
  25924. int valueLen, k, l;
  25925. xmlChar *value;
  25926. for (j = 0, i = 0; i < nb_attributes; i++, j += 5) {
  25927. /*
  25928. * Duplicate the value, changing any &#38; to a literal ampersand.
  25929. *
  25930. * libxml2 differs from normal SAX here in that it escapes all ampersands
  25931. * as &#38; instead of delivering the raw converted string. Changing the
  25932. * behavior at this point would break applications that use this API, so
  25933. * we are forced to work around it.
  25934. */
  25935. valueLen = attributes[j+4] - attributes[j+3];
  25936. value = xmlMallocAtomic(valueLen + 1);
  25937. if (value == NULL) {
  25938. xmlSchemaVErrMemory(vctxt,
  25939. "allocating string for decoded attribute",
  25940. NULL);
  25941. goto internal_error;
  25942. }
  25943. for (k = 0, l = 0; k < valueLen; l++) {
  25944. if (k < valueLen - 4 &&
  25945. attributes[j+3][k+0] == '&' &&
  25946. attributes[j+3][k+1] == '#' &&
  25947. attributes[j+3][k+2] == '3' &&
  25948. attributes[j+3][k+3] == '8' &&
  25949. attributes[j+3][k+4] == ';') {
  25950. value[l] = '&';
  25951. k += 5;
  25952. } else {
  25953. value[l] = attributes[j+3][k];
  25954. k++;
  25955. }
  25956. }
  25957. value[l] = '\0';
  25958. /*
  25959. * TODO: Set the node line.
  25960. */
  25961. ret = xmlSchemaValidatorPushAttribute(vctxt,
  25962. NULL, ielem->nodeLine, attributes[j], attributes[j+2], 0,
  25963. value, 1);
  25964. if (ret == -1) {
  25965. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25966. "calling xmlSchemaValidatorPushAttribute()");
  25967. goto internal_error;
  25968. }
  25969. }
  25970. }
  25971. /*
  25972. * Validate the element.
  25973. */
  25974. ret = xmlSchemaValidateElem(vctxt);
  25975. if (ret != 0) {
  25976. if (ret == -1) {
  25977. VERROR_INT("xmlSchemaSAXHandleStartElementNs",
  25978. "calling xmlSchemaValidateElem()");
  25979. goto internal_error;
  25980. }
  25981. goto exit;
  25982. }
  25983. exit:
  25984. return;
  25985. internal_error:
  25986. vctxt->err = -1;
  25987. xmlStopParser(vctxt->parserCtxt);
  25988. return;
  25989. }
  25990. static void
  25991. xmlSchemaSAXHandleEndElementNs(void *ctx,
  25992. const xmlChar * localname ATTRIBUTE_UNUSED,
  25993. const xmlChar * prefix ATTRIBUTE_UNUSED,
  25994. const xmlChar * URI ATTRIBUTE_UNUSED)
  25995. {
  25996. xmlSchemaValidCtxtPtr vctxt = (xmlSchemaValidCtxtPtr) ctx;
  25997. int res;
  25998. /*
  25999. * Skip elements if inside a "skip" wildcard or if invalid.
  26000. */
  26001. if (vctxt->skipDepth != -1) {
  26002. if (vctxt->depth > vctxt->skipDepth) {
  26003. vctxt->depth--;
  26004. return;
  26005. } else
  26006. vctxt->skipDepth = -1;
  26007. }
  26008. /*
  26009. * SAX VAL TODO: Just a temporary check.
  26010. */
  26011. if ((!xmlStrEqual(vctxt->inode->localName, localname)) ||
  26012. (!xmlStrEqual(vctxt->inode->nsName, URI))) {
  26013. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  26014. "elem pop mismatch");
  26015. }
  26016. res = xmlSchemaValidatorPopElem(vctxt);
  26017. if (res != 0) {
  26018. if (res < 0) {
  26019. VERROR_INT("xmlSchemaSAXHandleEndElementNs",
  26020. "calling xmlSchemaValidatorPopElem()");
  26021. goto internal_error;
  26022. }
  26023. goto exit;
  26024. }
  26025. exit:
  26026. return;
  26027. internal_error:
  26028. vctxt->err = -1;
  26029. xmlStopParser(vctxt->parserCtxt);
  26030. return;
  26031. }
  26032. /************************************************************************
  26033. * *
  26034. * Validation interfaces *
  26035. * *
  26036. ************************************************************************/
  26037. /**
  26038. * xmlSchemaNewValidCtxt:
  26039. * @schema: a precompiled XML Schemas
  26040. *
  26041. * Create an XML Schemas validation context based on the given schema.
  26042. *
  26043. * Returns the validation context or NULL in case of error
  26044. */
  26045. xmlSchemaValidCtxtPtr
  26046. xmlSchemaNewValidCtxt(xmlSchemaPtr schema)
  26047. {
  26048. xmlSchemaValidCtxtPtr ret;
  26049. ret = (xmlSchemaValidCtxtPtr) xmlMalloc(sizeof(xmlSchemaValidCtxt));
  26050. if (ret == NULL) {
  26051. xmlSchemaVErrMemory(NULL, "allocating validation context", NULL);
  26052. return (NULL);
  26053. }
  26054. memset(ret, 0, sizeof(xmlSchemaValidCtxt));
  26055. ret->type = XML_SCHEMA_CTXT_VALIDATOR;
  26056. ret->dict = xmlDictCreate();
  26057. ret->nodeQNames = xmlSchemaItemListCreate();
  26058. ret->schema = schema;
  26059. return (ret);
  26060. }
  26061. /**
  26062. * xmlSchemaValidateSetFilename:
  26063. * @vctxt: the schema validation context
  26064. * @filename: the file name
  26065. *
  26066. * Workaround to provide file error reporting information when this is
  26067. * not provided by current APIs
  26068. */
  26069. void
  26070. xmlSchemaValidateSetFilename(xmlSchemaValidCtxtPtr vctxt, const char *filename) {
  26071. if (vctxt == NULL)
  26072. return;
  26073. if (vctxt->filename != NULL)
  26074. xmlFree(vctxt->filename);
  26075. if (filename != NULL)
  26076. vctxt->filename = (char *) xmlStrdup((const xmlChar *) filename);
  26077. else
  26078. vctxt->filename = NULL;
  26079. }
  26080. /**
  26081. * xmlSchemaClearValidCtxt:
  26082. * @vctxt: the schema validation context
  26083. *
  26084. * Free the resources associated to the schema validation context;
  26085. * leaves some fields alive intended for reuse of the context.
  26086. */
  26087. static void
  26088. xmlSchemaClearValidCtxt(xmlSchemaValidCtxtPtr vctxt)
  26089. {
  26090. if (vctxt == NULL)
  26091. return;
  26092. /*
  26093. * TODO: Should we clear the flags?
  26094. * Might be problematic if one reuses the context
  26095. * and assumes that the options remain the same.
  26096. */
  26097. vctxt->flags = 0;
  26098. vctxt->validationRoot = NULL;
  26099. vctxt->doc = NULL;
  26100. #ifdef LIBXML_READER_ENABLED
  26101. vctxt->reader = NULL;
  26102. #endif
  26103. vctxt->hasKeyrefs = 0;
  26104. if (vctxt->value != NULL) {
  26105. xmlSchemaFreeValue(vctxt->value);
  26106. vctxt->value = NULL;
  26107. }
  26108. /*
  26109. * Augmented IDC information.
  26110. */
  26111. if (vctxt->aidcs != NULL) {
  26112. xmlSchemaIDCAugPtr cur = vctxt->aidcs, next;
  26113. do {
  26114. next = cur->next;
  26115. xmlFree(cur);
  26116. cur = next;
  26117. } while (cur != NULL);
  26118. vctxt->aidcs = NULL;
  26119. }
  26120. if (vctxt->idcMatcherCache != NULL) {
  26121. xmlSchemaIDCMatcherPtr matcher = vctxt->idcMatcherCache, tmp;
  26122. while (matcher) {
  26123. tmp = matcher;
  26124. matcher = matcher->nextCached;
  26125. xmlSchemaIDCFreeMatcherList(tmp);
  26126. }
  26127. vctxt->idcMatcherCache = NULL;
  26128. }
  26129. if (vctxt->idcNodes != NULL) {
  26130. int i;
  26131. xmlSchemaPSVIIDCNodePtr item;
  26132. for (i = 0; i < vctxt->nbIdcNodes; i++) {
  26133. item = vctxt->idcNodes[i];
  26134. xmlFree(item->keys);
  26135. xmlFree(item);
  26136. }
  26137. xmlFree(vctxt->idcNodes);
  26138. vctxt->idcNodes = NULL;
  26139. vctxt->nbIdcNodes = 0;
  26140. vctxt->sizeIdcNodes = 0;
  26141. }
  26142. if (vctxt->idcKeys != NULL) {
  26143. int i;
  26144. for (i = 0; i < vctxt->nbIdcKeys; i++)
  26145. xmlSchemaIDCFreeKey(vctxt->idcKeys[i]);
  26146. xmlFree(vctxt->idcKeys);
  26147. vctxt->idcKeys = NULL;
  26148. vctxt->nbIdcKeys = 0;
  26149. vctxt->sizeIdcKeys = 0;
  26150. }
  26151. /*
  26152. * Note that we won't delete the XPath state pool here.
  26153. */
  26154. if (vctxt->xpathStates != NULL) {
  26155. xmlSchemaFreeIDCStateObjList(vctxt->xpathStates);
  26156. vctxt->xpathStates = NULL;
  26157. }
  26158. /*
  26159. * Attribute info.
  26160. */
  26161. if (vctxt->nbAttrInfos != 0) {
  26162. xmlSchemaClearAttrInfos(vctxt);
  26163. }
  26164. /*
  26165. * Element info.
  26166. */
  26167. if (vctxt->elemInfos != NULL) {
  26168. int i;
  26169. xmlSchemaNodeInfoPtr ei;
  26170. for (i = 0; i < vctxt->sizeElemInfos; i++) {
  26171. ei = vctxt->elemInfos[i];
  26172. if (ei == NULL)
  26173. break;
  26174. xmlSchemaClearElemInfo(vctxt, ei);
  26175. }
  26176. }
  26177. xmlSchemaItemListClear(vctxt->nodeQNames);
  26178. /* Recreate the dict. */
  26179. xmlDictFree(vctxt->dict);
  26180. /*
  26181. * TODO: Is is save to recreate it? Do we have a scenario
  26182. * where the user provides the dict?
  26183. */
  26184. vctxt->dict = xmlDictCreate();
  26185. if (vctxt->filename != NULL) {
  26186. xmlFree(vctxt->filename);
  26187. vctxt->filename = NULL;
  26188. }
  26189. }
  26190. /**
  26191. * xmlSchemaFreeValidCtxt:
  26192. * @ctxt: the schema validation context
  26193. *
  26194. * Free the resources associated to the schema validation context
  26195. */
  26196. void
  26197. xmlSchemaFreeValidCtxt(xmlSchemaValidCtxtPtr ctxt)
  26198. {
  26199. if (ctxt == NULL)
  26200. return;
  26201. if (ctxt->value != NULL)
  26202. xmlSchemaFreeValue(ctxt->value);
  26203. if (ctxt->pctxt != NULL)
  26204. xmlSchemaFreeParserCtxt(ctxt->pctxt);
  26205. if (ctxt->idcNodes != NULL) {
  26206. int i;
  26207. xmlSchemaPSVIIDCNodePtr item;
  26208. for (i = 0; i < ctxt->nbIdcNodes; i++) {
  26209. item = ctxt->idcNodes[i];
  26210. xmlFree(item->keys);
  26211. xmlFree(item);
  26212. }
  26213. xmlFree(ctxt->idcNodes);
  26214. }
  26215. if (ctxt->idcKeys != NULL) {
  26216. int i;
  26217. for (i = 0; i < ctxt->nbIdcKeys; i++)
  26218. xmlSchemaIDCFreeKey(ctxt->idcKeys[i]);
  26219. xmlFree(ctxt->idcKeys);
  26220. }
  26221. if (ctxt->xpathStates != NULL) {
  26222. xmlSchemaFreeIDCStateObjList(ctxt->xpathStates);
  26223. ctxt->xpathStates = NULL;
  26224. }
  26225. if (ctxt->xpathStatePool != NULL) {
  26226. xmlSchemaFreeIDCStateObjList(ctxt->xpathStatePool);
  26227. ctxt->xpathStatePool = NULL;
  26228. }
  26229. /*
  26230. * Augmented IDC information.
  26231. */
  26232. if (ctxt->aidcs != NULL) {
  26233. xmlSchemaIDCAugPtr cur = ctxt->aidcs, next;
  26234. do {
  26235. next = cur->next;
  26236. xmlFree(cur);
  26237. cur = next;
  26238. } while (cur != NULL);
  26239. }
  26240. if (ctxt->attrInfos != NULL) {
  26241. int i;
  26242. xmlSchemaAttrInfoPtr attr;
  26243. /* Just a paranoid call to the cleanup. */
  26244. if (ctxt->nbAttrInfos != 0)
  26245. xmlSchemaClearAttrInfos(ctxt);
  26246. for (i = 0; i < ctxt->sizeAttrInfos; i++) {
  26247. attr = ctxt->attrInfos[i];
  26248. xmlFree(attr);
  26249. }
  26250. xmlFree(ctxt->attrInfos);
  26251. }
  26252. if (ctxt->elemInfos != NULL) {
  26253. int i;
  26254. xmlSchemaNodeInfoPtr ei;
  26255. for (i = 0; i < ctxt->sizeElemInfos; i++) {
  26256. ei = ctxt->elemInfos[i];
  26257. if (ei == NULL)
  26258. break;
  26259. xmlSchemaClearElemInfo(ctxt, ei);
  26260. xmlFree(ei);
  26261. }
  26262. xmlFree(ctxt->elemInfos);
  26263. }
  26264. if (ctxt->nodeQNames != NULL)
  26265. xmlSchemaItemListFree(ctxt->nodeQNames);
  26266. if (ctxt->dict != NULL)
  26267. xmlDictFree(ctxt->dict);
  26268. if (ctxt->filename != NULL)
  26269. xmlFree(ctxt->filename);
  26270. xmlFree(ctxt);
  26271. }
  26272. /**
  26273. * xmlSchemaIsValid:
  26274. * @ctxt: the schema validation context
  26275. *
  26276. * Check if any error was detected during validation.
  26277. *
  26278. * Returns 1 if valid so far, 0 if errors were detected, and -1 in case
  26279. * of internal error.
  26280. */
  26281. int
  26282. xmlSchemaIsValid(xmlSchemaValidCtxtPtr ctxt)
  26283. {
  26284. if (ctxt == NULL)
  26285. return(-1);
  26286. return(ctxt->err == 0);
  26287. }
  26288. /**
  26289. * xmlSchemaSetValidErrors:
  26290. * @ctxt: a schema validation context
  26291. * @err: the error function
  26292. * @warn: the warning function
  26293. * @ctx: the functions context
  26294. *
  26295. * Set the error and warning callback informations
  26296. */
  26297. void
  26298. xmlSchemaSetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26299. xmlSchemaValidityErrorFunc err,
  26300. xmlSchemaValidityWarningFunc warn, void *ctx)
  26301. {
  26302. if (ctxt == NULL)
  26303. return;
  26304. ctxt->error = err;
  26305. ctxt->warning = warn;
  26306. ctxt->errCtxt = ctx;
  26307. if (ctxt->pctxt != NULL)
  26308. xmlSchemaSetParserErrors(ctxt->pctxt, err, warn, ctx);
  26309. }
  26310. /**
  26311. * xmlSchemaSetValidStructuredErrors:
  26312. * @ctxt: a schema validation context
  26313. * @serror: the structured error function
  26314. * @ctx: the functions context
  26315. *
  26316. * Set the structured error callback
  26317. */
  26318. void
  26319. xmlSchemaSetValidStructuredErrors(xmlSchemaValidCtxtPtr ctxt,
  26320. xmlStructuredErrorFunc serror, void *ctx)
  26321. {
  26322. if (ctxt == NULL)
  26323. return;
  26324. ctxt->serror = serror;
  26325. ctxt->error = NULL;
  26326. ctxt->warning = NULL;
  26327. ctxt->errCtxt = ctx;
  26328. if (ctxt->pctxt != NULL)
  26329. xmlSchemaSetParserStructuredErrors(ctxt->pctxt, serror, ctx);
  26330. }
  26331. /**
  26332. * xmlSchemaGetValidErrors:
  26333. * @ctxt: a XML-Schema validation context
  26334. * @err: the error function result
  26335. * @warn: the warning function result
  26336. * @ctx: the functions context result
  26337. *
  26338. * Get the error and warning callback informations
  26339. *
  26340. * Returns -1 in case of error and 0 otherwise
  26341. */
  26342. int
  26343. xmlSchemaGetValidErrors(xmlSchemaValidCtxtPtr ctxt,
  26344. xmlSchemaValidityErrorFunc * err,
  26345. xmlSchemaValidityWarningFunc * warn, void **ctx)
  26346. {
  26347. if (ctxt == NULL)
  26348. return (-1);
  26349. if (err != NULL)
  26350. *err = ctxt->error;
  26351. if (warn != NULL)
  26352. *warn = ctxt->warning;
  26353. if (ctx != NULL)
  26354. *ctx = ctxt->errCtxt;
  26355. return (0);
  26356. }
  26357. /**
  26358. * xmlSchemaSetValidOptions:
  26359. * @ctxt: a schema validation context
  26360. * @options: a combination of xmlSchemaValidOption
  26361. *
  26362. * Sets the options to be used during the validation.
  26363. *
  26364. * Returns 0 in case of success, -1 in case of an
  26365. * API error.
  26366. */
  26367. int
  26368. xmlSchemaSetValidOptions(xmlSchemaValidCtxtPtr ctxt,
  26369. int options)
  26370. {
  26371. int i;
  26372. if (ctxt == NULL)
  26373. return (-1);
  26374. /*
  26375. * WARNING: Change the start value if adding to the
  26376. * xmlSchemaValidOption.
  26377. * TODO: Is there an other, more easy to maintain,
  26378. * way?
  26379. */
  26380. for (i = 1; i < (int) sizeof(int) * 8; i++) {
  26381. if (options & 1<<i)
  26382. return (-1);
  26383. }
  26384. ctxt->options = options;
  26385. return (0);
  26386. }
  26387. /**
  26388. * xmlSchemaValidCtxtGetOptions:
  26389. * @ctxt: a schema validation context
  26390. *
  26391. * Get the validation context options.
  26392. *
  26393. * Returns the option combination or -1 on error.
  26394. */
  26395. int
  26396. xmlSchemaValidCtxtGetOptions(xmlSchemaValidCtxtPtr ctxt)
  26397. {
  26398. if (ctxt == NULL)
  26399. return (-1);
  26400. else
  26401. return (ctxt->options);
  26402. }
  26403. static int
  26404. xmlSchemaVDocWalk(xmlSchemaValidCtxtPtr vctxt)
  26405. {
  26406. xmlAttrPtr attr;
  26407. int ret = 0;
  26408. xmlSchemaNodeInfoPtr ielem = NULL;
  26409. xmlNodePtr node, valRoot;
  26410. const xmlChar *nsName;
  26411. /* DOC VAL TODO: Move this to the start function. */
  26412. if (vctxt->validationRoot != NULL)
  26413. valRoot = vctxt->validationRoot;
  26414. else
  26415. valRoot = xmlDocGetRootElement(vctxt->doc);
  26416. if (valRoot == NULL) {
  26417. /* VAL TODO: Error code? */
  26418. VERROR(1, NULL, "The document has no document element");
  26419. return (1);
  26420. }
  26421. vctxt->depth = -1;
  26422. vctxt->validationRoot = valRoot;
  26423. node = valRoot;
  26424. while (node != NULL) {
  26425. if ((vctxt->skipDepth != -1) && (vctxt->depth >= vctxt->skipDepth))
  26426. goto next_sibling;
  26427. if (node->type == XML_ELEMENT_NODE) {
  26428. /*
  26429. * Init the node-info.
  26430. */
  26431. vctxt->depth++;
  26432. if (xmlSchemaValidatorPushElem(vctxt) == -1)
  26433. goto internal_error;
  26434. ielem = vctxt->inode;
  26435. ielem->node = node;
  26436. ielem->nodeLine = node->line;
  26437. ielem->localName = node->name;
  26438. if (node->ns != NULL)
  26439. ielem->nsName = node->ns->href;
  26440. ielem->flags |= XML_SCHEMA_ELEM_INFO_EMPTY;
  26441. /*
  26442. * Register attributes.
  26443. * DOC VAL TODO: We do not register namespace declaration
  26444. * attributes yet.
  26445. */
  26446. vctxt->nbAttrInfos = 0;
  26447. if (node->properties != NULL) {
  26448. attr = node->properties;
  26449. do {
  26450. if (attr->ns != NULL)
  26451. nsName = attr->ns->href;
  26452. else
  26453. nsName = NULL;
  26454. ret = xmlSchemaValidatorPushAttribute(vctxt,
  26455. (xmlNodePtr) attr,
  26456. /*
  26457. * Note that we give it the line number of the
  26458. * parent element.
  26459. */
  26460. ielem->nodeLine,
  26461. attr->name, nsName, 0,
  26462. xmlNodeListGetString(attr->doc, attr->children, 1), 1);
  26463. if (ret == -1) {
  26464. VERROR_INT("xmlSchemaDocWalk",
  26465. "calling xmlSchemaValidatorPushAttribute()");
  26466. goto internal_error;
  26467. }
  26468. attr = attr->next;
  26469. } while (attr);
  26470. }
  26471. /*
  26472. * Validate the element.
  26473. */
  26474. ret = xmlSchemaValidateElem(vctxt);
  26475. if (ret != 0) {
  26476. if (ret == -1) {
  26477. VERROR_INT("xmlSchemaDocWalk",
  26478. "calling xmlSchemaValidateElem()");
  26479. goto internal_error;
  26480. }
  26481. /*
  26482. * Don't stop validation; just skip the content
  26483. * of this element.
  26484. */
  26485. goto leave_node;
  26486. }
  26487. if ((vctxt->skipDepth != -1) &&
  26488. (vctxt->depth >= vctxt->skipDepth))
  26489. goto leave_node;
  26490. } else if ((node->type == XML_TEXT_NODE) ||
  26491. (node->type == XML_CDATA_SECTION_NODE)) {
  26492. /*
  26493. * Process character content.
  26494. */
  26495. if ((ielem != NULL) && (ielem->flags & XML_SCHEMA_ELEM_INFO_EMPTY))
  26496. ielem->flags ^= XML_SCHEMA_ELEM_INFO_EMPTY;
  26497. ret = xmlSchemaVPushText(vctxt, node->type, node->content,
  26498. -1, XML_SCHEMA_PUSH_TEXT_PERSIST, NULL);
  26499. if (ret < 0) {
  26500. VERROR_INT("xmlSchemaVDocWalk",
  26501. "calling xmlSchemaVPushText()");
  26502. goto internal_error;
  26503. }
  26504. /*
  26505. * DOC VAL TODO: Should we skip further validation of the
  26506. * element content here?
  26507. */
  26508. } else if ((node->type == XML_ENTITY_NODE) ||
  26509. (node->type == XML_ENTITY_REF_NODE)) {
  26510. /*
  26511. * DOC VAL TODO: What to do with entities?
  26512. */
  26513. VERROR_INT("xmlSchemaVDocWalk",
  26514. "there is at least one entity reference in the node-tree "
  26515. "currently being validated. Processing of entities with "
  26516. "this XML Schema processor is not supported (yet). Please "
  26517. "substitute entities before validation.");
  26518. goto internal_error;
  26519. } else {
  26520. goto leave_node;
  26521. /*
  26522. * DOC VAL TODO: XInclude nodes, etc.
  26523. */
  26524. }
  26525. /*
  26526. * Walk the doc.
  26527. */
  26528. if (node->children != NULL) {
  26529. node = node->children;
  26530. continue;
  26531. }
  26532. leave_node:
  26533. if (node->type == XML_ELEMENT_NODE) {
  26534. /*
  26535. * Leaving the scope of an element.
  26536. */
  26537. if (node != vctxt->inode->node) {
  26538. VERROR_INT("xmlSchemaVDocWalk",
  26539. "element position mismatch");
  26540. goto internal_error;
  26541. }
  26542. ret = xmlSchemaValidatorPopElem(vctxt);
  26543. if (ret != 0) {
  26544. if (ret < 0) {
  26545. VERROR_INT("xmlSchemaVDocWalk",
  26546. "calling xmlSchemaValidatorPopElem()");
  26547. goto internal_error;
  26548. }
  26549. }
  26550. if (node == valRoot)
  26551. goto exit;
  26552. }
  26553. next_sibling:
  26554. if (node->next != NULL)
  26555. node = node->next;
  26556. else {
  26557. node = node->parent;
  26558. goto leave_node;
  26559. }
  26560. }
  26561. exit:
  26562. return (ret);
  26563. internal_error:
  26564. return (-1);
  26565. }
  26566. static int
  26567. xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) {
  26568. /*
  26569. * Some initialization.
  26570. */
  26571. vctxt->err = 0;
  26572. vctxt->nberrors = 0;
  26573. vctxt->depth = -1;
  26574. vctxt->skipDepth = -1;
  26575. vctxt->hasKeyrefs = 0;
  26576. #ifdef ENABLE_IDC_NODE_TABLES_TEST
  26577. vctxt->createIDCNodeTables = 1;
  26578. #else
  26579. vctxt->createIDCNodeTables = 0;
  26580. #endif
  26581. /*
  26582. * Create a schema + parser if necessary.
  26583. */
  26584. if (vctxt->schema == NULL) {
  26585. xmlSchemaParserCtxtPtr pctxt;
  26586. vctxt->xsiAssemble = 1;
  26587. /*
  26588. * If not schema was given then we will create a schema
  26589. * dynamically using XSI schema locations.
  26590. *
  26591. * Create the schema parser context.
  26592. */
  26593. if ((vctxt->pctxt == NULL) &&
  26594. (xmlSchemaCreatePCtxtOnVCtxt(vctxt) == -1))
  26595. return (-1);
  26596. pctxt = vctxt->pctxt;
  26597. pctxt->xsiAssemble = 1;
  26598. /*
  26599. * Create the schema.
  26600. */
  26601. vctxt->schema = xmlSchemaNewSchema(pctxt);
  26602. if (vctxt->schema == NULL)
  26603. return (-1);
  26604. /*
  26605. * Create the schema construction context.
  26606. */
  26607. pctxt->constructor = xmlSchemaConstructionCtxtCreate(pctxt->dict);
  26608. if (pctxt->constructor == NULL)
  26609. return(-1);
  26610. pctxt->constructor->mainSchema = vctxt->schema;
  26611. /*
  26612. * Take ownership of the constructor to be able to free it.
  26613. */
  26614. pctxt->ownsConstructor = 1;
  26615. }
  26616. /*
  26617. * Augment the IDC definitions for the main schema and all imported ones
  26618. * NOTE: main schema if the first in the imported list
  26619. */
  26620. xmlHashScan(vctxt->schema->schemasImports, xmlSchemaAugmentImportedIDC,
  26621. vctxt);
  26622. return(0);
  26623. }
  26624. static void
  26625. xmlSchemaPostRun(xmlSchemaValidCtxtPtr vctxt) {
  26626. if (vctxt->xsiAssemble) {
  26627. if (vctxt->schema != NULL) {
  26628. xmlSchemaFree(vctxt->schema);
  26629. vctxt->schema = NULL;
  26630. }
  26631. }
  26632. xmlSchemaClearValidCtxt(vctxt);
  26633. }
  26634. static int
  26635. xmlSchemaVStart(xmlSchemaValidCtxtPtr vctxt)
  26636. {
  26637. int ret = 0;
  26638. if (xmlSchemaPreRun(vctxt) < 0)
  26639. return(-1);
  26640. if (vctxt->doc != NULL) {
  26641. /*
  26642. * Tree validation.
  26643. */
  26644. ret = xmlSchemaVDocWalk(vctxt);
  26645. #ifdef LIBXML_READER_ENABLED
  26646. } else if (vctxt->reader != NULL) {
  26647. /*
  26648. * XML Reader validation.
  26649. */
  26650. #ifdef XML_SCHEMA_READER_ENABLED
  26651. ret = xmlSchemaVReaderWalk(vctxt);
  26652. #endif
  26653. #endif
  26654. } else if ((vctxt->sax != NULL) && (vctxt->parserCtxt != NULL)) {
  26655. /*
  26656. * SAX validation.
  26657. */
  26658. ret = xmlParseDocument(vctxt->parserCtxt);
  26659. } else {
  26660. VERROR_INT("xmlSchemaVStart",
  26661. "no instance to validate");
  26662. ret = -1;
  26663. }
  26664. xmlSchemaPostRun(vctxt);
  26665. if (ret == 0)
  26666. ret = vctxt->err;
  26667. return (ret);
  26668. }
  26669. /**
  26670. * xmlSchemaValidateOneElement:
  26671. * @ctxt: a schema validation context
  26672. * @elem: an element node
  26673. *
  26674. * Validate a branch of a tree, starting with the given @elem.
  26675. *
  26676. * Returns 0 if the element and its subtree is valid, a positive error
  26677. * code number otherwise and -1 in case of an internal or API error.
  26678. */
  26679. int
  26680. xmlSchemaValidateOneElement(xmlSchemaValidCtxtPtr ctxt, xmlNodePtr elem)
  26681. {
  26682. if ((ctxt == NULL) || (elem == NULL) || (elem->type != XML_ELEMENT_NODE))
  26683. return (-1);
  26684. if (ctxt->schema == NULL)
  26685. return (-1);
  26686. ctxt->doc = elem->doc;
  26687. ctxt->node = elem;
  26688. ctxt->validationRoot = elem;
  26689. return(xmlSchemaVStart(ctxt));
  26690. }
  26691. /**
  26692. * xmlSchemaValidateDoc:
  26693. * @ctxt: a schema validation context
  26694. * @doc: a parsed document tree
  26695. *
  26696. * Validate a document tree in memory.
  26697. *
  26698. * Returns 0 if the document is schemas valid, a positive error code
  26699. * number otherwise and -1 in case of internal or API error.
  26700. */
  26701. int
  26702. xmlSchemaValidateDoc(xmlSchemaValidCtxtPtr ctxt, xmlDocPtr doc)
  26703. {
  26704. if ((ctxt == NULL) || (doc == NULL))
  26705. return (-1);
  26706. ctxt->doc = doc;
  26707. ctxt->node = xmlDocGetRootElement(doc);
  26708. if (ctxt->node == NULL) {
  26709. xmlSchemaCustomErr(ACTXT_CAST ctxt,
  26710. XML_SCHEMAV_DOCUMENT_ELEMENT_MISSING,
  26711. (xmlNodePtr) doc, NULL,
  26712. "The document has no document element", NULL, NULL);
  26713. return (ctxt->err);
  26714. }
  26715. ctxt->validationRoot = ctxt->node;
  26716. return (xmlSchemaVStart(ctxt));
  26717. }
  26718. /************************************************************************
  26719. * *
  26720. * Function and data for SAX streaming API *
  26721. * *
  26722. ************************************************************************/
  26723. typedef struct _xmlSchemaSplitSAXData xmlSchemaSplitSAXData;
  26724. typedef xmlSchemaSplitSAXData *xmlSchemaSplitSAXDataPtr;
  26725. struct _xmlSchemaSplitSAXData {
  26726. xmlSAXHandlerPtr user_sax;
  26727. void *user_data;
  26728. xmlSchemaValidCtxtPtr ctxt;
  26729. xmlSAXHandlerPtr schemas_sax;
  26730. };
  26731. #define XML_SAX_PLUG_MAGIC 0xdc43ba21
  26732. struct _xmlSchemaSAXPlug {
  26733. unsigned int magic;
  26734. /* the original callbacks informations */
  26735. xmlSAXHandlerPtr *user_sax_ptr;
  26736. xmlSAXHandlerPtr user_sax;
  26737. void **user_data_ptr;
  26738. void *user_data;
  26739. /* the block plugged back and validation informations */
  26740. xmlSAXHandler schemas_sax;
  26741. xmlSchemaValidCtxtPtr ctxt;
  26742. };
  26743. /* All those functions just bounces to the user provided SAX handlers */
  26744. static void
  26745. internalSubsetSplit(void *ctx, const xmlChar *name,
  26746. const xmlChar *ExternalID, const xmlChar *SystemID)
  26747. {
  26748. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26749. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26750. (ctxt->user_sax->internalSubset != NULL))
  26751. ctxt->user_sax->internalSubset(ctxt->user_data, name, ExternalID,
  26752. SystemID);
  26753. }
  26754. static int
  26755. isStandaloneSplit(void *ctx)
  26756. {
  26757. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26758. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26759. (ctxt->user_sax->isStandalone != NULL))
  26760. return(ctxt->user_sax->isStandalone(ctxt->user_data));
  26761. return(0);
  26762. }
  26763. static int
  26764. hasInternalSubsetSplit(void *ctx)
  26765. {
  26766. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26767. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26768. (ctxt->user_sax->hasInternalSubset != NULL))
  26769. return(ctxt->user_sax->hasInternalSubset(ctxt->user_data));
  26770. return(0);
  26771. }
  26772. static int
  26773. hasExternalSubsetSplit(void *ctx)
  26774. {
  26775. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26776. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26777. (ctxt->user_sax->hasExternalSubset != NULL))
  26778. return(ctxt->user_sax->hasExternalSubset(ctxt->user_data));
  26779. return(0);
  26780. }
  26781. static void
  26782. externalSubsetSplit(void *ctx, const xmlChar *name,
  26783. const xmlChar *ExternalID, const xmlChar *SystemID)
  26784. {
  26785. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26786. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26787. (ctxt->user_sax->externalSubset != NULL))
  26788. ctxt->user_sax->externalSubset(ctxt->user_data, name, ExternalID,
  26789. SystemID);
  26790. }
  26791. static xmlParserInputPtr
  26792. resolveEntitySplit(void *ctx, const xmlChar *publicId, const xmlChar *systemId)
  26793. {
  26794. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26795. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26796. (ctxt->user_sax->resolveEntity != NULL))
  26797. return(ctxt->user_sax->resolveEntity(ctxt->user_data, publicId,
  26798. systemId));
  26799. return(NULL);
  26800. }
  26801. static xmlEntityPtr
  26802. getEntitySplit(void *ctx, const xmlChar *name)
  26803. {
  26804. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26805. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26806. (ctxt->user_sax->getEntity != NULL))
  26807. return(ctxt->user_sax->getEntity(ctxt->user_data, name));
  26808. return(NULL);
  26809. }
  26810. static xmlEntityPtr
  26811. getParameterEntitySplit(void *ctx, const xmlChar *name)
  26812. {
  26813. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26814. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26815. (ctxt->user_sax->getParameterEntity != NULL))
  26816. return(ctxt->user_sax->getParameterEntity(ctxt->user_data, name));
  26817. return(NULL);
  26818. }
  26819. static void
  26820. entityDeclSplit(void *ctx, const xmlChar *name, int type,
  26821. const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
  26822. {
  26823. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26824. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26825. (ctxt->user_sax->entityDecl != NULL))
  26826. ctxt->user_sax->entityDecl(ctxt->user_data, name, type, publicId,
  26827. systemId, content);
  26828. }
  26829. static void
  26830. attributeDeclSplit(void *ctx, const xmlChar * elem,
  26831. const xmlChar * name, int type, int def,
  26832. const xmlChar * defaultValue, xmlEnumerationPtr tree)
  26833. {
  26834. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26835. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26836. (ctxt->user_sax->attributeDecl != NULL)) {
  26837. ctxt->user_sax->attributeDecl(ctxt->user_data, elem, name, type,
  26838. def, defaultValue, tree);
  26839. } else {
  26840. xmlFreeEnumeration(tree);
  26841. }
  26842. }
  26843. static void
  26844. elementDeclSplit(void *ctx, const xmlChar *name, int type,
  26845. xmlElementContentPtr content)
  26846. {
  26847. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26848. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26849. (ctxt->user_sax->elementDecl != NULL))
  26850. ctxt->user_sax->elementDecl(ctxt->user_data, name, type, content);
  26851. }
  26852. static void
  26853. notationDeclSplit(void *ctx, const xmlChar *name,
  26854. const xmlChar *publicId, const xmlChar *systemId)
  26855. {
  26856. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26857. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26858. (ctxt->user_sax->notationDecl != NULL))
  26859. ctxt->user_sax->notationDecl(ctxt->user_data, name, publicId,
  26860. systemId);
  26861. }
  26862. static void
  26863. unparsedEntityDeclSplit(void *ctx, const xmlChar *name,
  26864. const xmlChar *publicId, const xmlChar *systemId,
  26865. const xmlChar *notationName)
  26866. {
  26867. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26868. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26869. (ctxt->user_sax->unparsedEntityDecl != NULL))
  26870. ctxt->user_sax->unparsedEntityDecl(ctxt->user_data, name, publicId,
  26871. systemId, notationName);
  26872. }
  26873. static void
  26874. setDocumentLocatorSplit(void *ctx, xmlSAXLocatorPtr loc)
  26875. {
  26876. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26877. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26878. (ctxt->user_sax->setDocumentLocator != NULL))
  26879. ctxt->user_sax->setDocumentLocator(ctxt->user_data, loc);
  26880. }
  26881. static void
  26882. startDocumentSplit(void *ctx)
  26883. {
  26884. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26885. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26886. (ctxt->user_sax->startDocument != NULL))
  26887. ctxt->user_sax->startDocument(ctxt->user_data);
  26888. }
  26889. static void
  26890. endDocumentSplit(void *ctx)
  26891. {
  26892. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26893. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26894. (ctxt->user_sax->endDocument != NULL))
  26895. ctxt->user_sax->endDocument(ctxt->user_data);
  26896. }
  26897. static void
  26898. processingInstructionSplit(void *ctx, const xmlChar *target,
  26899. const xmlChar *data)
  26900. {
  26901. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26902. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26903. (ctxt->user_sax->processingInstruction != NULL))
  26904. ctxt->user_sax->processingInstruction(ctxt->user_data, target, data);
  26905. }
  26906. static void
  26907. commentSplit(void *ctx, const xmlChar *value)
  26908. {
  26909. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26910. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26911. (ctxt->user_sax->comment != NULL))
  26912. ctxt->user_sax->comment(ctxt->user_data, value);
  26913. }
  26914. /*
  26915. * Varargs error callbacks to the user application, harder ...
  26916. */
  26917. static void XMLCDECL
  26918. warningSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26919. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26920. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26921. (ctxt->user_sax->warning != NULL)) {
  26922. TODO
  26923. }
  26924. }
  26925. static void XMLCDECL
  26926. errorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26927. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26928. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26929. (ctxt->user_sax->error != NULL)) {
  26930. TODO
  26931. }
  26932. }
  26933. static void XMLCDECL
  26934. fatalErrorSplit(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) {
  26935. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26936. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26937. (ctxt->user_sax->fatalError != NULL)) {
  26938. TODO
  26939. }
  26940. }
  26941. /*
  26942. * Those are function where both the user handler and the schemas handler
  26943. * need to be called.
  26944. */
  26945. static void
  26946. charactersSplit(void *ctx, const xmlChar *ch, int len)
  26947. {
  26948. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26949. if (ctxt == NULL)
  26950. return;
  26951. if ((ctxt->user_sax != NULL) && (ctxt->user_sax->characters != NULL))
  26952. ctxt->user_sax->characters(ctxt->user_data, ch, len);
  26953. if (ctxt->ctxt != NULL)
  26954. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  26955. }
  26956. static void
  26957. ignorableWhitespaceSplit(void *ctx, const xmlChar *ch, int len)
  26958. {
  26959. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26960. if (ctxt == NULL)
  26961. return;
  26962. if ((ctxt->user_sax != NULL) &&
  26963. (ctxt->user_sax->ignorableWhitespace != NULL))
  26964. ctxt->user_sax->ignorableWhitespace(ctxt->user_data, ch, len);
  26965. if (ctxt->ctxt != NULL)
  26966. xmlSchemaSAXHandleText(ctxt->ctxt, ch, len);
  26967. }
  26968. static void
  26969. cdataBlockSplit(void *ctx, const xmlChar *value, int len)
  26970. {
  26971. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26972. if (ctxt == NULL)
  26973. return;
  26974. if ((ctxt->user_sax != NULL) &&
  26975. (ctxt->user_sax->cdataBlock != NULL))
  26976. ctxt->user_sax->cdataBlock(ctxt->user_data, value, len);
  26977. if (ctxt->ctxt != NULL)
  26978. xmlSchemaSAXHandleCDataSection(ctxt->ctxt, value, len);
  26979. }
  26980. static void
  26981. referenceSplit(void *ctx, const xmlChar *name)
  26982. {
  26983. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26984. if (ctxt == NULL)
  26985. return;
  26986. if ((ctxt != NULL) && (ctxt->user_sax != NULL) &&
  26987. (ctxt->user_sax->reference != NULL))
  26988. ctxt->user_sax->reference(ctxt->user_data, name);
  26989. if (ctxt->ctxt != NULL)
  26990. xmlSchemaSAXHandleReference(ctxt->user_data, name);
  26991. }
  26992. static void
  26993. startElementNsSplit(void *ctx, const xmlChar * localname,
  26994. const xmlChar * prefix, const xmlChar * URI,
  26995. int nb_namespaces, const xmlChar ** namespaces,
  26996. int nb_attributes, int nb_defaulted,
  26997. const xmlChar ** attributes) {
  26998. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  26999. if (ctxt == NULL)
  27000. return;
  27001. if ((ctxt->user_sax != NULL) &&
  27002. (ctxt->user_sax->startElementNs != NULL))
  27003. ctxt->user_sax->startElementNs(ctxt->user_data, localname, prefix,
  27004. URI, nb_namespaces, namespaces,
  27005. nb_attributes, nb_defaulted,
  27006. attributes);
  27007. if (ctxt->ctxt != NULL)
  27008. xmlSchemaSAXHandleStartElementNs(ctxt->ctxt, localname, prefix,
  27009. URI, nb_namespaces, namespaces,
  27010. nb_attributes, nb_defaulted,
  27011. attributes);
  27012. }
  27013. static void
  27014. endElementNsSplit(void *ctx, const xmlChar * localname,
  27015. const xmlChar * prefix, const xmlChar * URI) {
  27016. xmlSchemaSAXPlugPtr ctxt = (xmlSchemaSAXPlugPtr) ctx;
  27017. if (ctxt == NULL)
  27018. return;
  27019. if ((ctxt->user_sax != NULL) &&
  27020. (ctxt->user_sax->endElementNs != NULL))
  27021. ctxt->user_sax->endElementNs(ctxt->user_data, localname, prefix, URI);
  27022. if (ctxt->ctxt != NULL)
  27023. xmlSchemaSAXHandleEndElementNs(ctxt->ctxt, localname, prefix, URI);
  27024. }
  27025. /**
  27026. * xmlSchemaSAXPlug:
  27027. * @ctxt: a schema validation context
  27028. * @sax: a pointer to the original xmlSAXHandlerPtr
  27029. * @user_data: a pointer to the original SAX user data pointer
  27030. *
  27031. * Plug a SAX based validation layer in a SAX parsing event flow.
  27032. * The original @saxptr and @dataptr data are replaced by new pointers
  27033. * but the calls to the original will be maintained.
  27034. *
  27035. * Returns a pointer to a data structure needed to unplug the validation layer
  27036. * or NULL in case of errors.
  27037. */
  27038. xmlSchemaSAXPlugPtr
  27039. xmlSchemaSAXPlug(xmlSchemaValidCtxtPtr ctxt,
  27040. xmlSAXHandlerPtr *sax, void **user_data)
  27041. {
  27042. xmlSchemaSAXPlugPtr ret;
  27043. xmlSAXHandlerPtr old_sax;
  27044. if ((ctxt == NULL) || (sax == NULL) || (user_data == NULL))
  27045. return(NULL);
  27046. /*
  27047. * We only allow to plug into SAX2 event streams
  27048. */
  27049. old_sax = *sax;
  27050. if ((old_sax != NULL) && (old_sax->initialized != XML_SAX2_MAGIC))
  27051. return(NULL);
  27052. if ((old_sax != NULL) &&
  27053. (old_sax->startElementNs == NULL) && (old_sax->endElementNs == NULL) &&
  27054. ((old_sax->startElement != NULL) || (old_sax->endElement != NULL)))
  27055. return(NULL);
  27056. /*
  27057. * everything seems right allocate the local data needed for that layer
  27058. */
  27059. ret = (xmlSchemaSAXPlugPtr) xmlMalloc(sizeof(xmlSchemaSAXPlugStruct));
  27060. if (ret == NULL) {
  27061. return(NULL);
  27062. }
  27063. memset(ret, 0, sizeof(xmlSchemaSAXPlugStruct));
  27064. ret->magic = XML_SAX_PLUG_MAGIC;
  27065. ret->schemas_sax.initialized = XML_SAX2_MAGIC;
  27066. ret->ctxt = ctxt;
  27067. ret->user_sax_ptr = sax;
  27068. ret->user_sax = old_sax;
  27069. if (old_sax == NULL) {
  27070. /*
  27071. * go direct, no need for the split block and functions.
  27072. */
  27073. ret->schemas_sax.startElementNs = xmlSchemaSAXHandleStartElementNs;
  27074. ret->schemas_sax.endElementNs = xmlSchemaSAXHandleEndElementNs;
  27075. /*
  27076. * Note that we use the same text-function for both, to prevent
  27077. * the parser from testing for ignorable whitespace.
  27078. */
  27079. ret->schemas_sax.ignorableWhitespace = xmlSchemaSAXHandleText;
  27080. ret->schemas_sax.characters = xmlSchemaSAXHandleText;
  27081. ret->schemas_sax.cdataBlock = xmlSchemaSAXHandleCDataSection;
  27082. ret->schemas_sax.reference = xmlSchemaSAXHandleReference;
  27083. ret->user_data = ctxt;
  27084. *user_data = ctxt;
  27085. } else {
  27086. /*
  27087. * for each callback unused by Schemas initialize it to the Split
  27088. * routine only if non NULL in the user block, this can speed up
  27089. * things at the SAX level.
  27090. */
  27091. if (old_sax->internalSubset != NULL)
  27092. ret->schemas_sax.internalSubset = internalSubsetSplit;
  27093. if (old_sax->isStandalone != NULL)
  27094. ret->schemas_sax.isStandalone = isStandaloneSplit;
  27095. if (old_sax->hasInternalSubset != NULL)
  27096. ret->schemas_sax.hasInternalSubset = hasInternalSubsetSplit;
  27097. if (old_sax->hasExternalSubset != NULL)
  27098. ret->schemas_sax.hasExternalSubset = hasExternalSubsetSplit;
  27099. if (old_sax->resolveEntity != NULL)
  27100. ret->schemas_sax.resolveEntity = resolveEntitySplit;
  27101. if (old_sax->getEntity != NULL)
  27102. ret->schemas_sax.getEntity = getEntitySplit;
  27103. if (old_sax->entityDecl != NULL)
  27104. ret->schemas_sax.entityDecl = entityDeclSplit;
  27105. if (old_sax->notationDecl != NULL)
  27106. ret->schemas_sax.notationDecl = notationDeclSplit;
  27107. if (old_sax->attributeDecl != NULL)
  27108. ret->schemas_sax.attributeDecl = attributeDeclSplit;
  27109. if (old_sax->elementDecl != NULL)
  27110. ret->schemas_sax.elementDecl = elementDeclSplit;
  27111. if (old_sax->unparsedEntityDecl != NULL)
  27112. ret->schemas_sax.unparsedEntityDecl = unparsedEntityDeclSplit;
  27113. if (old_sax->setDocumentLocator != NULL)
  27114. ret->schemas_sax.setDocumentLocator = setDocumentLocatorSplit;
  27115. if (old_sax->startDocument != NULL)
  27116. ret->schemas_sax.startDocument = startDocumentSplit;
  27117. if (old_sax->endDocument != NULL)
  27118. ret->schemas_sax.endDocument = endDocumentSplit;
  27119. if (old_sax->processingInstruction != NULL)
  27120. ret->schemas_sax.processingInstruction = processingInstructionSplit;
  27121. if (old_sax->comment != NULL)
  27122. ret->schemas_sax.comment = commentSplit;
  27123. if (old_sax->warning != NULL)
  27124. ret->schemas_sax.warning = warningSplit;
  27125. if (old_sax->error != NULL)
  27126. ret->schemas_sax.error = errorSplit;
  27127. if (old_sax->fatalError != NULL)
  27128. ret->schemas_sax.fatalError = fatalErrorSplit;
  27129. if (old_sax->getParameterEntity != NULL)
  27130. ret->schemas_sax.getParameterEntity = getParameterEntitySplit;
  27131. if (old_sax->externalSubset != NULL)
  27132. ret->schemas_sax.externalSubset = externalSubsetSplit;
  27133. /*
  27134. * the 6 schemas callback have to go to the splitter functions
  27135. * Note that we use the same text-function for ignorableWhitespace
  27136. * if possible, to prevent the parser from testing for ignorable
  27137. * whitespace.
  27138. */
  27139. ret->schemas_sax.characters = charactersSplit;
  27140. if ((old_sax->ignorableWhitespace != NULL) &&
  27141. (old_sax->ignorableWhitespace != old_sax->characters))
  27142. ret->schemas_sax.ignorableWhitespace = ignorableWhitespaceSplit;
  27143. else
  27144. ret->schemas_sax.ignorableWhitespace = charactersSplit;
  27145. ret->schemas_sax.cdataBlock = cdataBlockSplit;
  27146. ret->schemas_sax.reference = referenceSplit;
  27147. ret->schemas_sax.startElementNs = startElementNsSplit;
  27148. ret->schemas_sax.endElementNs = endElementNsSplit;
  27149. ret->user_data_ptr = user_data;
  27150. ret->user_data = *user_data;
  27151. *user_data = ret;
  27152. }
  27153. /*
  27154. * plug the pointers back.
  27155. */
  27156. *sax = &(ret->schemas_sax);
  27157. ctxt->sax = *sax;
  27158. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27159. xmlSchemaPreRun(ctxt);
  27160. return(ret);
  27161. }
  27162. /**
  27163. * xmlSchemaSAXUnplug:
  27164. * @plug: a data structure returned by xmlSchemaSAXPlug
  27165. *
  27166. * Unplug a SAX based validation layer in a SAX parsing event flow.
  27167. * The original pointers used in the call are restored.
  27168. *
  27169. * Returns 0 in case of success and -1 in case of failure.
  27170. */
  27171. int
  27172. xmlSchemaSAXUnplug(xmlSchemaSAXPlugPtr plug)
  27173. {
  27174. xmlSAXHandlerPtr *sax;
  27175. void **user_data;
  27176. if ((plug == NULL) || (plug->magic != XML_SAX_PLUG_MAGIC))
  27177. return(-1);
  27178. plug->magic = 0;
  27179. xmlSchemaPostRun(plug->ctxt);
  27180. /* restore the data */
  27181. sax = plug->user_sax_ptr;
  27182. *sax = plug->user_sax;
  27183. if (plug->user_sax != NULL) {
  27184. user_data = plug->user_data_ptr;
  27185. *user_data = plug->user_data;
  27186. }
  27187. /* free and return */
  27188. xmlFree(plug);
  27189. return(0);
  27190. }
  27191. /**
  27192. * xmlSchemaValidateSetLocator:
  27193. * @vctxt: a schema validation context
  27194. * @f: the locator function pointer
  27195. * @ctxt: the locator context
  27196. *
  27197. * Allows to set a locator function to the validation context,
  27198. * which will be used to provide file and line information since
  27199. * those are not provided as part of the SAX validation flow
  27200. * Setting @f to NULL disable the locator.
  27201. */
  27202. void
  27203. xmlSchemaValidateSetLocator(xmlSchemaValidCtxtPtr vctxt,
  27204. xmlSchemaValidityLocatorFunc f,
  27205. void *ctxt)
  27206. {
  27207. if (vctxt == NULL) return;
  27208. vctxt->locFunc = f;
  27209. vctxt->locCtxt = ctxt;
  27210. }
  27211. /**
  27212. * xmlSchemaValidateStreamLocator:
  27213. * @ctx: the xmlTextReaderPtr used
  27214. * @file: returned file information
  27215. * @line: returned line information
  27216. *
  27217. * Internal locator function for the readers
  27218. *
  27219. * Returns 0 in case the Schema validation could be (de)activated and
  27220. * -1 in case of error.
  27221. */
  27222. static int
  27223. xmlSchemaValidateStreamLocator(void *ctx, const char **file,
  27224. unsigned long *line) {
  27225. xmlParserCtxtPtr ctxt;
  27226. if ((ctx == NULL) || ((file == NULL) && (line == NULL)))
  27227. return(-1);
  27228. if (file != NULL)
  27229. *file = NULL;
  27230. if (line != NULL)
  27231. *line = 0;
  27232. ctxt = (xmlParserCtxtPtr) ctx;
  27233. if (ctxt->input != NULL) {
  27234. if (file != NULL)
  27235. *file = ctxt->input->filename;
  27236. if (line != NULL)
  27237. *line = ctxt->input->line;
  27238. return(0);
  27239. }
  27240. return(-1);
  27241. }
  27242. /**
  27243. * xmlSchemaValidateStream:
  27244. * @ctxt: a schema validation context
  27245. * @input: the input to use for reading the data
  27246. * @enc: an optional encoding information
  27247. * @sax: a SAX handler for the resulting events
  27248. * @user_data: the context to provide to the SAX handler.
  27249. *
  27250. * Validate an input based on a flow of SAX event from the parser
  27251. * and forward the events to the @sax handler with the provided @user_data
  27252. * the user provided @sax handler must be a SAX2 one.
  27253. *
  27254. * Returns 0 if the document is schemas valid, a positive error code
  27255. * number otherwise and -1 in case of internal or API error.
  27256. */
  27257. int
  27258. xmlSchemaValidateStream(xmlSchemaValidCtxtPtr ctxt,
  27259. xmlParserInputBufferPtr input, xmlCharEncoding enc,
  27260. xmlSAXHandlerPtr sax, void *user_data)
  27261. {
  27262. xmlSchemaSAXPlugPtr plug = NULL;
  27263. xmlSAXHandlerPtr old_sax = NULL;
  27264. xmlParserCtxtPtr pctxt = NULL;
  27265. xmlParserInputPtr inputStream = NULL;
  27266. int ret;
  27267. if ((ctxt == NULL) || (input == NULL))
  27268. return (-1);
  27269. /*
  27270. * prepare the parser
  27271. */
  27272. pctxt = xmlNewParserCtxt();
  27273. if (pctxt == NULL)
  27274. return (-1);
  27275. old_sax = pctxt->sax;
  27276. pctxt->sax = sax;
  27277. pctxt->userData = user_data;
  27278. #if 0
  27279. if (options)
  27280. xmlCtxtUseOptions(pctxt, options);
  27281. #endif
  27282. pctxt->linenumbers = 1;
  27283. xmlSchemaValidateSetLocator(ctxt, xmlSchemaValidateStreamLocator, pctxt);
  27284. inputStream = xmlNewIOInputStream(pctxt, input, enc);;
  27285. if (inputStream == NULL) {
  27286. ret = -1;
  27287. goto done;
  27288. }
  27289. inputPush(pctxt, inputStream);
  27290. ctxt->parserCtxt = pctxt;
  27291. ctxt->input = input;
  27292. /*
  27293. * Plug the validation and launch the parsing
  27294. */
  27295. plug = xmlSchemaSAXPlug(ctxt, &(pctxt->sax), &(pctxt->userData));
  27296. if (plug == NULL) {
  27297. ret = -1;
  27298. goto done;
  27299. }
  27300. ctxt->input = input;
  27301. ctxt->enc = enc;
  27302. ctxt->sax = pctxt->sax;
  27303. ctxt->flags |= XML_SCHEMA_VALID_CTXT_FLAG_STREAM;
  27304. ret = xmlSchemaVStart(ctxt);
  27305. if ((ret == 0) && (! ctxt->parserCtxt->wellFormed)) {
  27306. ret = ctxt->parserCtxt->errNo;
  27307. if (ret == 0)
  27308. ret = 1;
  27309. }
  27310. done:
  27311. ctxt->parserCtxt = NULL;
  27312. ctxt->sax = NULL;
  27313. ctxt->input = NULL;
  27314. if (plug != NULL) {
  27315. xmlSchemaSAXUnplug(plug);
  27316. }
  27317. /* cleanup */
  27318. if (pctxt != NULL) {
  27319. pctxt->sax = old_sax;
  27320. xmlFreeParserCtxt(pctxt);
  27321. }
  27322. return (ret);
  27323. }
  27324. /**
  27325. * xmlSchemaValidateFile:
  27326. * @ctxt: a schema validation context
  27327. * @filename: the URI of the instance
  27328. * @options: a future set of options, currently unused
  27329. *
  27330. * Do a schemas validation of the given resource, it will use the
  27331. * SAX streamable validation internally.
  27332. *
  27333. * Returns 0 if the document is valid, a positive error code
  27334. * number otherwise and -1 in case of an internal or API error.
  27335. */
  27336. int
  27337. xmlSchemaValidateFile(xmlSchemaValidCtxtPtr ctxt,
  27338. const char * filename,
  27339. int options ATTRIBUTE_UNUSED)
  27340. {
  27341. int ret;
  27342. xmlParserInputBufferPtr input;
  27343. if ((ctxt == NULL) || (filename == NULL))
  27344. return (-1);
  27345. input = xmlParserInputBufferCreateFilename(filename,
  27346. XML_CHAR_ENCODING_NONE);
  27347. if (input == NULL)
  27348. return (-1);
  27349. ret = xmlSchemaValidateStream(ctxt, input, XML_CHAR_ENCODING_NONE,
  27350. NULL, NULL);
  27351. return (ret);
  27352. }
  27353. /**
  27354. * xmlSchemaValidCtxtGetParserCtxt:
  27355. * @ctxt: a schema validation context
  27356. *
  27357. * allow access to the parser context of the schema validation context
  27358. *
  27359. * Returns the parser context of the schema validation context or NULL
  27360. * in case of error.
  27361. */
  27362. xmlParserCtxtPtr
  27363. xmlSchemaValidCtxtGetParserCtxt(xmlSchemaValidCtxtPtr ctxt)
  27364. {
  27365. if (ctxt == NULL)
  27366. return(NULL);
  27367. return (ctxt->parserCtxt);
  27368. }
  27369. #define bottom_xmlschemas
  27370. #include "elfgcchack.h"
  27371. #endif /* LIBXML_SCHEMAS_ENABLED */